Laravel удалить задание, если оно не удалось - PullRequest
1 голос
/ 04 июля 2019

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

Вот как я справляюсь с ошибкой задания:

use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

public function handle()
{
    //infinite websocket listening loop
}

public function failed(Exception $exception)
{
    $this::dispatch()->onQueue('long-queue');
    $this->delete();
}

$this->delete() происходит от черты InteractsWithQueue.Что я делаю не так?

Редактировать: я использую горизонт для запуска заданий, вот конфигурация для пользовательской очереди, установленной в config/horizon.php

'supervisor-long' => [
    'connection' => 'redis-long',
    'queue' => ['long-queue'],
    'balance' => 'simple',
    'processes' => 3,
    'tries' => 1,
    'timeout' => 3600,
],

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

Ответы [ 2 ]

1 голос
/ 04 июля 2019

Причина, по которой произошел сбой, не выполняется, он срабатывает только тогда, когда задание превышает максимальное число попыток.Поток выглядит примерно так:

$job->dispatch(); // try 1
// times out
// retries on try 2 now
// times out
// retries on try 3 now
// max attempt is hit and MaxAttempt exception is thrown
// failed is called

Эта логика изменяется, если ваша работа действительно падает, этот пример только тогда, когда она выполняется бесконечно.Где логика обработана .

В определении вашей очереди в config / horizon.php вы можете определить попытки.

'my-short-queue' => [
    'connection' => 'redis',
    'queue' => ['my-short-queue'],
    'balance' => 'simple',
    'processes' => 1,
    'tries' => 1,
]
0 голосов
/ 05 июля 2019

Оказывается, что мои задания не терпели неудачу, поэтому метод failed() не выполнялся. Даже если вы попытаетесь установить значение tries => 1 в вашем файле config/horizon.php, вам нужно установить значение retry_after на 0 в вашем файле config/queue.php, чтобы задание не выполнялось сразу после истечения времени ожидания. Таким образом, ваши failed() методы вызываются немедленно. Ниже вы можете найти окончательные формы моих конфигурационных файлов.

config/queue.php:

'redis-long' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => 'long-queue',
    'retry_after' => 0,
    'block_for' => null,
],

config/horizon.php:

'supervisor-long' => [
    'connection' => 'redis-long',
    'queue' => ['long-queue'],
    'balance' => 'simple',
    'processes' => 1,
    'tries' => 1,
    'timeout' => 3600,
],
...