请教关于异步事件任务的唯一的问题
在文档中,队列那章里面,Unique Jobs
曾提到:文档链接
- 如果任务的另一个实例已经在队列中并且尚未完成处理,则不会分派该任务。
- 在现有任务完成处理之前,任何具有相同 product ID 的任务都将被忽略。
说明一下,我的事件驱动是基于redis
,缓存驱动支持原子锁,我用一个简单的例子来提问:
事件示例:
EventServiceProvider
添加事件'App\Events\Test\RollEvent' => [ 'App\Listeners\Test\CapterBEventListener', ],
RollEvent
默认配置,不做说明CapterBEventListener
为异步侦听器,为了测试uniqueId
统一设置为5
,并在执行过程中阻塞10
秒钟<?php namespace App\Listeners\Test; use App\Events\Test\RollEvent; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; class CapterBEventListener implements ShouldQueue, ShouldBeUnique { use InteractsWithQueue; private $_data = 0; /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param RollEvent $event * @return void */ public function handle(RollEvent $event) { echo 'RoolEventB===',PHP_EOL; sleep(10); echo '阻塞结束====',PHP_EOL; } public function shouldQueue(RollEvent $event) { return true; } public function uniqid(RollEvent $event) { return 5; } }
测试事件:
$ php artisan tinker
>>> $evet1 = new App\Events\Test\RollEvent(5)
>>> $evet2 = new App\Events\Test\RollEvent(5)
>>> event($evet1)
>>> event($evet2)
测试结果:
还是按照顺序执行了两遍
我的理解是在事件唯一ID中,第一个事件没有执行前,添加相同的ID事件,将不会执行
> [2022-04-30 18:29:17][VlGCdjmgniuAKbFuJ6QL7t7jLuhxzEN6] Processing: App\Listeners\Test\CapterBEventListener > RoolEventB=== > 阻塞结束 > [2022-04-30 18:29:27][VlGCdjmgniuAKbFuJ6QL7t7jLuhxzEN6] Processed: App\Listeners\Test\CapterBEventListener > [2022-04-30 18:29:27][uh4p7EuDmVSVEf17SrbcoUdKNQ1xVKzo] Processing: App\Listeners\Test\CapterBEventListener > RoolEventB=== > 阻塞结束 > [2022-04-30 18:29:37][uh4p7EuDmVSVEf17SrbcoUdKNQ1xVKzo] Processed: App\Listeners\Test\CapterBEventListener
请问事件ID指的是什么唯一?为何相同编号却执行了两遍?
我将事件侦听器改为任务,测试成功了
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class TestPodcast implements ShouldQueue, ShouldBeUnique { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Create a new job instance. * * @return void */ public function __construct() { // } /** * Execute the job. * * @return void */ public function handle() { echo 'handle start', PHP_EOL; sleep(10); echo 'handle end', PHP_EOL; } public function uniqueId() { return 5; } }
连续执行,只commit一次
>>> App\Jobs\TestPodcast::dispatch(); >>> App\Jobs\TestPodcast::dispatch();
请问为什么在事件侦听器上不行呢?
推荐文章: