Laravel-按顺序运行作业

时间:2018-10-25 15:08:23

标签: laravel laravel-5 redis laravel-queue laravel-horizon

我正在学习Laravel,他正在一个运行Horizo​​n的项目中学习工作。我被困在一个地方,需要一次又一次地做几次相同的工作。

这是我目前正在做的

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Subscriptions;
class MailController extends Controller
{


    public function sendEmail() {
        Subscriptions::all()
        ->each(function($subscription) {
            SendMailJob::dispatch($subscription);
        });
    }
}

这很好用,除了它可以跨多个工人运行作业,而且顺序不保证。有什么方法可以依次运行作业吗?

3 个答案:

答案 0 :(得分:1)

正如您在问题中提到的,您正在寻找的是工作链。

From the Laravel docs

  

作业链接使您可以指定应按顺序运行的排队作业列表。如果序列中的一个作业失败,则其余的作业将不会运行。要执行排队的作业链,可以对任何可调度作业使用withChain方法:

ProcessPodcast::withChain([
    new OptimizePodcast,
    new ReleasePodcast
])->dispatch();

所以在上面的示例中

$mailJobs = Subscriptions::all()
    ->map(function($subscription) {
        return new SendMailJob($subscription);
    });

Job::withChain($mailJobs)->dispatch()

应该给出预期的结果!

更新

如果您不想使用初始作业进行链接(如上面的文档示例中所示),则应该能够创建一个具有Job的空use Dispatchable;类。那你可以用我上面的例子

答案 1 :(得分:0)

一切取决于您要运行多少队列工作者

如果您运行单队列工作器,则这些jobs将按照其排队的顺序进行处理。但是,如果您运行多个队列工作器,则显然它们将在同一时间运行。这就是队列的工作方式。您添加了一些任务,它们可能会以不同的顺序同时运行。

当然,如果要确保在jobs之间存在暂停,则可以在each内添加一些sleep(),但前提是您正在运行这在控制器中(这可能不是一个好主意,因为如果您有数百万的订阅,这可能不是最佳解决方案。

答案 2 :(得分:0)

您需要的是工作链。

您可以在Laravel网站上找到所有相关信息:Chain

祝你好运