Jersey: immediate response after an asynchronous request

I am trying to understand how asynchronous responses work with Jersey. I read chapter 10 of the Jersey documentation ( https://jersey.java.net/documentation/latest/async.html ), but that does not help with my problem. Also, the study here on stackoverflow did not lead to satisfying answers (which I can understand).

What I'm trying to do seems to be one question in this post ( Use HTTP status 202 for asynchronous operations ). I want to upload a large file to the server using an HTML form document. After sending a request to the server, the web service should immediately respond with the status 202 and URI, where the file can be found after the request is completed.

After reading post abive, this seems possible, but unfortunately there is no hint about how to implement this behavior when it is given.

I wrote a small web service to test the functionality:

@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(); } } 

The service works, but in response I get the message "Woke Up!". message after 10 seconds of waiting, not 202 response, which seems logical, because AsyncResponse is the one that processes the response (as I understand it).

After reading the documentation, I got the impression that this should happen, because all that Jersey does with the asynchronous server response is to transfer the thread from the response pool to another to free up processing time for additional answers to this service .

So, my two questions: I understood correctly and can I use the response of an asynchronous server to get the desired behavior?

I tried to start a new stream without AsyncResponse , and I got a NullPointerException because Jersey already closed the response and thus closed the InputStream that contains the file data. Is this expected behavior? This post ( https://stackoverflow.com/a/167269/ ) indicates that it can work.

Any answer is welcome.

Hello

+6
source share
1 answer

There are two topics mixed in your question.

From an HTTP perspective, 202 is a technically complete request. And the result of the request is 202, the server tells you that it will do it from the side. You will need to make another HTTP request to get the updated status.

From the point of view of your application, async means that you will execute the request in a separate thread (or other asynchronous path). But also this means that you will not return the result, not even 202, until another "veryExpensiveOperation" ends. The whole point of jumping through this hoop is to free the calling stream. Your web server has a limited number, for example. 20, and if each of your queries took a very long time, all 20 would be hanging. Using @Suspended, you transfer execution from the web server thread in some other way (another thread in your case). This is really just the first step. The idea of โ€‹โ€‹asynchronous servers is that even veryExpensiveOperation is implemented in some asynchronous mode, so waiting for a database or file does not take up a whole stream.

+4
source

Source: https://habr.com/ru/post/973174/


All Articles