Laravel Queues:仅在处理另一组作业之后才如何处理一组作业?

时间:2019-03-12 20:53:07

标签: php laravel

我有两套工作:

  • Set1 :作业A,作业B,作业C
  • 设置2:作业D,作业E,作业F

如何处理 Set1 中的所有作业,然后处理 Set2 中的作业?

我尝试了工作链接。但是,如果作业链的先前作业失败,则作业链会停止处理作业。即使其中之一发生故障,我也要全部处理。

它应该处理 Set1 (A,B,C)中的所有作业,并且如果作业A的处理失败,则B和C的处理不应停止。 当处理完 Set1 的所有作业时(无论成功还是失败),它都应拾取 Set2 中的作业进行处理。

此处的作业顺序不是优先顺序。它们可以按任何顺序进行处理。
唯一规则是,只有在处理 Set1 中的所有作业之后,才能处理 Set2 中的作业。

我无法处理延迟派发,因为处理 Set1 作业所需的时间差异很大。

3 个答案:

答案 0 :(得分:0)

一个想法是创建一个JobSet作业和一个JobWorker作业。

因此,作业集将新的JobWorker(“ A”),JobWorker(“ B”),JobWorker(“ C”)作为参数,然后分派所有这些。

dispatch(new JobSet(new JobWorker("A"), new JobWorker("B"), new JobWorker("C")));

和“ JobSet”工作来激发灵感

class JobSet implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $a;
    private $b;
    private $c;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(JobWorker $a, JobWorker $b, JobWorker $c)
    {
        $this->a = $a;
        $this->b = $b;
        $this->c = $c;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        dispatch($this->a);
        dispatch($this->b);
        dispatch($this->c);
    }
}

答案 1 :(得分:0)

您可以将它们分派到不同的队列:

local_path_thumb

并在检查set2之前运行确保set1为空的工作程序:

A::dispatch()->onQueue('set1');
B::dispatch()->onQueue('set1');
C::dispatch()->onQueue('set1');

D::dispatch()->onQueue('set2');
E::dispatch()->onQueue('set2');
F::dispatch()->onQueue('set2');
  

要开始在继续执行php artisan queue:work --queue=set1,set2 队列上的任何作业之前先验证所有high队列作业已被处理的工作程序,请将以逗号分隔的队列名称列表传递到{{1 }}命令:

low
     

https://laravel.com/docs/5.8/queues#running-the-queue-worker

编辑:

您可以通过启动更多工作人员来解决User2的work个工作,从而延迟User1的php artisan queue:work --queue=high,low 个工作。

答案 2 :(得分:0)

现在可以使用 Laravel 8.x 中的 Job Batching 来完成:

$batch = Bus::batch([
    new ImportCsv(1, 100),
    new ImportCsv(101, 200),
    new ImportCsv(201, 300),
    new ImportCsv(301, 400),
    new ImportCsv(401, 500),
])->then(function (Batch $batch) {
    // All jobs completed successfully...
})->catch(function (Batch $batch, Throwable $e) {
    // First batch job failure detected...
})->finally(function (Batch $batch) {
    // The batch has finished executing...
})->dispatch();