Подход для REST-запроса с длительным временем выполнения? - PullRequest
8 голосов
/ 26 октября 2009

Мы создаем службу REST, выполнение которой займет около 5 минут. Внутренним приложением он будет вызываться только несколько раз в день. Существует ли проблема с использованием запроса REST (т. Е. HTTP), выполнение которого занимает 5 минут?

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

Ответы [ 4 ]

14 голосов
/ 27 октября 2009

Это один подход.

Создать новый запрос для выполнения ProcessXYZ

POST /ProcessXYZRequests

201-Created
Location: /ProcessXYZRequest/987

Если вы хотите увидеть текущий статус запроса:

GET /ProcessXYZRequest/987

<ProcessXYZRequest Id="987">
  <Status>In progress</Status>
  <Cancel method="DELETE" href="/ProcessXYZRequest/987"/>
</ProcessXYZRequest>

когда запрос закончится, вы увидите что-то вроде

GET /ProcessXYZRequest/987

<ProcessXYZRequest>
  <Status>Completed</Status>
  <Results href="/ProcessXYZRequest/Results"/>
</ProcessXYZRequest>

Используя этот подход, вы можете легко представить, что будут давать следующие запросы

GET  /ProcessXYZRequests/Pending
GET  /ProcessXYZRequests/Completed
GET  /ProcessXYZRequests/Failed
GET  /ProcessXYZRequests/Today
7 голосов
/ 14 октября 2010

Как отмечает Брайан Агнью, 5 минут вполне поддаются управлению, если они несколько бесполезны, если можно контролировать настройки тайм-аута. В противном случае должно быть сделано по крайней мере два запроса: первый, чтобы запустить процесс создания результатов, а второй (и третий, четвертый, и т. Д. , если для компиляции результата требуется больше времени, чем ожидалось), опрос за результат.

Брайан Агнью и Даррел Миллер оба предлагают аналогичные подходы для двух (+) - пошагового подхода: POST-запрос к конечной точке фабрики, запуск задания на сервере и позднее ПОЛУЧЕНИЕ результата из возвращенной конечной точки результата.

Хотя вышеизложенное является очень распространенным решением и действительно соответствует букве ограничений REST, оно очень сильно пахнет RPC. То есть вместо того, чтобы сказать «предоставьте мне представление этого ресурса », в нем говорится «запустите это задание » (RPC), а затем «предоставьте мне представление ресурса, который является результатом выполнения задания "(REST). РЕДАКТИРОВАТЬ: Я говорю очень свободно здесь. Чтобы быть ясным, ничего из этого явно не противоречит ограничениям REST , но это очень похоже на одевание подхода без RESTful в одежде REST, теряя его преимущества ( например кеширование , идемпотентность) в процессе.

Таким образом, я бы предпочел, чтобы, когда клиент впервые попытался получить ресурс, сервер ответил 202 «Принят» (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3),, возможно, «повторить попытку через 5 минут» где-то в ответе). После этого клиент может опросить той же конечной точки , чтобы ПОЛУЧИТЬ результат, если он доступен (в противном случае вернуть еще 202 и повторить попытку позже).

Некоторые дополнительные преимущества этого подхода состоят в том, что одноразовые ресурсы (такие как задания) не создаются излишне, две отдельные конечные точки не должны запрашиваться (фабрика и результат), и аналогично вторая конечная точка не должна быть определена из анализа Ответ от первого, таким образом, проще. Кроме того, результаты могут быть кэшированы «бесплатно» (по кодам). Установите время истечения срока действия кэша в заголовке результата в соответствии с тем, как долго результаты являются «действительными», в некотором смысле, для вашей проблемной области.

Хотелось бы, чтобы я назвал это учебным примером "ресурсно-ориентированного" подхода, но, возможно, по иронии судьбы, в главе 8 "RESTful Web Services" предлагается фабричный подход с двумя конечными точками. Пойди разберись.

5 голосов
/ 26 октября 2009

Предполагая, что вы можете настроить тайм-ауты HTTP, используя любую платформу, которую вы выберете, вы можете запросить через GET и просто зависнуть на 5 минут.

Однако может быть более гибким инициировать выполнение через POST, получить квитанцию ​​(номер / идентификатор и т. Д.), А затем выполнить GET, используя это через 5 минут (и, возможно, повторить попытку, если ваша процедура не займет ровно 5 минут каждый раз). Если запрос все еще выполняется, верните соответствующий код ошибки HTTP (возможно, 404, но что бы вы вернули для GET с несуществующей квитанцией?) Или верните результаты, если они доступны.

4 голосов
/ 26 октября 2009

Если вы контролируете оба конца , то вы можете делать все, что захотите. Например. браузеры, как правило, запускают HTTP-запросы с заголовками «закрытие соединения», поэтому у вас остается меньше вариантов; -)

Имейте в виду, что если между вами есть некоторые NAT / межсетевые экраны, у вас могут быть некоторые разрываемые соединения, если они какое-то время неактивны.

Могу ли я предложить зарегистрировать процедуру "обратного вызова"? Клиент выдает запрос с «конечной точкой обратного вызова» на сервер, получает «билет». Как только сервер завершает работу, он выполняет «обратный вызов» клиента ... или клиент может проверить состояние запроса через идентификатор билета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...