У меня есть работа в очереди, которая создает нового пользователя ...
<?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.