Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Senior Artisan

Як написати довгу команду, яку безпечно переривати й запускати знову?

Довгу команду переривають деплой, зупинка контейнера, OOM. Вона має завершуватися чисто й продовжувати, а не починати все з нуля чи дублювати роботу.

1. Реагувати на сигнал:

public function handle(): int
{
    $this->trap([SIGTERM, SIGINT], fn () => $this->shouldStop = true);

    Order::query()->where('synced', false)->lazyById(500)->each(function (Order $order) {
        if ($this->shouldStop) {
            return false;            // вийти після поточного запису
        }
        $this->sync($order);
        $order->update(['synced' => true]);
    });

    return self::SUCCESS;
}

2. Пам'ятати прогрес у даних, а не в пам'яті: позначка synced, останній оброблений id у таблиці чи кеші. Перезапуск продовжить з місця зупинки.

3. Ідемпотентність кроку: повторна обробка того самого запису не має шкодити - перевірка стану чи унікальний ключ.

4. Один екземпляр: Isolatable і --isolated або withoutOverlapping() у планувальнику.

5. Обходити дані порціями (lazyById, chunkById) - щоб пам'ять не росла, а зміни не зсували сторінки.

Альтернатива для дуже великих обсягів - команда лише розбиває роботу на завдання черги (батчі), а повтори й паралельність бере на себе черга.

Докладніше в документації: Обробка сигналів

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання