Команды и задания Laravel
Мне было интересно, какая разница между различными командоподобными классами в Laravel 5.1. Насколько я могу судить, Laravel 5.1 имеет следующие возможности:
- Команды консоли (
artisan make:console
)
- Команды (
artisan make:command
)
- Обработчики (
artisan make::command --handler
)
- Работа (
artisan make:job
)
Я пришел прямо с 4.2 до 5.1, поэтому я не знаю, что произошло между 4.2 и 5.1, но мне сказали, что средний (просто команды) в основном не предполагается использовать больше - они начиная с того момента, когда задания в очереди становятся "командами" в 5.0, но Laravel с тех пор решил против этого, и они просто готовы к совместимости. Тем не менее, я не на 100% по этому вопросу, поэтому разъяснение будет оценено.
Мой конкретный вариант использования - это то, что я хочу место, чтобы поставить автономную задачу "runnable". Например, что-то, что будет удалять файлы старше 5 дней из заданного каталога (но это может сделать что угодно).
Сначала это звучит как консольная команда - я хочу, чтобы она могла запускать ее из artisan
для начала. Но я могу также хотеть его по расписанию (отлично, artisan schedule:run
запускает консольные команды). Но я также могу выполнить его асинхронно из кода. Консольные команды можно запускать синхронно с Artisan::call()
, но для асинхронных это (я думаю), в которые входят очереди, и это внезапно должно быть заданием.
Итак, у нас есть работа. Теперь мы можем добавить его в очередь из кода, но как мы его выполняем как команду ремесленника (синхронно)? Могу ли я просто создать тонкую консольную команду и добавить в нее тэг DispatchesJobs
(или код в нем), а затем отправить задание? Должно ли задание всегда идти в очереди или мы можем выполнить задание синхронно (и, в идеале, выводить на вывод команды консоли?) Тот же вопрос касается запуска его по расписанию - я должен создать эту консоль и добавьте это в планировщик, или я могу заставить планировщик выполнить задание напрямую?
И, наконец, у нас есть "команды", которые не являются командами консоли и не являются заданиями. Как я уже говорил, люди говорят мне, что это всего лишь зависания от изменения кода Laravel 5.0, которое было (kinda) отменено. Но команда artisan make
по-прежнему существует для них, поэтому они не могут быть мертвыми. Кроме того, что связано с командой самообучения (по умолчанию используется метод handle
) и тот, который "требует" класса обработчика (run artisan make:command --handler
)? Как вы на самом деле их выполняете? Вручную с помощью (new App\Command\SomeCommand)->handle();
или (new App\handlers\SomeCommandHandler)->handle(new App\Command\SomeCommand)
, или есть какая-то скрытая система, о которой я не знаю (может быть, они могут быть отправлены с помощью диспетчера задания/очереди)? Также вы можете создавать команды "queued" artisan make::command --queued
, так как они тоже отличаются?
Я думаю, мой вопрос сводится к следующему:
- Что такое реальная (семантическая и функциональная) разница между ними?
- Каков правильный способ их запуска?
- Что лучше для моих целей в целом-отдельном бите кода, который нужно запускать, каким бы способом я ни считал нужным?
Я нашел информацию в документации о том, как использовать очереди и создавать консольные команды, но ничего конкретно о том, когда их использовать или что-либо в командных классах и обработчиках.
Связанный, но не совсем то же (также, он не отвечает): Команды и задания Laravel 5.1
Ответы
Ответ 1
Я вижу эти "объекты" следующим образом: (Я добавил некоторые примеры кода из одного из моих побочных проектов)
Консоль
Вещи, которые я хочу выполнить из командной строки (Как вы упомянули в своем примере с "Удалить файлы старше x" ). Но дело в том, что вы можете извлечь бизнес-логику из нее в команду .
Пример: консольная команда с огнем команды для извлечения изображений из Imgur. Класс FetchImages
содержит фактическую бизнес-логику выборки изображений.
Command
Класс, содержащий фактическую логику. Вы также можете вызвать эту команду из своего приложения с помощью app()->make(Command::class)->handle()
.
Пример: Команда, упомянутая в примере 1. Содержит логику, которая фактически вызывает API для Imgur и обрабатывает возвращенные данные.
Работа
Я сделал это приложение с Laravel 5.0, поэтому jobs
не было тогда. Но, как я вижу, Джобс как команды, но они поставлены в очередь и могут быть отправлены. (Как вы могли видеть в этих примерах, эти команды реализуют ваши упомянутые интерфейсы SelfHandling
и ShouldBeQueued
).
Я считаю себя опытным разработчиком Laravel, но те изменения в Commands
и jobs
довольно трудно понять.
EDIT:
Из документов Laravel:
Каталог приложений/команд был переименован в приложение/Джобс. Однако вам не нужно перемещать все свои команды в новое место, и вы можете продолжать использовать команду make: command and handler: command Artisan для генерации ваших классов.
Аналогично, каталог app/Handlers был переименован в приложение /Listeners и теперь содержит только прослушиватели событий. Однако вам не требуется перемещать или переименовывать существующие обработчики команд и событий, и вы можете продолжать использовать команду обработчик: event для генерации обработчиков событий.
Предоставляя обратную совместимость для структуры папок Laravel 5.0, вы можете обновлять свои приложения до Laravel 5.1 и медленно обновлять свои события и команды до своих новых местоположений, когда это удобно для вас или вашей команды.
Ответ 2
Консольные команды
В течение некоторого времени у Laravel были консольные команды. Они в основном неизменны и работают так, как они всегда есть. Проще говоря, они являются эквивалентом маршрутов для командной строки - точки входа в приложение. Они никоим образом не связаны с...
Командная шина
В Laravel 5.0 реализована реализация команды Command Bus
pattern - Command Bus Commands. (Я считаю, что они были переименованы в "Джобс" из-за возникающей путаницы между ними и командами CLI).
Командная шина как две части - объект, который представляет собой команду, которая должна быть выполнена, с любыми и всеми данными, которые ему нужны (задание), и класс для выполнения команды (обработчик).
Обработчик
В laravel вы можете объявить задание самостоятельной обработкой, то есть иметь сам метод дескриптора.
Если вы хотите зарегистрировать обработчик команд, вы можете вызвать следующее у поставщика услуг:
app('Illuminate\Bus\Dispatcher')->maps(['Job' => 'Handler']);
где Job - это имя класса для задания, а Handler - это имя класса для обработчика.
Каталог обработчиков в laravel 5.0 был способом неявного объявления этих отношений (т.е. EmailCommand
в папке команд имело бы EmailCommandHandler
в папке обработчиков).
Отправка команды
Вы можете использовать следующую команду для отправки команды.
app('Illuminate\Bus\Dispatcher')->dispatch(new EmailPersonCommand('[email protected]', $otherdata));
Очередь
Задания, по умолчанию, будут запускаться, как только они будут вызваны (или отправлены). Установка их как ShouldQueue
всегда будет передавать их в очередь при отправке.
Если вы хотите периодически запускать их синхронно и асинхронно в другое время, вы можете вызвать $dispatcher->dispatchToQueue($job)
, когда вы хотите, чтобы они были в очереди. Это все, что происходит внутри, когда вы передаете задание ShouldQueue
на ->dispatch()
.
edit: To Queuing (или нет)
Я только что посмотрел на диспетчера. Метод dispatch
проверяет, является ли команда ShouldQueue
, и либо переводит ее на dispatchToQueue
, либо dispatchNow
. Вы можете вызвать любой из этих методов непосредственно вместо dispatch
с помощью вашей команды, если вы хотите переопределить поведение по умолчанию.
Итак, в вашем случае, в зависимости от того, что "поведение по умолчанию" вашего задания (т.е. будет ли оно обычно поставлено в очередь?):
- используйте ShouldQueue
и используйте dispatchNow
в команде CLI.
- не иметь его ShouldQueue
и использовать dispatchToQueue
, где вы вызываете его в своем коде.
Из его звуков я бы сделал первый.
Ответ 3
Просто добавление к фактическим ответам.
Работы в Laravel >= 5.1 являются командами Bus в Laravel 5.0.
Это изменение имени только из-за путаницы между Console\Commands
(команды, запускаемые с консоли) и Command Bus
(содержащие Commands
) для задач приложения.
Нельзя смешивать:
-
Command Bus
: используется для "инкапсуляции задач вашего приложения" (из larvel 5.0 doc), который теперь переименован в Jobs
-
Console\Commands
: используется для "Artisan [...] интерфейса командной строки, включенного в Laravel" (из laravel 5.1 docs), который не изменяется в Laravel с 4.x