I am using Asynchronous Servlets to process requests,
According to Docs:(complete(),dispatch())
╔══════════════════╦═══════════════════════════════════════════════════════════╗
║ void complete() ║ Completes the asynchronous operation and closes the ║
║ ║ response associated with this asynchronous context. ║
║ ║ You call this method after writing to the response object ║
║ ║ inside the asynchronous context. ║
╠══════════════════╬═══════════════════════════════════════════════════════════╣
║ void dispatch() ║ Dispatches the request and response objects ║
║ ║ of this AsyncContext to the servlet container. ║
╚══════════════════╩═══════════════════════════════════════════════════════════╝
I failed to understand async.dispatch(), async.complete(), and how they work.
I have few doubts on this:
- What exactly the difference between
async.dispatch()
andasync.complete()
? - When I called dispatch()(inside run()) the response reaches the client, that mean we can push the response asynchronously?
- if I call
asyncContext.dispatch()
first andasyncContext.complete()
next what is the behaviour of the thread? - If I call any method after
asyncContext.complete()
, what will happen to that method call, as shown below code(in the samerun()
)?
[when I tested this it's working fine and showing same thread id] - If I am calling Asynchronous methods inside
run()
should I need to completeasyncContext.complete()
inside callback()? (onSuccess() or onFailure()) Whether any help(example source/books/online help) available regarding this? (Async Servlets and Futures Combination)
final FutureCallback<Void> calculateTime= new CustomFuture<>(calculate); // start Async context. final AsyncContext asyncContext = request.startAsync(); asyncContext.start(new Runnable() { @Override public void run() { MyObject object= null; try { object= myFactory.create(); //dispatch async context asyncContext.dispatch("Object Successfully Created"); } catch (final IOException e1) { logger.error("logging error"); } asyncContext.complete(); //complete async context // call asynchronous method final ListenableFuture<Void> future = myService.doSomething(); Futures.addCallback(future, calculateTime); // calling asyncContext.complete() here will work? } });
Thanks in Advance.
From the horse's mouth (Oracle Javadoc)
complete()
Completes the asynchronous operation that was started on the request that was used to initialze this AsyncContext, closing the response that was used to initialize this AsyncContext.
Any listeners of type AsyncListener that were registered with the ServletRequest for which this AsyncContext was created will be invoked at their onComplete method.
dispatch(String path)
Dispatches the request and response objects of this AsyncContext to the given path.
...
Control over the request and response is delegated to the dispatch target, and the response will be closed when the dispatch target has completed execution, unless ServletRequest#startAsync() or ServletRequest#startAsync(ServletRequest, ServletResponse) are called.
Q/A
what's the difference between
dispatch
andcomplete
?Calling
complete
tells container to fireonComplete
listeners and stop the asynchronous mode,dispatch
basically tells container to callcomplete
and then forward the request (internally) to the specified path. The path can be a JSP, a synchronous servlet or even another asynchronous servlet that will trigger a new round of async processing.When I called
dispatch
insiderun
the response reached the client, does that mean we can push the response asynchronously like this?On the contrary
dispatch
closes the asynchrnonous mode and forwards the request to another servlet or JSP. To push data to the client you have to write toResponse
object associated with theAsyncContext
.if I call
dispatch
first andcomplete
next what is the behaviour of the thread ?Undefined, which is a nice way of saying it depends on how the container is implemented. Maybe it will throw an error, maybe
onComplete
handlers will be fired twice, maybe call tocomplete
will do nothing, maybe there will be a race condition between your thread and the container in calling handlers and manipulating internal structures ofAsyncContext
implementation etc.If I call any method after
complete
what will happen to that method callDepends on what method you are calling. The specification states that
dispatch
will throwIllegalStateException
if called aftercomplete
, anything else is undefined and thus implementation specific.If I am calling asynchronous methods inside
run
should I callcomplete
inside callback()?Yes you have to call
complete
to finish asynchronous processing once you are done. Therun
method is used to schedule a task to be executed by a container managed thread pool and it can be called multiple times during the lifetime of an asynchronous request.Are there any examples of using Async Servlets and Futures Combination?
I am not aware of any, but there are a few good examples of using async servlets linked in "See also" section. In principle I don't see much value in using futures. See: "Is async servlet a good fit for what I am doing?"
Is async servlet a good fit for what I am doing ?
The objective of an async servlet is to reduce the number of threads required to serve certain types of "push clients": HTTP request is left open until an (usually external) event occurs and then the server will push data down the channel. In a standard servlet environment each client will have a dedicated thread allocated and waiting thus consuming valuable system resources. In asynchronous mode the client connection can be put "on hold" and detached from an execution thread until an event comes in which makes it possible to do something with it. Think about an online chat application as an example. All connected clients will be idle until someone posts a message to the room. It is wasteful to keep a dedicated thread for every connected user.
If your application needs to call multiple services at the same time and you wish to use futures and executors to parallelize that operation then an asynchronous servlet is probably not a good fit: You will gain nothing and a standard servlet will be much easier to implement. On the other hand if service calls can be made in an asynchronous (non-blocking) way, without relying on threaded executors, then it's another story.
The "right" question to ask is: Do I want to have fewer threads than active connections?
See also:
AsyncStateMachine
javadoc (Tomcat implementation).