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

Junior: питання на співбесіді з теми «Черги»

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

3 питання

Черга дозволяє відкласти повільну роботу: замість того щоб виконувати її під час запиту й тримати користувача, застосунок ставить завдання в чергу й одразу повертає відповідь. Окремий процес - воркер - виконує її згодом.

Створити завдання:

php artisan make:job SendWelcomeEmail
class SendWelcomeEmail implements ShouldQueue
{
    use Queueable;

    public function __construct(public User $user)
    {
    }

    public function handle(): void
    {
        Mail::to($this->user)->send(new WelcomeMail($this->user));
    }
}

Інтерфейс ShouldQueue - це і є те, що відправляє завдання в чергу, а не виконує одразу.

Поставити в чергу:

SendWelcomeEmail::dispatch($user);
SendWelcomeEmail::dispatch($user)->delay(now()->addMinutes(10));

Запустити воркер:

php artisan queue:work

Що варто виносити: надсилання листів і сповіщень, обробку зображень і відео, звернення до зовнішніх API, генерацію звітів та експорт, імпорт великих файлів - усе, що займає більше частки секунди й не потрібне для формування відповіді.

Що виносити не варто: те, результат чого користувач має побачити просто зараз. Черга - асинхронна, і відповідь її не дочекається.

Головна пастка новачка: у завдання передається модель, а Laravel серіалізує лише її ключ і перечитує запис у воркері. Якщо між постановкою й виконанням запис видалили, завдання впаде. Тому в чергу передають ідентифікатори або готові дані, а не громіздкі обʼєкти.

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

dispatch() ставить завдання в чергу: запит закінчується одразу, а роботу пізніше виконає воркер. dispatchSync() виконує handle() тут і зараз, у поточному процесі, черга не задіяна.

SendWelcomeEmail::dispatch($user);      // у чергу - відповідь не чекає листа
SendWelcomeEmail::dispatchSync($user);  // одразу - запит чекає, поки лист піде

Коли що:

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

Важливо: якщо клас не реалізує ShouldQueue, навіть dispatch() виконає його одразу. А в Laravel 13 є ще проміжний варіант - підключення deferred: завдання виконається в тому самому процесі, але після відправки відповіді користувачу, без воркера.

Докладніше в документації: Синхронна диспетчеризація

Найчастіше - бо ніхто їх не виконує. Черга лише зберігає завдання; виконує їх окремий процес-воркер:

php artisan queue:work

У свіжому застосунку Laravel підключення за замовчуванням - database (QUEUE_CONNECTION=database), тож завдання просто накопичуються в таблиці jobs, доки воркер не запущено.

Що ще перевірити:

  • Інша черга. Завдання з ->onQueue('emails') не візьме воркер, що слухає лише default: потрібен --queue=emails,default.
  • Інше підключення. Код пише в redis, а воркер слухає database.
  • Старий код. queue:work тримає застосунок у пам'яті й не бачить змін, доки його не перезапустити (php artisan queue:restart).

На сервері воркер має працювати постійно, тож його запускають під Supervisor чи systemd, які піднімуть процес після падіння. Для розробки є queue:listen: він повільніший, зате перечитує код на кожне завдання.

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