基于 Bus 门面或 dispatch 函数推送队列任务


推送任务到队列

在 Laravel 中,主要通过 Command Bus 来推送任务到队列。我们可以通过 Bus 门面来代理对 Command Bus 的调用:

-w638

Bus 门面可以使用任务类定义的 connectionqueuedelay 属性自定义任务推送。

立即执行任务

还可以通过 Command Bus 来直接运行任务,而不是推送到队列。例如,在一个队列任务中立即执行另一个队列任务可以这么做:

-w648

RestartNginx 任务会被推送到 sync 通道然后立即执行其 handle 方法,如果执行失败也会被推送到 failed_jobs 数据表。

响应后执行任务

对于某些足够小、不需要推送到队列但是也不想影响用户等待时间的任务,可以放到响应发送后执行:

-w691

只适用于耗时很短的小任务。

推送任务链

除此之外,Command Bus 还引入了多个方法来支持推送任务链、任务批处理。

要推送任务链,可以使用 Bus 门面的 chain 方法:

-w638

任务链中的任务会按顺序一个接一个执行。

还可以在推送时指定队列名称、队列连接:

-w657

以及在任务执行失败后进行兜底处理的回调函数:

-w658

推送批处理任务

要推送任务批处理,可以使用 Bus 门面的 batch 方法:

-w612

和推送任务链一样,也可以指定队列名称和队列连接:

-w612

如果任意任务执行失败,则整个批处理会被标记为失败,你可以通过 allowFailures 方法来改变这一默认行为:

-w652

还可以通过闭包定义不同场景的业务逻辑:

-w669

使用 dispatch 辅助函数

除了 Bus 门面外,还可以通过 dispatch 辅助函数执行任务推送:

-w635

如果 SendInvoice 实现了 ShouldQueue 接口,则推送到队列,否则立即执行。

要实现响应发送后执行,可以这么做:

-w615

Bus 门面一样,你也可以指定队列名称和队列连接:

-w682

我们来看下 dispatch 辅助函数执行的时机:

-w656

SendInvoice 任务会在 return 方法之后,响应被发送给客户端之前执行。在这个时间点,OrderController::store() 方法的作用域已经结束,而这正是 Bus::dispatch() 方法执行的时机。但这与 dispatch 函数又有何关联呢?

原来,dispatch() 会返回 Illuminate\Foundation\Bus\PendingDispatch 对象的实例,它使用了 __destruct() 方法进行真正的推送工作,在这里,调用的正是 Bus 门面代理的 Command Bus 对象实例的 dispatch 方法:

-w649

所以,dispatch 辅助函数和 Bus 门面底层执行的是同一套代码逻辑。

使用 dispatch 静态方法

队列任务使用的 Dispatchable Trait 提供了很多分发任务相关的方法,比如 dispatch

-w632

该方法和 dispatch() 辅助函数功能类似,真正调用分发动作也是在所在方法作用域结束之后。


点赞 取消点赞 收藏 取消收藏

<< 上一篇: 如何设计可靠的消息队列任务

>> 下一篇: 没有下一篇了