在Queue ::之前检查Laravel作业,然后在处理之前删除它们

时间:2017-03-26 08:21:16

标签: php laravel queue rabbitmq

我被赋予了使用Queue ::来查看AppServiceProvider的想法,之后作为一种添加对我不再想要运行的作业的检查的方法并删除它们而不必为我写的每个作业添加检查。
背景,我正在开发一个执行审计的SaaS,因此审计可以运行数小时,并且可以完成1000个工作。如果我可以在作业中找到一个审计ID,并将其与已取消的任何审计ID的Cache数组进行比较,我可以节省时间。

所以我得到的是如何在Queue ::之前解开Job来获取id来检查? (正常laravel队列代码,并使用RabbitMQ)

由于作业被包装在一个或两个Event类中,我无法将数据转储到屏幕上以查看,只是为了记录队列中的文件。

app / Providers / AppServiceProvider.php中的

Queue::before(function (JobProcessing $event) {
    // $event->connectionName
    // $event->job
    $job = $event->job->payload();
    $obj = unserialize($job['data']['data']);
}

就我感兴趣的事件而言,有效负载包含数据,数据是我感兴趣的序列化对象。这似乎不是最好的方法,或者看看如何与它交互以更好的方式。

感谢

1 个答案:

答案 0 :(得分:0)

我正处于涉及webhook交付的类似问题的中间。通过开发人员门户网站,我们允许用户重新排队webhook(以缩短对后退传递尝试的等待)。由于这可以为同一个webhook创建第二个工作,我们想方设法将原始文件识别为过时。

true构造函数:

app/Jobs/DeliverWebhook.php

在这里,您可以看到我们已将public function __construct(Webhook $webhook) { $this->webhook = $webhook; $this->queued_at = Carbon::now(); Cache::put( 'DeliverWebhook.'. $this->webhook->id .'.QueuedAt', $this->queued_at, Carbon::now()->addDays(3) ); } 属性附加到此作业实例。 (我们也可以通过使用queued_atuniqid()之类的内容使其更加独特,以避免在排队时出现潜在的双击问题或类似的问题。)

第二部分是我们设置半唯一缓存键以匹配此random_bytes()时间。我将它设置为在我们退回重试尝试结束后的3天内过期。

现在,当一个作业被选中进行处理时,我可以根据缓存的值检查作业实例的queued_at属性,如果作业旧,则删除该作业。

在我的queued_at AppServiceProvider方法中:

boot

最后抛出异常,因为默认情况下,队列工作程序在调用Queue::before(function ($event) { if ($event->job->queue == 'webhooks' && $event->job->getName() == 'DeliverWebhook') { $cache_key = 'DeliverWebhook.'. $event->job->instance->webhook->id .'QueuedAt'; if ($event->job->instance->queued_at < Cache::get($cache_key)) { $event->job->delete(); throw new JobRequeuedException; } } }); 之前不会检查作业是否被删除。抛出异常会强制工作人员跳过$job->fire()并跳转到fire()方法。

注意:我仍然需要对此进行适当的测试。