🛠️ Задача осталась в processing, а воркер давно упал. Причём здесь SKIP LOCKED?
Запрос очереди:
SELECT id FROM jobs WHERE status = 'pending' AND retry_at <= now() ORDER BY created_at, id FOR UPDATE SKIP LOCKED LIMIT 10;
SKIP LOCKED помогает воркерам не ждать строки, уже заблокированные другим потребителем.
Но он не отвечает на вопросы:
— жив ли воркер; — завершил ли он обработку; — нужно ли вернуть задачу; — безопасен ли повтор; — сколько попыток уже было.
Есть две разные модели.
Первая — держать транзакцию до конца обработки:
BEGIN → заблокировать задачу → выполнить работу → поставить done → COMMIT
Для короткой локальной операции это может быть допустимо. Для долгого HTTP-вызова — длинная транзакция и долгий row lock.
Вторая — быстро заявить задачу:
BEGIN → выбрать задачу → status = processing → worker_id, lease_until → COMMIT → выполнить работу
Транзакция короткая, но восстановление после падения воркера теперь должно делать приложение.
Поэтому нужны:
— worker_id; — lease_until; — attempt_count; — retry_at; — last_error.
Если lease истёк, задачу можно вернуть или отправить на разбор. Но нельзя автоматически возвращать все старые processing: долгие задачи могут ещё выполняться.
Важно: выбор и переход в processing должны быть атомарны. Если сначала сделать SELECT, завершить транзакцию, а потом отдельным UPDATE поставить processing, другой воркер может забрать ту же задачу.
ORDER BY created_at, id помогает с порядком среди доступных строк, но не гарантирует строгий FIFO при SKIP LOCKED: заблокированная старая задача может пропускаться.
Чек-лист:
— захват и processing в одной транзакции; — транзакция короткая; — есть lease и владелец; — done проверяет владельца; — retry ограничены; — повторная обработка безопасна; — старые pending и processing видны в мониторинге.
Вывод: SKIP LOCKED — это механизм конкурентного получения доступных строк, а не полноценная очередь. Надёжность строится вокруг lease, retry, владельца и правил восстановления.
Сохраните сценарий для проверки PostgreSQL-очередей, где несколько воркеров забирают задачи параллельно.
🔹🔹🔹🔹