为了账号安全,请及时绑定邮箱和手机立即绑定

取消 Laravel 中的作业

取消 Laravel 中的作业

PHP
芜湖不芜 2023-08-06 14:53:44
如果我调用以下内容:return AdventureJob::dispatch($event->character->refresh(), $event->adventure, $event->levelsAtATime)->delay($timeTillFinished);这将创建一个延迟 x 分钟的作业。我的作业都是通过redis处理的,有没有办法获取这个特定的作业或从队列中删除这个特定的作业?人们谈论 php artisan 命令然后删除所有作业,这不是我想要的我想要获取有关此作业的某种信息(作业 ID?或队列 ID?Redis ID?)然后存储在数据库中,以便如果然后玩家取消冒险,我可以使用它在队列中找到该作业并将其删除,假设它没有运行。
查看完整描述

1 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

没有直接或简单的方法可以做到这一点。延迟的作业保留在sorted sets待处理时间score和作业负载中value

有多种方法可以从排序集中删除元素(大多数方法需要一些努力,具体取决于延迟队列的大小),例如

  • 您获得分派作业的“准确”有效负载,然后使用ZREM将其删除。这很困难,因为对象(具有所有参数的作业的序列化版本)可能很大,并且您无法创建“精确”作业,因为它具有唯一标识符。您可以使用ZRANGEBYSCORE和获取它的列表WITHSCORES。它将为您提供职位列表及其分数。您可以使用分数来识别要延迟的工作。获取值(序列化有效负载)然后使用ZREM.

  • 如果在特定时间只有一项作业要处理,您可以使用ZREMRANGEBYSCORE并使用处理时间。如果正好有 n 个作业需要在该时间处理,那么其他作业也可以被删除,因为ZREMRANGEBYSCORE需要时间间隔。

  • 您可以尝试使用ZSCAN扫描整个延迟列表(带分页)并找到作业的分数和标识符,然后使用ZREMRANGEBYLEX和标识符将其删除。

  • 另一种方法可以是在方法的开头放置取消条件handle。这个需要应用层开发。每当您将作业推送到队列时,您都会向该作业发送一个标识符,并将相同的标识符(您可以理解的)也放入Redis中(大于EXPIRE延迟时间)。当你想取消它时,然后从Redis中删除它。在handle方法内部检查Redis中是否存在给定的标识符,如果不存在则从代码块提前返回。


查看完整回答
反对 回复 2023-08-06
  • 1 回答
  • 0 关注
  • 69 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信