【问题标题】:Check Laravel Jobs inside Queue::before to delete before they are processed检查 Queue::before 中的 Laravel Jobs 以在处理之前删除
【发布时间】:2017-08-18 23:46:42
【问题描述】:

我得到了使用 Queue::before 查看 AppServiceProvider 的想法,以此为我不再想运行和删除它们的作业添加检查,而无需为我编写的每个作业添加检查。
背景,我正在开发一个进行审计的 SaaS,因此审计可以运行数小时并包含 1000 多个工作。如果我可以在作业通过时在作业中查找审核 ID,并与已取消的任何审核 ID 的缓存数组进行比较,我可以节省时间。

那么我要做的是如何在 Queue::before 中解开 Job 以获取要检查的 id? (普通 laravel 队列代码,使用 RabbitMQ)

由于作业被包裹在一层或两层事件类中,我无法将数据转储到屏幕上查看,只能记录文件,因为它在队列中。

在 app/Providers/AppServiceProvider.php 中:

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

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

谢谢

【问题讨论】:

  • 我怎样才能在一个地方为每个作业中的一个键编写检查,而不是将检查编码到每个作业文件 php 中?

标签: php laravel queue rabbitmq


【解决方案1】:

我遇到了一个涉及 webhook 交付的类似问题。通过开发人员门户,我们允许用户重新排队 webhook(以缩短对回退交付尝试的等待)。由于这可能会为同一个 webhook 创建第二个作业,因此我们想方设法将原始作业标识为已过期。

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_at 属性附加到此作业实例。 (我们可能还可以通过使用 uniqid()random_bytes() 之类的东西来使其更加独特,以避免在排队时出现潜在的双击问题或类似的打嗝。)

第二部分是我们设置半唯一缓存键来匹配这个queued_at时间。我将其设置为在 3 天后过期,超过我们的回退重试尝试结束。

现在,当一个作业被提取进行处理时,我可以检查作业实例的queued_at 属性与缓存值,如果它是旧的则删除它。

在我的AppServiceProviderboot 方法中:

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-&gt;fire()之前不会检查作业是否被删除。抛出异常会强制worker跳过fire()并跳转到handleJobException()方法。

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

【讨论】:

  • 这在技术上是 Laravel 5.5 的解决方案,但它可能适用于其他版本。
猜你喜欢
  • 1970-01-01
  • 2020-08-28
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2015-12-27
  • 2016-04-24
  • 2020-01-29
  • 1970-01-01
相关资源
最近更新 更多