Laravel:排队的作业如何在失败时将自身转移到failed_jobs?

时间:2018-06-27 09:16:52

标签: laravel laravel-5

我有一个可排队的工作,可以创建一个新用户...

<?php

namespace App\Jobs;

...

class CreateNewUser implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /** @var array */
    public $newUserData;

    public function __construct($newUserData)
    {
        $this->newUserData = $newUserData;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $email = $this->newUserData['email'];
        if (User::whereEmail($email)->count()) {
            // TODO: Make this job fail immediately
            throw new UserWithEmailExistsException('User with email ' . $email . ' already exists');
        }

        ...
    }
}

这是一个排队的工作,因为我们批量处理CSV,以便一次加载多个用户,每个CSV都需要2个表中的一个条目,而角色和权限表中还需要多个条目。同步太慢。

我在handle()方法的开始处进行了检查,以查看是否尚未创建具有相同电子邮件地址的用户(因为可能要排队多个作业来创建具有相同电子邮件地址的用户电子邮件),并且会抛出自定义异常。

如果该检查失败,那么我永远都不想让队列工作者再次尝试此作业,因为我知道该作业将无限期地继续失败,这是浪费时间再次尝试。 我如何手动强制该作业一次全部失败并移至“失败的作业”表?

P.S。我已经找到了关于fail()助手和$this->markAsFailed()方法的答案,但是这些仍然不能立即将作业从作业移到failed_jobs。

1 个答案:

答案 0 :(得分:0)

我已经完全为您重写了答案。昨晚我很着急,以为可以为您的问题提供快速解决方案,对于错误消息,我们深表歉意。

您可以执行类似下面的代码的操作,这不会将作业放入失败的作业表中,但可以防止重新尝试。希望对您有所帮助。

<?php

namespace App\Jobs;

use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class TestJob extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        if ($this->attempts() > 0) {
            // Will not reattempt this job.
            return;
        }

        throw new \Exception('Job will fail.');
    }
}