Реализация рабочей очереди в postresql - PullRequest
0 голосов
/ 01 июня 2018

Я хочу сделать постоянную очередь заданий в postgresql.Чтобы несколько работников могли выбрать одно задание из очереди (используя select for update с skip locked), обработать его и затем удалить из очереди.У меня есть таблица:

create table queue (
   id serial primary key
   some_job_param1 text not null
   some_job_param2 text not null
)

Теперь, если есть две работы, то она работает нормально:

worker1 начинает транзакцию и выбирает первую работу

begin;
select * from queue for update skip locked limit 1;

начинает обработку.worker2 делает то же самое и выбирает второе задание с тем же запросом.

После того, как worker1 выполнит свою работу, удалит ее из очереди и подтвердит транзакцию:

delete from queue where id=$1;
commit;

Тогда worker1 готов к новой работе, поэтому он делает то же самое.Начинает новую транзакцию, выбирает для работы, которая не заблокирована.Но проблема в том, что больше нет заданий, запрос возвращает ноль строк.

Идеально было бы, если бы запрос блокировался до тех пор, пока не появится новое задание, и он вернет результат.Это как-то возможно?Или я иду в неправильном направлении?

РЕДАКТИРОВАТЬ:

рабочие являются внешним процессом.Таким образом, если работник умер, сеанс умирает, и транзакция также.Тогда выбранная работа больше не будет заблокирована и готова для другого работника.Псевдокод будет выглядеть так:

while (true) {
  tx = db.new_transaction()
  job_id, param1, param2 = tx.query("select * from queue for update skip locked limit 1")
  try {
    some_long_processing(param1, param2)
    tx.commit()
  } catch {
    tx.rollback()
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...