Laravel: Как задание в очереди может переместиться в fail_jobs при сбое? - PullRequest
0 голосов
/ 27 июня 2018

У меня есть работа в очереди, которая создает нового пользователя ...

<?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 для одновременной загрузки множества пользователей, для каждого из которых требуется запись в 2 таблицах плюс несколько записей в таблицах ролей и разрешений. Слишком медленно, чтобы делать синхронно.

У меня есть проверка в начале метода handle(), чтобы увидеть, не был ли еще создан пользователь с тем же адресом электронной почты (потому что потенциально несколько задач могут быть поставлены в очередь для создания пользователей с одним и тем же адресом электронной почты) и он выдает пользовательское исключение, если это так.

Если эта проверка не удалась, я никогда не хочу, чтобы работник очереди снова пытался выполнить эту работу, потому что я знаю, что она будет продолжать работать бесконечно, это пустая трата времени, чтобы повторить попытку еще раз. Как вручную принудительно завершить эту работу раз и навсегда перейти к таблице невыполненных работ?

P.S. Я нашел ответ SO о помощнике fail() и методе $this->markAsFailed(), но они по-прежнему не сразу переводят работу из заданий в failed_jobs.

1 Ответ

0 голосов
/ 27 июня 2018

Я полностью переписал свой ответ для вас. Прошлой ночью я спешил и подумал, что могу быстро решить вашу проблему, извините за дезинформацию.

Вы можете сделать что-то вроде приведенного ниже кода, это не поместит работу в таблицу невыполненных работ, но предотвратит повторные попытки. Я надеюсь, что это помогает.

<?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.');
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...