如果我调用以下内容:
return AdventureJob::dispatch($event->character->refresh(), $event->adventure, $event->levelsAtATime)->delay($timeTillFinished);
这将创建一个延迟 x 分钟的作业。我的作业都是通过redis处理的,有没有办法获取这个特定的作业或从队列中删除这个特定的作业?
人们谈论 php artisan 命令然后删除所有作业,这不是我想要的我想要获取有关此作业的某种信息(作业 ID?或队列 ID?Redis ID?)然后存储在数据库中,以便如果然后玩家取消冒险,我可以使用它在队列中找到该作业并将其删除,假设它没有运行。
没有直接或简单的方法可以做到这一点。延迟的作业保留在sorted sets
待处理时间为score
和工作负载作为value
.
有多种方法可以从排序集中删除元素(大多数方法需要一些努力,具体取决于延迟队列的大小),例如
- 您获得分派作业的“准确”有效负载,然后使用ZREM将其删除。这很困难,因为对象(具有所有参数的作业的序列化版本)可能很大,并且您无法创建“精确”作业,因为它具有唯一标识符。你可以通过以下方式获取它的列表分数范围与
WITHSCORES
。它将为您提供职位列表及其分数。您可以使用分数来识别要延迟的工作。获取值(序列化有效负载)然后使用ZREM
.
- 如果在特定时间只有一项作业需要处理,您可以使用ZREM范围按分数使用处理时间。如果当时有 n 个作业需要处理,那么其他作业也可以被删除,因为
ZREMRANGEBYSCORE
需要时间间隔。
- 您可以尝试使用ZSCAN扫描整个延迟列表(带分页)并找到作业的分数和标识符,然后使用ZREMRANGEBYLEX使用标识符将其删除。
- 另一种方法是在开始时设置取消条件
handle
方法。这个需要应用层开发。每当您将作业推送到队列时,您都会向该作业发送一个标识符,也将相同的标识符(您可以理解的)放入Redis中(使用EXPIRE
大于延迟时间)。当你想取消它时,然后从Redis中删除它。在handle方法内部检查Redis中是否存在给定的标识符,如果不存在则从代码块提前返回。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)