I am using Asynchronous Servlets to process requests,
According to Docs:(complete(),dispatch())
╔══════════════════╦═════════════════════════════════════
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.
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.
dispatch
and complete
?Calling complete
tells container to fire onComplete
listeners and stop the asynchronous mode, dispatch
basically tells container to call complete
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.
dispatch
inside run
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 to Response
object associated with the AsyncContext
.
dispatch
first and complete
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 to complete
will do nothing, maybe there will be a race condition between your thread and the container in calling handlers and manipulating internal structures of AsyncContext
implementation etc.
complete
what will happen to that method callDepends on what method you are calling. The specification states that dispatch
will throw IllegalStateException
if called after complete
, anything else is undefined and thus implementation specific.
run
should I call complete
inside callback()?Yes you have to call complete
to finish asynchronous processing once you are done. The run
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.
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?"
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: