Подписывайтесь на наш Telegram канал и будьте в курсе всех событий.

Александр Черняев

С ремеслом дружу
Александр Черняев

С ремеслом дружу

Давай по новой

Когда что-то не срабатывает с первого раза, что мы делаем? Правильно, пробуем снова. Вдруг на этот раз получится? Этот же подход хорошо работает и в разработке.

Мы можем повторять неудачные операции, чтобы восстановиться после временных ошибок или сбоев в сети. Laravel предоставляет “из коробки” набор отличных механизмов “повтора” для обработки временных сбоев!

Перечисленные методы ни как не помогут со сбоями вызванной неправильной бизнес-логикой, ошибками в коде, или неверными данными (.env). Независимо от того, сколько раз мы их повторяем, эти сбои не будут автоматически исправлены, пока мы не исправим код или конфигурацию.

Теперь давайте узнаем о механизмах “Повтора” в Laravel:

Транзакции базы данных

При выполнении транзакции базы данных может возникнуть взаимоблокировка. Это может произойти, когда транзакция не может завершиться из-за конфликта с другой параллельной транзакцией, пытающейся записать те же данные.

В методе DB::transaction можно просто передать второй параметр, чтобы указать, сколько раз он будет повторять транзакцию, если произойдет взаимоблокировка.

use Illuminate\Support\Facades\DB;

DB::transaction(function () {
    DB::update('update users set votes = 1');

    DB::delete('delete from posts');
}, 5);

Подробнее можно посмотреть в документации:

HTTP Вызов

Мы все знаем, что сторонние API или сервисы не всегда надежны! По этому должны построить наше приложение так, чтобы мы могли элегантно обрабатывать сбои этих сервисов.

Если мы используем HTTP Client, предоставленный Laravel, мы можем использовать метод retry, чтобы автоматически повторить вызов API, если он не был успешным.

$response = Http::retry(3, 100)->post(/* ... */);

Мы также можем передать второй параметр методу, чтобы указать, сколько времени Laravel должен подождать перед повторной попыткой.

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

Подробнее можно посмотреть в документации:

Очереди

При выполнении задания в очереди оно может не выполниться из-за какой-то ошибки. Если сбой вызван временными ошибками, хорошей идеей будет попытаться выполнить задание снова.

При запуске queue:work мы можем передать аргумент для указания максимального количества попыток выполнения задания, если оно не удалось.

php artisan queue:work --tries=3

А так же можем указать в каждом задании отдельно, сколько раз оно может быть повторено, и сколько времени оно должно ожидать перед повтороной попыткой:

namespace App\Jobs;

class ProcessPodcast implements ShouldQueue
{
    /**
     * Количество попыток выполнить задание.
     *
     * @var int
     */    
    public $tries = 5;

    /**
     * Количество секунд ожидания перед повторной попыткой задания.
     *
     * @var int
     */    
    public $backoff = 3;
}

Мы также можем определить метод tries, метод backoff или использовать подход на основе времени, определив метод retryUntil в классе задания.

Подробнее можно посмотреть в документации:

Даже после нескольких попыток выполнить задание некоторые из них могут остаться неудачными из-за ошибок, для исправления которых нужно внести изменения в код или конфигурацию. Laravel сохраняет такие неудавшиеся задания в специальной таблице базы данных failed_jobs, что бы после изменений мы могли повторно выполнить задания.

С помощью команды php artisan queue:retry мы можем повторно выполнить как одно, несколько или все задания.

Подробнее можно посмотреть в документации:

Универсальная функция

Laravel предоставляет отличный вспомогательную функцию под названием retry, который можно использовать для повтора любого участка кода. Это действительно полезно, когда мы хотим повторить какую-то логику с разными параметрами.

Вот простой пример для генерации уникального числа, которое еще не используется на основе некоторых критериев:

function getUniqueNumber()
{
    return retry(5, function () {
        $number = rand(1, 100);

        // 'isUsed' - вымышленный метод, который проверяет какую-то логику
        if (isUsed($number)) {
            throw new Exception('Число уже используется');
        }

        return $number;
    });
}

Подробнее можно посмотреть в документации:

Режим обслуживания

Хотя это не является частью механизма повтора, но заслуживает упоминания.

При запуске php artisan down мы также можем указать параметр retry, который будет установлен как значение заголовка HTTP Retry-After:

php artisan down --retry=60

Некоторые браузеры будут автоматически обновлять страницу с указанным интервалом, освобождая пользователя от необходимости постоянно нажимать “F5”.

Подробнее можно посмотреть в документации:

0
Александр Черняев

С ремеслом дружу

Статистика квеста

Кто сильнее и храбрее?

Хочу поделиться с вами интересной статистикой: Больше 173 часов было проведено в квесте “Раскрой секреты своего ремесла” как показывает Яндекс.Метрика.

У нас тут настоящие Шерлоки 😎 Но, до окончания осталось совсем чуть-чуть! Если кто-то до сих пор не успел, самое время завершить!

Но не расстраивайтесь если по какой либо причине загадки вам не близки, то мы уже занялись новым событием, которое потребует написания кода. 🤔 Как думаете, каким оно будет?

Изображение взято с новой страницы

2