Атрибут backoff
Атрибут backoff класса Job определяет время задержки (в секундах) перед повторным выполнением задачи в случае возникновения ошибки. Он применяется совместно с атрибутом tries и позволяет управлять интервалами между попытками выполнения. Если атрибут не указан, повторные попытки будут выполняться с нулевой задержкой.
Атрибут можно задать в виде целого числа (фиксированная задержка), массива чисел (разные задержки для каждой попытки), либо в виде замыкания, возвращающего время задержки. При использовании массива количество элементов должно соответствовать количеству попыток.
Синтаксис
<?php
#[Backoff(10)] // фиксированная задержка 10 секунд
#[Backoff([5, 10, 30])] // разные задержки для трёх попыток
#[Backoff(function($attempt) {
return $attempt * 5; // задержка увеличивается с каждой попыткой
})]
?>
Пример
Давайте создадим задачу, которая при возникновении ошибки будет повторно выполняться с фиксированной задержкой в 10 секунд:
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessReportJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, SerializesModels;
public $tries = 5;
#[Backoff(10)]
public function handle()
{
$res = $this->processData();
if (!$res) {
throw new \Exception('Failed to process report');
}
echo "Report processed successfully";
}
private function processData()
{
return rand(0, 1) === 1;
}
}
?>
В этом примере задача будет повторяться до 5 раз с интервалом в 10 секунд между попытками.
Пример
Используем разные времена задержки для каждой попытки. Это полезно, когда ошибка может быть связана с временными проблемами, и нам нужно дать больше времени для их устранения:
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SendNotificationJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, SerializesModels;
public $tries = 4;
#[Backoff([5, 15, 30, 60])]
public function handle()
{
$res = $this->sendNotification();
if (!$res) {
throw new \Exception('Failed to send notification');
}
echo "Notification sent successfully";
}
private function sendNotification()
{
return rand(0, 1) === 1;
}
}
?>
В этом примере первая повторная попытка будет через 5 секунд, вторая - через 15, третья - через 30, четвертая - через 60 секунд.
Пример
Используем замыкание для динамического расчета времени задержки в зависимости от номера попытки:
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ImportDataJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, SerializesModels;
public $tries = 5;
#[Backoff(function($attempt) {
return $attempt * 5;
})]
public function handle()
{
$res = $this->importData();
if (!$res) {
throw new \Exception('Failed to import data');
}
echo "Data imported successfully";
}
private function importData()
{
return rand(0, 1) === 1;
}
}
?>
В этом примере задержка будет увеличиваться на 5 секунд с каждой попыткой: 5, 10, 15, 20, 25 секунд.