I'm trying to set up a servlet that I can use to call webservices asynchronously. For the most part, it is working fine. I have a servlet with a doGet method and a js that calls it. I have a callback method in the js that the servlet correctly calls when it has finished doing its thing.
The complication is that one of the web services I am calling is also asynchronous, and I would like to be able to essentially call the js callback method a second time after the asynchronous ws callback has finished. For example, if you have a status field, when you call the synchronous web service, it immediately updates to "Beginning Synchronous Call" and then when the servlet callback arrives it changes to the callback value, which is the result of the web service.
When you call the asynchronous web service, the update field immediately updates to "Beginning Asynchronous Call", and shortly receives the first callback from the servlet indicating that the web service has been requested, so we update the field to "Processing Web Service" or whatever. The problem is that once the web service finishes and calls back to the servlet, I can't seem to figure out how to send the result to the js callback method.
I'm pretty new at AJAX and servlets, so maybe this is a horrible way to accomplish what I want.
The web services are both being called in the Servlet, mostly using Netbeans auto-generated WS calls. The WS calls themselves work fine, but once I get the result of the asynchronous WS, I am stuck inside of the handleResponse method of the webservice callback and no longer have any reference to the response element for the document I want to update.
I tried to store the original response variable as a static member variable and use it in the handleResponse method like so:
javax.xml.ws.AsyncHandler<WsClients.Op11Response> asyncHandler = new javax.xml.ws.AsyncHandler<WsClients.Op11Response>() {
public void handleResponse(javax.xml.ws.Response<WsClients.Op11Response> asyncResponse) {
try {
storedResponse.setContentType("text/xml");
String returnString = asyncResponse.get().getReturn();
storedResponse.getWriter().write("<returnData><content>"
+ returnString + "</content></returnData>");
} catch (Exception ex) {
}
}
};
This will not compile with a debugger attached and does not seem to be able to assign a reference anyway.
Is there a better way to do this?
The nature of HTTP is that you cannot send anything back to the client unless client requested this information either by polling or by keeping the connection open.
The operation to start the asynchronous call ends immediately and you need to return from the servlet doGet method (while technically you can stay in the servlet call until your async call finishes I wouldn't recommend that as it ties up the server resources. It is generally a good practice to return from the servlet as soon as you can).
The best course of action would be:
Have internal data structure (e.g. HashMap with appropriate synchronization) to hold the asynchronous calls that are executing.
When you start a new call, assign it pseudo-random key and return it from the initial call.
Using the above key, have browser-side javascript AJAX calls periodically poll the status of the call and display the results.
Do not forget to clean up finished or stale calls (for example by running a timer thread).
When you comfortable with the polling implementation in step 3 above, you may want to consider Comet, a.k.a. long poll to replace client-side polling.
Servlet cannot send response again. HTTP protocol is synchronous, and only client can initiate a request-response exchange.
For async updates you need to perform polling from the client side to the server side, and accumulate messages on the server side (in the sessions) until client picks them up or they expire.
Related
I am analyzing some jersey 2.0 code and i have a question on how the following method works:
#Stateless
#Path("/mycoolstuff")
public class MyEjbResource {
…
#GET
#Asynchronous //does this mean the method executes on child thread ?
public void longRunningOperation(#Suspended AsyncResponse ar) {
final String result = executeLongRunningOperation();
ar.resume(result);
}
private String executeLongRunningOperation() { … }
}
Lets say im at a web browser and i type in www.mysite/mycoolstuff
this will execute the method but im not understanding what the asyncResponse is used for neither the #Asynchronous annotation. From the browser how would i notice its asychnronous ? what would be the difference in removing the annotation ? Also the suspended annotation after reading the documentation i'm not clear its purpose.
is the #Asynchronous annotation simply telling the program to execute this method on a new thread ? is it a convenience method for doing "new Thread(.....)" ?
Update: this annotation relieves the server of hanging onto the request processing thread. Throughput can be better. Anyway from the official docs:
Request processing on the server works by default in a synchronous processing mode, which means that a client connection of a request is processed in a single I/O container thread. Once the thread processing the request returns to the I/O container, the container can safely assume that the request processing is finished and that the client connection can be safely released including all the resources associated with the connection. This model is typically sufficient for processing of requests for which the processing resource method execution takes a relatively short time. However, in cases where a resource method execution is known to take a long time to compute the result, server-side asynchronous processing model should be used. In this model, the association between a request processing thread and client connection is broken. I/O container that handles incoming request may no longer assume that a client connection can be safely closed when a request processing thread returns. Instead a facility for explicitly suspending, resuming and closing client connections needs to be exposed. Note that the use of server-side asynchronous processing model will not improve the request processing time perceived by the client. It will however increase the throughput of the server, by releasing the initial request processing thread back to the I/O container while the request may still be waiting in a queue for processing or the processing may still be running on another dedicated thread. The released I/O container thread can be used to accept and process new incoming request connections.
#Suspended have more definite if you used it, else it will not make any difference of using it.
Let's talk about benefits of it:
#Suspended will pause/Suspend the current thread until it gets response,by default #NO_TIMEOUT no suspend timeout set. So it doesn't mean your request response (I/O)thread will get free and be available for other request.
Now Assume you want your service to be a response with some specific time, but the method you are calling from resource not guarantee the response time, then how will you manage your service response time? At that time, you can set suspend timeout for your service using #Suspended, and even provide a fall back response when time get exceed.
Below is some sample of code for setting suspend/pause timeout
public void longRunningOperation(#Suspended AsyncResponse ar) {
ar.setTimeoutHandler(customHandler);
ar.setTimeout(10, TimeUnit.SECONDS);
final String result = executeLongRunningOperation();
ar.resume(result);
}
for more details refer this
The #Suspended annotation is added before an AsyncResponse parameter on the resource method to tell the underlying web server not to expect this thread to return a response for the remote caller:
#POST
public void asyncPost(#Suspended final AsyncResponse ar, ... <args>) {
someAsyncMethodInYourServer(<args>, new AsyncMethodCallback() {
#Override
void completed(<results>) {
ar.complete(Response.ok(<results>).build());
}
#Override
void failed(Throwable t) {
ar.failed(t);
}
}
}
Rather, the AsyncResponse object is used by the thread that calls completed or failed on the callback object to return an 'ok' or throw an error to the client.
Consider using such asynchronous resources in conjunction with an async jersey client. If you're trying to implement a ReST service that exposes a fundamentally async api, these patterns allow you to project the async api through the ReST interface.
We don't create async interfaces because we have a process that takes a long time (minutes or hours) to run, but rather because we don't want our threads to ever sleep - we send the request and register a callback handler to be called later when the result is ready - from milliseconds to seconds later - in a synchronous interface, the calling thread would be sleeping during that time, rather than doing something useful. One of the fastest web servers ever written is single threaded and completely asynchronous. That thread never sleeps, and because there is only one thread, there's no context switching going on under the covers (at least within that process).
The #suspend annotation makes the caller actually wait until your done work. Lets say you have a lot of work to do on another thread. when you use jersey #suspend the caller just sits there and waits (so on a web browser they just see a spinner) until your AsyncResponse object returns data to it.
Imagine you had a really long operation you had to do and you want to do it on another thread (or multiple threads). Now we can have the user wait until we are done. Don't forget in jersey you'll need to add the " true" right in the jersey servlet definition in web.xml to get it to work.
I am new to Java Spring Framework, I am Rails developer I have requirement in java spring like I need to do background jobs but after the response send to the end User. It should not wait for the jobs to complete. But the jobs should run every time action completes.
Is a webservice app. We have Service, Bo and DAO layers and we are logging any exceptions occurred while processing the user data in database before response send to user, but now we want to move(Exception handling) after response send to user to increase the performance.
I remember in rails we have callbacks/filters after the action executed it calls the methods we want to executed. Same is available in java Spring?
Thanks,
Senthil
I assume the use case is something like a user requests a long-running task, and you want to return a response immediately and then launch the task in the background.
Spring can help with this. See
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/scheduling.html
In particular see the #Async annotation.
With respect to the client getting a response back following the async processing (exception or otherwise), you can do it, but it's extra work.
Normally the immediate response would include some kind of ID that the client could come back with after some period of time. (For example, when you run a search against the Splunk API, it gives you a job ID, and you come back later with that job ID to check on the result). If this works, do that. The client has to poll but the implementation is the simplest.
If not, then you have to have some way for the client to listen for the response. This could be a "reply-to" web service endpoint on the client (perhaps passed in with the original request as a custom X-Reply-To HTTP header), or it could be a message queue, etc.
I'm getting confused a bit when it comes to Synchronous calls, and Asynchronous calls in GWT.
I am sure that GWT is makes Async calls.
It's clear to me that Synchronous is just waiting for the response, and after getting that response, executing the next command.
It is not in the case of Asynchronous, because it never waits for the response. Before getting the response it executes the next command right away.
But I can see in some blogs is says that RPC is Synchronous.....
Whereas GWT which uses RPC is not Synchronous. I understand that whenever I send the request it never waits.
Is RPC really synchronous?
If so how does GWT make Async RPCs?
or did I misunderstand anything?
GWT RPC(Remote Procedure Calls) is Asnyc for sure. Actually, All of implementations which are based on AJAX are all Asnyc.
Let's take a look on the example below:
emailService.emptyMyInbox(fUsername, fPassword, new AsyncCallback() {
public void onSuccess(Void result) {
// do some UI stuff to show success
}
public void onFailure(Throwable caught) {
// do some UI stuff to show failure
}
};
// do something more
We call the service on first line, right after the execution, the browser will execute the line // do something more, regardless of if the result returned or not.
For more information, see Dev Guide Server Communication
On Google App Engine (GAE) it is possible for frontend instances to create up to 10 threads to maximize throughput. According to this page, such multi-threading can be accomplished as follows:
Runnable myTask = new Runnable({
#Override
public void run() {
// Do whatever
}
});
ThreadFactory threadFactory = ThreadManager.currentRequestThreadFactory();
// GAE caps frontend instances to 10 worker threads per instance.
threadFactory.newRequestThread(myTask);
To hit my GAE server-side, I'll expose many servlets mapped to certain URLs, such as the FizzServlet mapped to http://myapp.com/fizz:
public class FizzServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// Handle the request here. Somehow send it to an available
// worker thread.
}
}
I guess I'm choking on how to connect these two ideas. As far as I see it, you have 3 different mechanisms/items here:
The App Engine instance itself, whose lifecycle I can "hook" by implementing a ServletContextListener and run custom code when GAE fires up the instance; and
This ThreadFactory/ThreadManager stuff (above)
The servlets/listeners
I guess I'm wondering how to implement code such that every time a new request comes into, say, FizzServlet#doGet, how to make sure that request gets sent to an available thread (if there is one available). That way, if FizzServlet was the only servlet I was exposing, it could get called up to 10 times before it would cause a new (11th) incoming request to hang while a previous request was processing.
I'm looking for the glue code between the servlet and this thread-creating code. Thanks in advance.
I guess I'm wondering how to implement code such that every time a new request comes into, say, FizzServlet#doGet, how to make sure that request gets sent to an available thread (if there is one available). That way, if FizzServlet was the only servlet I was exposing, it could get called up to 10 times before it would cause a new (11th) incoming request to hang while a previous request was processing.
That's what the GAE servlet engine does for you. You deploy an app containing a servlet, and when a request comes in, the servlet engine uses a thread to process the request and calls your servlet. You don't have anything to do.
If your servlet's doGet() or doPost() method, invoked by GAE, needs to perform several tasks in parallel (like contacting several other web sites for example), then you'll start threads by yourself as explained in the page you linked to.
HTTP controller (Spring) gets a requests and making a blocking call. Once the blocking call is over the controls get back to the controller.
At this point I don't want to send a response back to the client but rather wait for another event(e.g., completion of some processing) to happen. As soon as that event happens I need a way to collect the data from the event and then return the HTTP response with this data.
HTTPController doSomething( HTTPRequest )
{
makeBlockingCall();
waitForEventToHappen();
collectDataFromEvent();
return HTTPResponse();
}
You wouldn't do that from within one request, because that would probably time out eventually and until then wouldn't provide feedback to the customer that something is happening.
Instead, you would immediately show a page that asynchronously (probably per AJAX) polls the server to see whether the result is already available.
So the first request will return an id that will be used in the second (AJAX) request to lookup the result.