web-dev-qa-db-fra.com

Laravel commandes et travaux

Je me demandais quelle est la différence entre les différentes classes de type commande dans Laravel 5.1. Pour autant que je sache Laravel 5.1 dispose des éléments suivants:

  • Commandes de la console (artisan make:console)
  • Commandes (artisan make:command)
    • Gestionnaires (artisan make::command --handler)
  • Emplois (artisan make:job)

Je suis passé directement de 4.2 à 5.1, donc je ne sais pas ce qui s'est passé entre 4.2 et 5.1, mais on m'a dit que les commandes du milieu ( juste) ne sont fondamentalement pas vraiment supposées être utilisé plus - ils sont à partir de quand les travaux en file d'attente sont devenus des "commandes" dans 5.0, mais Laravel depuis décidé contre cela, et ils sont juste pour la compatibilité. Cependant, je ' m pas 100% sur ce point, donc des éclaircissements seraient appréciés.

Mon cas d'utilisation spécifique est que je veux un endroit pour mettre une tâche "exécutable" autonome. Par exemple, quelque chose qui supprimera des fichiers de plus de 5 jours d'un répertoire donné (mais cela pourrait faire n'importe quoi).

Au début, cela ressemble à une commande de console - je veux pouvoir l'exécuter à partir de artisan, pour commencer. Mais je peux aussi le vouloir sur un calendrier (super, artisan schedule:run Exécute les commandes de la console). Mais je peux également vouloir l'exécuter de manière asynchrone à partir du code. Les commandes de la console peuvent être exécutées de manière synchrone avec Artisan::call(), mais pour l'asynchrone, c'est (je pense) où les files d'attente entrent, et cela doit soudainement être un travail.

D'accord, nous avons donc un travail. Nous pouvons maintenant l'ajouter à une file d'attente à partir du code, mais comment l'exécuter en tant que commande artisanale (de manière synchrone)? Puis-je simplement créer une commande de console légère et y ajouter le trait DispatchesJobs (ou le code qu'il contient), puis répartir le travail? Le travail doit-il toujours être mis en file d'attente, ou pouvons-nous faire exécuter un travail de manière synchrone (et, idéalement, en sortie sur la sortie de la commande de la console?) La même question se pose pour l'exécuter selon un calendrier - suis-je censé créer cette console commande et l'ajouter au planificateur, ou puis-je faire exécuter le travail directement par le planificateur?

Et enfin, nous avons des "commandes" qui ne sont pas des commandes de console ni des tâches. Comme je l'ai déjà dit, les gens me disent que ce ne sont que des suspensions d'un changement de code Laravel 5.0 qui a été (un peu) annulé. Mais la commande artisan make Existe toujours pour eux, donc ils ne peuvent pas être ça morts. De plus, quel est le problème avec une commande d'auto-manipulation (la valeur par défaut, est livrée avec une méthode handle) et une qui "nécessite" une classe de gestionnaire (exécutez artisan make:command --handler)? Comment faites-vous pour les exécuter? Manuellement avec (new App\Command\SomeCommand)->handle(); Ou (new App\handlers\SomeCommandHandler)->handle(new App\Command\SomeCommand), Ou y a-t-il un système caché que je ne connais pas (peut-être peut-il être distribué à l'aide du répartiteur de tâches/files d'attente)? Vous pouvez également créer des commandes "en file d'attente" artisan make::command --queued, Alors en quoi diffèrent-elles également?

Je suppose que ma question se résume à ce qui suit:

  • Quelle est la différence réelle (sémantique et fonctionnelle) entre elles?
  • Quelle est la bonne façon de les "exécuter"?
  • Quel est le meilleur pour mes besoins d'un morceau de code généralement autonome qui doit être exécuté, de la manière que je juge appropriée?

J'ai trouvé des informations dans la documentation sur la façon d'utiliser les files d'attente et de créer des commandes de console, mais rien sur exactement quand les utiliser ou vraiment quoi que ce soit sur les classes de commandes et les gestionnaires.


Liés mais pas exactement les mêmes (aussi, c'est sans réponse): commandes et travaux Laravel 5.1

30
alexrussell

Je vois ces "objets" comme ceci: (j'ai ajouté quelques exemples de code d'un de mes projets secondaires)

Console

Choses que je veux exécuter à partir de la ligne de commande (comme vous l'avez mentionné avec votre exemple avec "Supprimer les fichiers plus anciens que x"). Mais le fait est que vous pouvez en extraire la logique métier dans une commande .

Exemple : Une commande de console avec déclenche une commande pour récupérer des images depuis Imgur. La classe FetchImages contient la logique métier réelle de la récupération d'images.

Commander

Classe qui contient la logique réelle. Vous devriez également pouvoir appeler cette commande à partir de votre application avec app()->make(Command::class)->handle().

Exemple : Commande mentionnée dans l'exemple 1. Contient une logique qui effectue les appels API réels à Imgur et traite les données renvoyées.

Emplois

J'ai créé cette application avec Laravel 5.0 donc jobs n'était pas une chose à l'époque. Mais comme je le vois, les Jobs sont comme des commandes mais ils sont mis en file d'attente et peuvent être envoyés. (Comme vous l'avez peut-être vu dans ces exemples, ces commandes implémentent les interfaces mentionnées SelfHandling et ShouldBeQueued).


Je me considère comme un développeur expérimenté Laravel mais ces changements dans Commands et Jobs sont assez difficiles à comprendre.

EDIT: À partir des documents Laravel:

Le répertoire app/Commands a été renommé app/Jobs. Cependant, vous n'êtes pas obligé de déplacer toutes vos commandes vers le nouvel emplacement, et vous pouvez continuer à utiliser les commandes make: command et handler: command Artisan pour générer vos classes.

De même, le répertoire app/Handlers a été renommé app/Listeners et ne contient désormais que des écouteurs d'événements. Toutefois, vous n'êtes pas obligé de déplacer ou de renommer vos gestionnaires de commandes et d'événements existants, et vous pouvez continuer à utiliser la commande handler: event pour générer des gestionnaires d'événements.

En fournissant une compatibilité descendante pour la structure de dossiers Laravel 5.0, vous pouvez mettre à niveau vos applications vers Laravel 5.1 et mettre à niveau lentement vos événements et commandes vers leurs nouveaux emplacements quand il est pratique pour vous ou votre équipe.

21
stefanzweifel

Commandes de la console

Laravel possède des "commandes" de console depuis un certain temps. Ils sont fondamentalement inchangés et fonctionnent comme ils l'ont toujours fait. En termes simples, ils sont l'équivalent de routes pour la ligne de commande - le point d'entrée dans l'application. Ils ne sont en aucun cas liés à ...

Le bus de commande

Laravel 5.0 a introduit une implémentation du modèle Command Bus - Commandes de bus de commande. (Je crois que ceux-ci ont été renommés Jobs en raison de la confusion qui en résulte entre eux et les commandes CLI).

Un bus de commande en deux parties - un objet qui représente une commande à exécuter, avec toutes les données dont il a besoin (le travail), et une classe pour exécuter la commande (le gestionnaire).

Le gestionnaire

Dans laravel, vous pouvez déclarer un travail comme autogestion - c'est-à-dire qu'il a lui-même une méthode de gestion.

Si vous souhaitez enregistrer un gestionnaire de commandes, vous pouvez appeler ce qui suit dans un fournisseur de services:

app('Illuminate\Bus\Dispatcher')->maps(['Job' => 'Handler']);

où Job est le nom de classe du travail et Handler est le nom de classe du gestionnaire.

Le répertoire des gestionnaires dans laravel 5.0 était un moyen de déclarer implicitement ces relations (par exemple. EmailCommand dans le dossier des commandes aurait un EmailCommandHandler dans le dossier des gestionnaires) .

Envoi d'une commande

Vous pouvez utiliser ce qui suit pour envoyer une commande.

app('Illuminate\Bus\Dispatcher')->dispatch(new EmailPersonCommand('[email protected]', $otherdata));

Files d'attente

Les travaux, par défaut, s'exécutent dès qu'ils sont appelés (ou envoyés). Les définir comme ShouldQueue les transmettra toujours à une file d'attente lors de leur envoi.

Si vous souhaitez les exécuter de manière synchrone parfois et de manière asynchrone à d'autres moments, vous pouvez appeler $dispatcher->dispatchToQueue($job) lorsque vous souhaitez les mettre en file d'attente. C'est tout ce qui se passe en interne lorsque vous passez un travail ShouldQueue à ->dispatch().

modifier: Pour mettre en file d'attente (ou non)

Je viens de jeter un œil au répartiteur. La méthode dispatch vérifie si la commande est un ShouldQueue et la transmet à dispatchToQueue ou dispatchNow. Vous pouvez appeler l'une de ces méthodes directement au lieu de dispatch avec votre commande si vous souhaitez remplacer le comportement par défaut.

Donc, dans votre cas, selon le comportement "par défaut" de votre travail (c.-à-d. Sera-t-il normalement mis en file d'attente?): - ayez-le ShouldQueue, et utilisez dispatchNow dans la CLI Commander. - ne l'avez pas ShouldQueue, et utilisez dispatchToQueue où vous l'appelez dans votre code.

D'après les sons, je ferais le premier.

28
stef

Juste un ajout aux réponses réelles.

Les travaux dans Laravel> = 5.1 sont des bus de commandes dans Laravel 5..

Il s'agit uniquement d'un changement de nom en raison de la confusion entre Console\Commands (commandes exécutées à partir de la console) et The Command Bus (contenant Commands) pour les tâches d'application.

Vous ne devez pas confondre:

  • Command Bus: utilisé pour "encapsuler les tâches de votre application" (de laravel 5.0 doc) qui est maintenant renommé Jobs
  • Console\Commands: utilisé pour "Artisan [...] l'interface de ligne de commande incluse avec Laravel" (de laravel 5.1 docs) qui est inchangé dans Laravel depuis 4.x
2
Ifnot