🛠️ Задача осталась в 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-очередей, где несколько воркеров забирают задачи параллельно.

🔹🔹🔹🔹

🛠️ Задача осталась в processing, а воркер давно упал | Сетка — социальная сеть от hh.ru