取消作业 Laravel

Cancel Jobs In Laravel

如果我调用以下内容:

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 to remove it. It is hard because the object(serialized version of the job with all the parameters) can be huge and you can't create the "exact" job because it has a unique identifier. You can get the list of it with ZRANGEBYSCOREWITHSCORES。它会给你一份工作清单和他们的分数。您可以使用分数来识别被延迟的作业。获取值(序列化有效负载)然后使用 ZREM.
  • 如果您在特定时间只有一个作业要处理,可以使用 ZREMRANGEBYSCORE 并使用已处理的时间。如果恰好在那个时间有 n 个作业要处理,那么也可以删除其他作业,因为 ZREMRANGEBYSCORE 需要时间间隔。
  • 您可以尝试使用 ZSCAN to scan the whole delayed list(with pagination) and find the score and identifier of the job, and then use ZREMRANGEBYLEX 和标识符来删除它。
  • 另一种方法是将取消条件放在 handle 方法的开头。这个需要应用层开发。每当您将作业推送到队列时,您都会向作业发送一个标识符,在 Redis 中也放入相同的标识符(您可以理解)(EXPIRE 大于延迟时间)。当你想取消它时,然后从 Redis 中删除它。在 handle 方法内部检查 Redis 中是否存在给定的标识符,如果不早 return 来自代码块。