Laravel-按顺序运行作业



我正在学习Laravel,正在做一个运行Horizon的项目来学习工作。我被困在一个地方,我需要一个接一个地运行相同的工作几次。

这是我目前正在做的事情

<?php
namespace AppHttpControllers;
use AppHttpControllersController;
use AppModelsSubscriptions;
class MailController extends Controller
{

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

这工作正常,除了它在多个工作人员之间运行作业并且不按保证的顺序运行。有没有办法一个接一个地运行作业?

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

来自拉拉维尔文档

作业

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

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

所以在你上面的例子中

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

应该给出预期的结果!

更新

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

一切都取决于您将运行多少队列工作线程

如果运行单队列工作线程,则将按排队顺序处理这些jobs。但是,如果您运行多个队列工作线程,显然它们将同时运行。这就是队列应该如何工作。添加一些任务,它们可能会以不同的顺序同时运行。

当然,如果您想确保这些jobs之间有暂停,您可以在内部each添加一些 sleep((,但假设您在控制器中运行它(这可能不是一个好主意,因为万一你有百万订阅(它可能不是最好的解决方案。

你需要的是作业链。

您可以在Laravel网站上阅读所有相关信息: 链条

祝你好运

要添加有关@Josh答案的额外信息,如果您的一个作业IlluminateContractsQueueShouldQueue接口实现,则链中的其他作业必须实现ShouldQueue接口,否则它们将不会链接。

例如,这里如果类ProcessPodcast实现ShouldQueueOptimizePodcast也必须实现这个接口才能包含在链中。

class ProcessPodcast implements ShouldQueue {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
...
}
class OptimizePodcast implements ShouldQueue {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
...
}

相关内容

  • 没有找到相关文章

最新更新