如果我称之为:
return AdventureJob::dispatch($event->character->refresh(), $event->adventure, $event->levelsAtATime)->delay($timeTillFinished);
这将创建一个延迟x分钟的作业。我的作业都是通过redis处理的,有没有办法得到这个特定的作业或者从队列中删除这个特定的作业?
人们谈论php artisan命令,然后删除所有作业,这不是我想要的,我想得到某种信息(作业id?或队列id?redis id?)。
1条答案
按热度按时间t1rydlwq1#
没有直接或简单的方法可以做到这一点。被耽搁的工作被保留了下来
sorted sets
待处理时间score
工作负载作为value
.有几种方法可以从已排序的集合中移除元素(大多数方法都需要一些努力,具体取决于延迟队列的大小),例如
您将获得已调度作业的“精确”负载,然后使用zrem将其删除。这很难,因为对象(包含所有参数的作业的序列化版本)可能很大,并且您无法创建“精确”作业,因为它具有唯一标识符。你可以用zrangebyscore和
WITHSCORES
. 它会给你一份有分数的工作清单。您可以使用分数来识别被延迟的作业。获取值(序列化负载),然后使用ZREM
.如果在特定时间只有一个作业要处理,则可以使用zremrangebyscore和使用处理时间。如果当时有n个作业要处理,那么也可以删除其他作业
ZREMRANGEBYSCORE
需要时间间隔。您可以尝试使用zscan扫描整个延迟列表(分页)并找到作业的分数和标识符,然后使用带有标识符的zremrangebylex将其删除。
另一种方法是在开始时设置取消条件
handle
方法。这需要应用层开发。每当您将作业推送到队列时,您都会向作业发送一个标识符,在redis中也放置相同的标识符(您可以理解)(使用EXPIRE
大于延迟时间)。当你想取消它,然后从redis中删除它。在handle方法内部检查redis中是否存在给定的标识符,如果不存在则提前从代码块返回。