Version: 9.4.5.v20170502 |
private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services for sponsored feature development
Asynchronous servlets were originally introduced with Jetty 6 Continuations, which were a Jetty specific mechanism. From Jetty 7 onwards, the Continuations API has been extended to be a general purpose API that will work asynchronously on any servlet-3.0 container, as well as on Jetty 6, 7, or 8. Continuations will also work in blocking mode with any servlet 2.5 container.
The ContinuationSupport factory class can be used to obtain a continuation instance associated with a request:
Continuation continuation = ContinuationSupport.getContinuation(request);
To suspend a request, the suspend method can be called on the continuation:
void doGet(HttpServletRequest request, HttpServletResponse response)
{
...
// optionally:
// continuation.setTimeout(long);
continuation.suspend();
...
}
The lifecycle of the request will be extended beyond the return to the container from the Servlet.service(...)
method and Filter.doFilter(...)
calls. When these dispatch methods return, the suspended request will not yet be committed and a response will not yet be sent to the HTTP client.
Once the request has been suspended, the continuation should be registered with an asynchronous service so that it may be used by an asynchronous callback when the waited-for event happens.
The request will be suspended until either continuation.resume()
or continuation.complete()
is called. If neither is called then the continuation will timeout.
The timeout should be set before the suspend, by a call to continuation.setTimeout(long)
if no timeout is set, then the default period is used.
If no timeout listeners resume or complete the continuation, then the continuation is resumed with continuation.isExpired()
true.
Suspension is analogous to the servlet 3.0 request.startAsync()
method. Unlike jetty 6 continuations, an exception is not thrown by suspend and the method should return normally.
This allows the registration of the continuation to occur after suspension and avoids the need for a mutex.
If an exception is desirable (to bypass code that is unaware of continuations and may try to commit the response), then continuation.undispatch()
may be called to exit the current thread from the current dispatch by throwing a ContinuationThrowable
.
Once an asynchronous event has occurred, the continuation can be resumed:
void myAsyncCallback(Object results)
{
continuation.setAttribute("results",results);
continuation.resume();
}
When a continuation is resumed, the request is re-dispatched to the servlet container, almost as if the request had been received again.
However during the re-dispatch, the continuation.isInitial()
method returns false and any attributes set by the asynchronous handler are available.
Continuation resume is analogous to Servlet 3.0 AsyncContext.dispatch()
.
As an alternative to resuming a request, an asynchronous handler may write the response itself. After writing the response, the handler must indicate the request handling is complete by calling the complete method:
void myAsyncCallback(Object results)
{
writeResults(continuation.getServletResponse(),results);
continuation.complete();
}
After complete is called, the container schedules the response to be committed and flushed. Continuation complete is analogous to Servlet 3.0 AsyncContext.complete()
.
An application may monitor the status of a continuation by using a ContinuationListener:
void doGet(HttpServletRequest request, HttpServletResponse response)
{
...
Continuation continuation = ContinuationSupport.getContinuation(request);
continuation.addContinuationListener(new ContinuationListener()
{
public void onTimeout(Continuation continuation) { ... }
public void onComplete(Continuation continuation) { ... }
});
continuation.suspend();
...
}
Continuation listeners are analogous to Servlet 3.0 AsyncListeners.