I am creating Executor in a web project so that the callable can do the work after the response has gone back to the web. Work that callable is doing behind the scene is not required for the current page but for one the pages that will follow.
As far as I know when then the response goes back to the web the servlet thread is free to process another request. In this case although the servlet thread created a executor service it should be available to process another incoming request as soon as the response is sent back even if the callables are active. Is my understanding correct?
If you are creating a new thread, which it sounds like you are, then you are correct. The thread handing the Servlet request goes back in the pool and is free to return results and take the next request.
Related
I am developing a spring 4 mvc application and I've got a database transaction that has to be done in the background.
It is triggered, when the URL /paramters_selected is called. The controller then starts an asynchronous task that is going to take a few minutes. For the time of processing the task, I return "processing" so that the controller method will render the /processing - JSP view. When the background task is finished, the "result" view should be rendered.
Is it possible, and if so how would it be done, to call /result when the background transaction has finished? Furthermore, is it possible to constantly update the "processing" view so that some kind of progress bar could be used?
Additonally, what kind of "technique" is best suited for this problem? I came across the terms of async-methods in spring, completable futures, deferredresult and listenablefuture.
Thank you in advance.
If you are using Async then i would suggest you not to wait for the result from server and better keep on either refreshing the status after some time or create callback which keeps on listening to response from server for Async Tasks.
If you use progress bar till Async task is completed, i suppose you mean just to show in UI and HTTP connection for that request is completed once the request is sent to Async task otherwise holding resource is not good as it will impact performance of the system and other tasks waiting for resource will eventually die due to unavailability of free resources.
So for Async task you can use any of the Java messaging queue, wherein your task will be pushing into JMS queue and Async task will keep of deque from JMS queue and once task is completed send response in form of notificaiton to originating task.
By using WebSocket you can implement this feature in a real time way.
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html
In context of Servlet request/response I read somewhere that:
Using a different thread to do work required by a request will, as you expect, allow the response to be sent immediately.
I am just wondering when a Servlet thread is handing over the actual processing to another thread then that means that it does not have the expected response with it at that point of time anyways, then what is the value in sending the immediate but meaningless response back to the browser?
Could someone please give me a valuable usecase for it.
That quote is talking about a scenario where you can return a meaningful response without actually finishing all the work required by the request. For instance you might upload a file to be processed and respond immediately with a processing ID, but pass the processing to another thread. Later on the client could make another request with that ID to find out if processing completed.
An asynchronous servlet scenario would hand off processing to another thread to do the work while blocking the request. But the blocked request would not tie up a servlet request thread during processing like a normal synchronous servlet request.
Suppose you had a single threaded processor and 10 requests were made at the same time. With a synchronous servlet that waited for the processing to finish, you'd have 10 blocked request threads + 1 processor thread. But with an asynchronous servlet, you'd have 0 blocked threads + 1 processor thread. That's a pretty significant gain.
I have been doing Java for a few years but I have not had much experience with Asynchronous programming.
I am working on an application that makes SOAP web service calls to some Synchronous web services and currently the implementation of my consuming application is Synchronous also ie. my applications threads block while waiting for the response.
I am trying to learn how to handle these SOAP calls in an asynchronous way - just for the hell of it but I have some high-level questions which I cant seem to find any answers to.
I am using CXF but my question is not specifically about CXF or SOAP, but higher-level, in terms of asynchronous application architecture I think.
What I want to know (working thru a scenario) - at a high level - is:
So I have a Thread (A) running in my JVM that makes a call to a remote web service
It registers a callback method and returns a Future
Thread (A) has done its bit and gets returned to its pool once it has returned the Future
The remote web service response returns and Thread (B) gets allocated and calls the callback method (which generally populates the Future with a result I believe)
Q1. I cant get my head off the blocking thread model - if Thread (A) is no longer listening to that network socket then how does the response that comes back from the remote service get allocated Thread (B) - is it simply treated as a new request coming into the server/container which then allocates a thread to service it?
Q2. Closely related to Q1 I imagine: if no Thread has the Future, or handler (with its callback method) on its stack, then how does the response from the remote web service get associated with the callback method it needs to call?
Or, in another way of asking, how does Thread B (now dealing with the response) get given a reference to the Future/Callback object?
Very sorry my question is so long - and thanks to anyone who gave their time to read through it! :)
I don't see why you'd add all this complexity using asynchronous Threading.
The way to design an asynchronous soap service:
You have one service sending out a response to a given client / clients.
Those clients work on the response given asynchronously.
When done, they would call another soap method to return their response.
The response will just be stored in a queue (e.g. a database table), without any extra logic. You'd have a "Worker" Service working on the incoming tasks. If a response is needed again another method on the other remote service would be called. The requests I would store as events in the database, which would later be asynchronously handled by an EventHandler. See
Hexagonal Architecture:
https://www.youtube.com/watch?v=fGaJHEgonKg
Your Q1 and Q2 seem to have more to do with multithreading than they have to do with asynchronous calls.
The magic of asynchronous web service calls is that you don't have to worry about multithreading to handle blocking while waiting for a response.
It's a bit unclear from the question what the specific problem statement is (i.e., what you are hoping to have your application do while blocking or rather than blocking), but here are a couple ways that you could use asynchronous web service calls that will allow you to do other work.
For the following cases, assume that the dispatch() method calls Dispatch.invokeAsync(T msg, AsyncHandler handler) and returns a Future:
1) Dispatch multiple web service requests, so that they run in parallel:
If you have multiple services to consume and they can all execute independently, dispatch them all at once and process the responses when you have received them all.
ArrayList<Future<?>> futures = new ArrayList<Future<?>>();
futures.add(serviceToConsume1.dispatch());
futures.add(serviceToConsume2.dispatch());
futures.add(serviceToConsume3.dispatch());
// now wait until all services return
for(Future f<?> : futures) {
f.get();
}
// now use responses to continue processing
2) Polling:
Future<?> f = serviceToConsume.dispatch();
while(!f.isDone()) {
// do other work here
}
// now use response to continue processing
We are writing some REST services using Jersey. Our service make some underlying service calls which happens to be dead slow, which results in holding each thread per request for 3-4 seconds. While investigating I came across Asynchronous Pages in .Net which assigns a thread to each request from thread pool and returns the thread to thread pool once I/O operation starts and gets a new thread when I/O operation is finished to do rest of the processing.
Is there anything similar to this exists in Jersey, where we can serve more concurrent connections instead of holding one thread for each connection until it completes. I don't want to POST a request, return a GUID and then keep polling for the status of the request from client, since I don't control client code.
Thanks,
GG
Take a look at the Atmosphere's Framework, specifically the atmosphere-jersey module that brings asynchronous annotation to Jersey.
Take a look at one of the samples, or read this quick tutorial. Atmosphere's Jersey does exactly what you are looking at, without requiring you to manipulate threads or anything like that. Come to our mailing list in case you need more help.
(I am the Atmosphere Creator and Lead)
I am working on a servlet that can take a few hours to complete the request. However, the client calling the servlet is only interested in knowing whether the request has been received by the servlet or not. The client doesn't want to wait hours before it gets any kind of response from the servlet. Also since calling the servlet is a blocking call, the client cannot proceed until it receives the response from the servlet.
To avoid this, I am thinking of actually launching a new thread in the servlet code. The thread launched by the servlet will do the time consuming processing allowing the servlet to return a response to the client very quickly. But I am not sure if this an acceptable way of working around the blocking nature of servlet calls. I have looked into NIO but it seems like it is not something that is guaranteed to work in any servlet container as the servlet container has be NIO based also.
What you need is a job scheduler because they give assurance that a job will be finished, even in case a server is restarted.
Take a look at java OSS job schedulers, most notably Quartz.
Your solution is correct, but creating threads in enterprise applications is considered a bad practice. Better use a thread pool or JMS queue.
You have to take into account what should happen server goes down during processing, how to react when multiple requests (think: hundreds or even thousands) occur at the same time, etc. So you have chosen the right direction, but it is a bit more complicated.
A thread isn't bad but I recommend throwing this off to an executor pool as a task. Better yet a long running work manager. It's not a bad practice to return quickly like you plan. I would recommend providing some sort of user feedback indicating where the user can find information about the long running job. So:
Create a job representing the work task with a unique ID
Send the job to your background handler object (that contains an executor)
Build a url for the unique job id.
Return a page describing where they can get the result
The page with the result will have to coordinate with this background job manager. While it's computing you can have this page describe the progress. When its done the page can display the results of the long running job.