Laravel Nested Jobs - PullRequest
       24

Laravel Nested Jobs

0 голосов
/ 03 июля 2019

Я создал задание с циклом foreach, который отправляет другое задание. Есть ли способ запустить даже когда все вложенные задания завершены?

При срабатывании вот что происходит

Шаг 1. Сначала я запускаю пакетное задание GenerateBatchReports::dispatch($orderable);

Шаг 2. Затем мы запускаем цикл и ставим в очередь другие задания

/**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $dir = storage_path('reports/tmp/'.str_slug($this->event->company) . '-event');

        if(file_exists($dir)) {
            File::deleteDirectory($dir);
        }

        foreach($this->event->participants as $participant) {
            $model = $participant->exercise;

            GenerateSingleReport::dispatch($model);
        }
    }

Мне просто нужно знать, когда все вложенные задания выполнены, чтобы я мог сжать отчеты и отправить их пользователю по электронной почте. Когда пакетное задание выполнено, ставя в очередь все вложенные задания, оно удаляется из списка. Есть ли способ сохранить задание до тех пор, пока не будут выполнены вложенные задания, а затем запустить событие?

Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Для Laravel> = 5,7

Вы можете использовать метод dispatchNow.Это будет поддерживать работу родительского задания во время его обработки:

https://laravel.com/docs/5.8/queues#synchronous-dispatching

Родительское задание:

public function handle()
{
    // ...

    foreach($this->event->participants as $participant) {
        $model = $participant->exercise;

        GenerateSingleReport::dispatchNow($model);
    }

    // then do something else...
}

Для уровня 5.2 - 5.6

Вы можете использовать соединение sync:

https://laravel.com/docs/5.5/queues#customizing-the-queue-and-connection

Убедитесь, что соединение определено в вашем config/queue.php:

https://github.com/laravel/laravel/blob/5.5/config/queue.php#L31

Родительское задание (ПРИМЕЧАНИЕ. Этот синтаксис для 5.5. Документы немного отличаются для 5.2):

public function handle()
{
    // ...

    foreach($this->event->participants as $participant) {
        $model = $participant->exercise;

        GenerateSingleReport::dispatch($model)->onConnection('sync');
    }

    // then do something else...
}
0 голосов
/ 03 июля 2019

Вы можете использовать цепочку заданий Laravel .Это позволяет вам запускать несколько заданий в последовательности, а в случае сбоя одно из остальных в цепочке не будет выполнено.

Основной синтаксис выглядит следующим образом:

FirstJob::withChain([
    new SecondJob($param),
    new ThirdJob($param)
])->dispatch($param_for_first_job);

В вашемВ этом случае вы можете добавить все ваши задания GenerateSingleReport в массив, кроме первого, и затем добавить, а затем добавить последнее задание, которое вы хотите запустить, в конец массива.Затем вы можете передать этот массив методу withChain на первом задании.

$jobs = [];
$first_job = null;
$first_parameter = null;

foreach($this->event->participants as $participant) {
    $model = $participant->exercise;

    if (empty($first_job)) {
        $first_job = GenerateSingleReport;
        $first_parameter = $model;
    } else {
        $jobs[] = new GenerateSingleReport($model);
    }            
}

$jobs[] = new FinalJob();

$first_job->withChain($jobs)->dispatch($first_parameter);
...