【问题标题】:Inconsistent behavior on Laravel Queue JobLaravel 队列作业的行为不一致
【发布时间】:2020-01-15 16:41:51
【问题描述】:

我的工作是这样的:

<?php

namespace App\Jobs;

use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Redis;

class FakeJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    /**  @var User */
    private $user;
    public $tries = 30;

    /**
     * Create a new job instance.
     *
     * @param User $user
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try {
            Redis::throttle('key')->allow(1)->every(60)->then(function () {
                // Job logic...
                throw new \Exception('fake exception');
                $this->logInfo($this->user->name);
            });
        } catch(\Illuminate\Contracts\Redis\LimiterTimeoutException $e) {
            $this->logInfo('inside LimiterTimeout catch, ' . $e->getMessage());
            $this->release(1);
        }
    }

    public function failed(\Exception $exception) {
        // Send user notification of failure, etc...
        $this->logInfo('inside failure, ' . $exception->getMessage());
    }

    public function logInfo($message) {
        $path = storage_path('logs/FakeJob.log');
        $logText = time() . ' ' . $message;
        file_put_contents($path, $logText.PHP_EOL , FILE_APPEND | LOCK_EX);
    }
}

现在您会注意到我在句柄函数中有一个 Redis 限制器,并且我立即在回调中抛出了一个错误。这就是我正在测试的内容,而那个错误就是问题所在。

你看,我试图区分 LimiterTimeoutExceptions 和 Throttler 回调中抛出的异常。当我通过sync 连接运行作业时,一切都按预期工作:FakeJob::dispatch($user)-&gt;onConnection('sync'); 因为我在前一个请求的 60 秒内发出请求而发生的错误进入 LimiterTimeoutException catch 块,并且在油门回调转到failed函数。

但是当我通过我的默认调度程序(即数据库)安排作业时,似乎每个错误都通过LimiterTimeoutException catch 块,直到我达到重试限制 - 该错误进入failed 函数,但不是“假异常”错误。

我对此感到非常困惑。

注意:即使我的“假异常”最终被LimiterTimeoutException catch 块捕获,$e-&gt;getMessage() 函数也不会因为某种原因返回fake exception。但我 100% 确定是那个错误导致它到达那里,因为这绝对不是由于这些测试中的节流阀造成的。

【问题讨论】:

    标签: laravel queue jobs


    【解决方案1】:

    好吧,实际上发生的事情是它不会在failed() 函数中结束,直到它达到重试限制,无论如何,无论抛出任何异常。如果我想以与其他所有错误不同的方式处理 LimiterTimeoutException 错误,我必须将我的 Redis::throttle 调用包装在 try-catch 中,并检查 catch 中的错误类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-20
      • 2019-11-28
      • 2017-12-02
      • 2016-09-01
      • 2017-03-28
      相关资源
      最近更新 更多