2014-07-31 3 views
6

Я стараюсь понять, как работают асинхронные ответы с Джерси. Я читаю главу 10 документации Джерси (https://jersey.java.net/documentation/latest/async.html), но это не помогает с моей проблемой. Также исследование здесь, в stackoverflow, не привело к удовлетворению ответов (что я могу понять).Джерси: немедленный ответ после асинхронного запроса

То, что я пытаюсь сделать, похоже на один вопрос в этом сообщении (Use http status 202 for asynchronous operations). Я хочу загрузить большой файл на сервер, используя документ HTML-формы. После отправки запроса на сервер веб-служба должна немедленно ответить со статусом 202 и URI, где файл можно найти после завершения запроса.

После прочтения сообщения abive это кажется возможным, но, к сожалению, нет намеков о том, как реализовать такое поведение, когда оно дано.

я написал небольшой веб-сервис для тестирования функциональности:

@Path("/test/async/") 
    public class TestAsyncResponse { 

     @GET 
     @Path("get") 
     public Response asyncGet(@Suspended final AsyncResponse response) { 

      new Thread(new Runnable() { 

       @Override 
       public void run() { 

        DateFormat df = new SimpleDateFormat("dd/MM/yy HH:mm:ss"); 

        System.out.println("#### thread started: " 
             + df.format(new Date()) + " ####"); 
        String result = veryExpensiveOperation(); 
        System.out.println("#### thread finished: " 
             + df.format(new Date()) + " ####"); 

        response.resume(result); 
       } 

       private String veryExpensiveOperation() { 

        try { 

         Thread.sleep(10000); 
        } 
        catch (InterruptedException e) { 

         e.printStackTrace(); 
        } 

        return "Woke up!"; 
       } 
      }).start(); 

      return Response.status(202).entity("Request accepted. " + 
             "Long running operation started") 
             .build(); 
     } 
    } 

Сервис работает, но в ответ я получаю «Проснулся Up!» сообщение после 10 секундного ожидания, а не ответ 202, который кажется логичным, потому что AsyncResponse - это тот, который обрабатывает ответ (как я его понимаю).

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

Итак, мои два вопроса: Я правильно понял и могу ли я использовать асинхронный ответ сервера для получения желаемого поведения?

Я попытался начать новую тему без AsyncResponse, и я получаю NullPointerException, потому что Джерси уже закрыл ответ и таким образом закрыл InputStream, который содержит данные файла. Это ожидаемое поведение? Этот пост (https://stackoverflow.com/a/17559684/1416602), похоже, указывает, что он может работать.

Любой отзыв приветствуется.

Привет

+1

Вы поняли это? – ksl

ответ

4

Ваш вопрос заключается в смешивании двух тем.

С точки зрения HTTP, 202 является технически завершенным запросом. И результат запроса - 202, сервер говорит вам, что он сделает это сбоку. Вам нужно будет сделать еще один HTTP-запрос, чтобы получить обновленный статус.

С точки зрения вашего приложения async означает, что вы выполните запрос в отдельном потоке (или другом асинхронном режиме). Но также это означает, что вы не вернете результат, даже не 202, пока не закончится другая «veryExpensiveOperation». Весь смысл прыгать через этот обруч - освободить вызывающий поток. Ваш веб-сервер имеет ограниченное число, например. 20, и если бы каждый из ваших запросов занял очень много времени, все 20 были бы висящими. Используя @Suspended, вы передаете исполнение из потока веб-сервера каким-либо другим способом (другой поток в вашем случае). Это действительно только первый шаг. Идея асинхронных серверов заключается в том, что даже veryExpensiveOperation реализуется в некотором асинхронном режиме, так что ожидание БД или файла не занимает целый поток.

Смежные вопросы