Ответ 1
Я предполагаю, что ваша система выглядит следующим образом. У вас есть служба REST, которая получает запросы от клиента. Он преобразует запросы в команды, которые может понять бизнес-логика. Вы помещаете эти команды в очередь. У вас есть один или несколько сотрудников, которые могут обрабатывать и удалять эти команды из очереди и отправлять результаты службе REST, которая может отвечать клиенту.
Ваша проблема, связанная с вашими длительными задачами, время ожидания подключения к клиенту, поэтому вы не можете отправить ответ. Так что вы можете отправить сообщение 202 после того, как вы поместите команды в очередь и добавьте ссылку для опроса, чтобы клиент мог опросить изменения. Ваши задачи имеют несколько подзадач, поэтому есть прогресс, а не только ожидающие и полные изменения состояния.
- Если вы хотите придерживаться опроса, вам следует создать новый ресурс REST, который содержит фактическое состояние и ход выполнения долгого задания. Это означает, что вам нужно сохранить эту информацию в базе данных, чтобы служба REST могла отвечать на запросы, такие как
GET/tasks/23461/status
. Это означает, что ваш рабочий должен обновить базу данных, когда она будет завершена подзадачей или всей задачей. - Если ваша служба REST работает как демон, вы можете уведомить ее о прогрессе, поэтому сохранение статуса задачи в базе данных не будет зависеть от работника. Этот вид службы REST также может хранить информацию в памяти.
- Если вы решили использовать веб-узлы для уведомления клиента, вы можете создать службу уведомлений. В REST вам нужно ответить идентификатором задачи. После этого вы отправляете этот идентификатор задачи в соединение с веб-сокетом, поэтому служба уведомлений будет знать, какое соединение с веб-узлом подписано на события определенной задачи. После этого вам не понадобится услуга REST, вы можете отправить прогресс через соединение с веб-сайтом, пока клиент не закрывает соединение.
- Вы можете объединить эти решения следующим образом. Вы разрешаете службе REST создавать ресурс задачи, чтобы вы могли получить доступ к прогрессу, используя ссылку для опроса. После этого вы отправляете обратно идентификатор с 202, который вы отправляете обратно через соединение с веб-соединениями. Таким образом, вы можете использовать службу уведомлений для уведомления клиента. По прогрессу ваш работник уведомит службу REST, которая создаст ссылку, такую как
GET/tasks/23461/status
и отправит эту ссылку клиенту через службу уведомлений. После этого клиент может использовать ссылку для обновления своего статуса.
Я думаю, что последнее - лучшее решение, если ваша служба REST работает как демон. Это связано с тем, что вы можете перенести ответственность уведомления на специализированную службу уведомлений, которая может использовать веб-сайты, опросы, SSE, что бы вы ни хотели. Он может разрушиться, не убивая службу REST, поэтому служба REST останется стабильной и быстрой. Если вы также отправите ссылку с обновлением вручную с помощью 202, тогда клиент может выполнить ручное обновление (при условии, что клиент, управляемый человеком), поэтому у вас будет что-то вроде грациозного ухудшения, если служба уведомления недоступна. Вам не нужно поддерживать службу уведомлений, потому что она ничего не знает о задачах, она просто отправит данные клиентам. Ваш работник не должен знать ничего о том, как отправлять уведомления и как создавать гиперссылки. Будет также легче поддерживать клиентский код, так как он будет почти чистым клиентом REST. Единственной дополнительной функцией будет подписка на уведомления, которая не меняется часто.