RESTful Назначение работы - PullRequest
0 голосов
/ 08 ноября 2010

У меня есть коллекция заданий, которые необходимо обработать, http://example.com/jobs. Каждое задание имеет статус «новый», «назначен» или «завершен».

Я хочу, чтобы подчиненные процессы выбирали одно «новое» задание, устанавливали его статус «назначено», а затем обрабатывали его. Я хочу убедиться, что каждое задание обрабатывается только одним ведомым.

Я подумал, чтобы каждый раб сделал следующее:

  1. GET http://example.com/jobs
  2. Выберите тот, который является "новым", и выполните HTTP PUT для http://example.com/jobs/123 {"status = назначено"}.
  3. Повторите

Проблема в том, что другой ведомый мог назначить себе задание между GET и PUT. Я мог бы заставить второй PUT возвращать 409 (конфликт), который будет сигнализировать второму ведомому, чтобы он попытался выполнить другую работу.

Я на правильном пути, или я должен сделать это по-другому?

Ответы [ 4 ]

1 голос
/ 08 ноября 2010

У меня был бы один процесс, который выбирает «новые» задания и назначает их.Другие процессы будут независимо входить и проверять, назначена ли им работа.У вас должен быть какой-то способ определить, какому процессу назначено задание, поэтому потребуется какой-то идентификатор подчиненного процесса.

0 голосов
/ 29 ноября 2010

Я был немного конкретен, на самом деле мне все равно, когда раб выбирает работу, просто он получает уникальную.

Учитывая это, я думаю, что @manuel aldana был на правильном пути, но я сделал несколько модификаций.

Я сохраню ресурс / jobs, но также предоставлю ресурс / jobs / назначенный. В обеих коллекциях может существовать одна работа.

Подчиненный может выполнять POST для / jobs / без параметров. Сервер выберет одно «новое» задание, переместит его в «назначенное» и вернет URL (/ jobs / назначенный / {jobid} или / jobs / {jobid}) в заголовке Location со статусом 201.

Когда ведомое устройство завершает работу, оно переводится в / jobs / {jobid} (статус = завершено).

0 голосов
/ 08 ноября 2010

Похоже, что статусы являются неотъемлемой частью вашей модели предметной области. Так что я бы выставил это как выделенные подресурсы


# 'idle' is what you called 'new'
GET /jobs/idle
GET /jobs/assigned

# start job
PUT /jobs/assigned/123

Ведомому разрешено собирать задания только на GET /jobs/idle. Это никогда не включает рабочие места, которые работают. Тем не менее могут быть условия гонки (два раба получают набор, прежде чем один из них приступил к работе). Я думаю, что 400 Bad Request или ваш упомянутый 409 Conflict в порядке с этим.

Я предпочитаю приведенную выше структуру ресурсов вместо работы с полезными нагрузками (что для меня часто выглядит "процедурно").

0 голосов
/ 08 ноября 2010

(Вы также можете использовать POST, поскольку то, что вы пытаетесь сделать, в любом случае не должно быть идемпотентным).

Вы можете присвоить каждому из ваших клиентов уникальный идентификатор (возможно, UUID) и иметь поле «работник / работник» в вашем ресурсе работы.

  1. GET http://example.com/jobs/
  2. POST {"worker" = $ myID} до http://example.com/jobs/123
  3. GET http://example.com/jobs/123 и убедитесь, что идентификатор работника совпадает с идентификатором клиента

Вы можете комбинировать это и с условными запросами.

Кроме того, у вас может быть функция тайм-аута, если очередь заданий не получает ответ от данного клиента, она помещает его обратно в очередь.

...