Через defer() - замикання виконається вже після того, як відповідь пішла користувачу.
public function store(StoreOrderRequest $request): RedirectResponse
{
$order = Order::create($request->validated());
defer(fn () => Metrics::reportOrder($order));
return redirect()->route('orders.show', $order);
}
Користувач не чекає на звернення до сервісу метрик, а окремий воркер черги не потрібен.
Як це працює: Laravel відправляє відповідь і закриває з'єднання, а процес PHP продовжує виконання. Для команд Artisan і завдань черги відкладені функції виконуються в кінці.
Деталі:
- якщо відповідь з помилкою (4xx/5xx), відкладена функція за замовчуванням не виконується;
->always()змінює це; defer(fn () => ..., 'name')з іменем дозволяє скасувати:defer()->forget('name');- у тестах їх можна виконувати одразу через
$this->withoutDefer().
Коли defer(), а коли черга:
defer- коротка, некритична робота: метрики, логування, прогрів кешу. Якщо процес упаде, вона просто не виконається, повторів немає;- черга - усе, що має гарантовано виконатися, довго триває чи потребує повторів: листи, платежі, обробка файлів.
Пам'ятайте, що поки працює відкладена функція, процес PHP зайнятий: важка робота тут з'їдає воркери, які мали б обслуговувати запити.