org.eclipse.jetty.server
Class AsyncContinuation

java.lang.Object
  extended by org.eclipse.jetty.server.AsyncContinuation
All Implemented Interfaces:
AsyncContext, Continuation

public class AsyncContinuation
extends java.lang.Object
implements AsyncContext, Continuation

Implementation of Continuation and AsyncContext interfaces


Nested Class Summary
 class AsyncContinuation.AsyncEventState
           
 class AsyncContinuation.AsyncTimeout
           
 
Field Summary
protected  HttpConnection _connection
           
 
Fields inherited from interface javax.servlet.AsyncContext
ASYNC_CONTEXT_PATH, ASYNC_PATH_INFO, ASYNC_QUERY_STRING, ASYNC_REQUEST_URI, ASYNC_SERVLET_PATH
 
Fields inherited from interface org.eclipse.jetty.continuation.Continuation
ATTRIBUTE
 
Constructor Summary
protected AsyncContinuation()
           
 
Method Summary
 void addContinuationListener(ContinuationListener listener)
          Add a ContinuationListener.
 void addListener(AsyncListener listener)
          Registers the given AsyncListener with the most recent asynchronous cycle that was started by a call to one of the ServletRequest.startAsync() methods.
 void addListener(AsyncListener listener, ServletRequest request, ServletResponse response)
          Registers the given AsyncListener with the most recent asynchronous cycle that was started by a call to one of the ServletRequest.startAsync() methods.
 void cancel()
           
protected  void cancelTimeout()
           
 void 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.
<T extends AsyncListener>
T
createListener(java.lang.Class<T> clazz)
          Instantiates the given AsyncListener class.
 void dispatch()
          Dispatches the request and response objects of this AsyncContext to the servlet container.
 void dispatch(ServletContext context, java.lang.String path)
          Dispatches the request and response objects of this AsyncContext to the given path scoped to the given context.
 void dispatch(java.lang.String path)
          Dispatches the request and response objects of this AsyncContext to the given path.
protected  void doComplete(java.lang.Throwable ex)
           
protected  void expired()
           
 AsyncContinuation.AsyncEventState getAsyncEventState()
           
 java.lang.Object getAttribute(java.lang.String name)
          Get a request attribute.
 Request getBaseRequest()
           
 ContextHandler getContextHandler()
           
 ServletRequest getRequest()
          Gets the request that was used to initialize this AsyncContext by calling ServletRequest.startAsync() or ServletRequest.startAsync(ServletRequest, ServletResponse).
 ServletResponse getResponse()
          Gets the response that was used to initialize this AsyncContext by calling ServletRequest.startAsync() or ServletRequest.startAsync(ServletRequest, ServletResponse).
 ServletResponse getServletResponse()
          Get the suspended response.
 java.lang.String getStatusString()
           
 long getTimeout()
          Gets the timeout (in milliseconds) for this AsyncContext.
protected  boolean handling()
           
 boolean hasOriginalRequestAndResponse()
          Checks if this AsyncContext was initialized with the original or application-wrapped request and response objects.
 boolean isAsync()
           
 boolean isAsyncStarted()
           
 boolean isComplete()
           
 boolean isCompleting()
           
 boolean isExpired()
           
 boolean isInitial()
           
 boolean isResponseWrapped()
          Is the suspended response wrapped.
 boolean isResumed()
           
 boolean isSuspended()
           
protected  void recycle()
           
 void removeAttribute(java.lang.String name)
          Remove a request attribute.
 void resume()
          Resume a suspended request.
protected  void scheduleDispatch()
           
protected  void scheduleTimeout()
           
 void setAttribute(java.lang.String name, java.lang.Object attribute)
          Set a request attribute.
protected  void setConnection(HttpConnection connection)
           
 void setTimeout(long ms)
          Sets the timeout (in milliseconds) for this AsyncContext.
 void start(java.lang.Runnable run)
          Causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable.
 void suspend()
          Suspend the processing of the request and associated ServletResponse.
protected  void suspend(ServletContext context, ServletRequest request, ServletResponse response)
           
 void suspend(ServletResponse response)
          Suspend the processing of the request and associated ServletResponse.
 java.lang.String toString()
           
 void undispatch()
          Undispatch the request.
protected  boolean unhandle()
          Signal that the HttpConnection has finished handling the request.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

_connection

protected HttpConnection _connection
Constructor Detail

AsyncContinuation

protected AsyncContinuation()
Method Detail

setConnection

protected void setConnection(HttpConnection connection)

addListener

public void addListener(AsyncListener listener)
Description copied from interface: AsyncContext
Registers the given AsyncListener with the most recent asynchronous cycle that was started by a call to one of the ServletRequest.startAsync() methods.

The given AsyncListener will receive an AsyncEvent when the asynchronous cycle completes successfully, times out, or results in an error.

AsyncListener instances will be notified in the order in which they were added.

Specified by:
addListener in interface AsyncContext
Parameters:
listener - the AsyncListener to be registered

addListener

public void addListener(AsyncListener listener,
                        ServletRequest request,
                        ServletResponse response)
Description copied from interface: AsyncContext
Registers the given AsyncListener with the most recent asynchronous cycle that was started by a call to one of the ServletRequest.startAsync() methods.

The given AsyncListener will receive an AsyncEvent when the asynchronous cycle completes successfully, times out, or results in an error.

AsyncListener instances will be notified in the order in which they were added.

The given ServletRequest and ServletResponse objects will be made available to the given AsyncListener via the getSuppliedRequest and getSuppliedResponse methods, respectively, of the AsyncEvent delivered to it. These objects should not be read from or written to, respectively, at the time the AsyncEvent is delivered, because additional wrapping may have occurred since the given AsyncListener was registered, but may be used in order to release any resources associated with them.

Specified by:
addListener in interface AsyncContext
Parameters:
listener - the AsyncListener to be registered
request - the ServletRequest that will be included in the AsyncEvent
response - the ServletResponse that will be included in the AsyncEvent

addContinuationListener

public void addContinuationListener(ContinuationListener listener)
Description copied from interface: Continuation
Add a ContinuationListener.

Specified by:
addContinuationListener in interface Continuation

setTimeout

public void setTimeout(long ms)
Description copied from interface: AsyncContext
Sets the timeout (in milliseconds) for this AsyncContext.

The timeout applies to this AsyncContext once the container-initiated dispatch during which one of the ServletRequest.startAsync() methods was called has returned to the container.

The timeout will expire if neither the AsyncContext.complete() method nor any of the dispatch methods are called. A timeout value of zero or less indicates no timeout.

If AsyncContext.setTimeout(long) is not called, then the container's default timeout, which is available via a call to AsyncContext.getTimeout(), will apply.

Specified by:
setTimeout in interface AsyncContext
Specified by:
setTimeout in interface Continuation
Parameters:
ms - the timeout in milliseconds

getTimeout

public long getTimeout()
Description copied from interface: AsyncContext
Gets the timeout (in milliseconds) for this AsyncContext.

This method returns the container's default timeout for asynchronous operations, or the timeout value passed to the most recent invocation of AsyncContext.setTimeout(long).

A timeout value of zero or less indicates no timeout.

Specified by:
getTimeout in interface AsyncContext
Returns:
the timeout in milliseconds

getAsyncEventState

public AsyncContinuation.AsyncEventState getAsyncEventState()

isResponseWrapped

public boolean isResponseWrapped()
Description copied from interface: Continuation
Is the suspended response wrapped.

Filters that wrap the response object should check this method to determine if they should destroy/finish the wrapped response. If the request was suspended with a call to Continuation.suspend(ServletResponse) that passed the wrapped response, then the filter should register a ContinuationListener to destroy/finish the wrapped response during a call to ContinuationListener.onComplete(Continuation).

Specified by:
isResponseWrapped in interface Continuation
Returns:
True if Continuation.suspend(ServletResponse) has been passed a ServletResponseWrapper instance.
See Also:
Continuation.isResponseWrapped()

isInitial

public boolean isInitial()
Specified by:
isInitial in interface Continuation
Returns:
true while the request is within the initial dispatch to the filter chain and/or servlet. Will return false once the calling thread has returned to the container after suspend has been called and during any subsequent redispatch.

isSuspended

public boolean isSuspended()
Specified by:
isSuspended in interface Continuation
Returns:
true after Continuation.suspend() has been called and before the request has been redispatched due to being resumed, completed or timed out.

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

getStatusString

public java.lang.String getStatusString()

handling

protected boolean handling()
Returns:
false if the handling of the request should not proceed

suspend

protected void suspend(ServletContext context,
                       ServletRequest request,
                       ServletResponse response)

unhandle

protected boolean unhandle()
Signal that the HttpConnection has finished handling the request. For blocking connectors, this call may block if the request has been suspended (startAsync called).

Returns:
true if handling is complete, false if the request should be handled again (eg because of a resume that happened before unhandle was called)

dispatch

public void dispatch()
Description copied from interface: AsyncContext
Dispatches the request and response objects of this AsyncContext to the servlet container.

If the asynchronous cycle was started with ServletRequest.startAsync(ServletRequest, ServletResponse), and the request passed is an instance of HttpServletRequest, then the dispatch is to the URI returned by HttpServletRequest.getRequestURI(). Otherwise, the dispatch is to the URI of the request when it was last dispatched by the container.

The following sequence illustrates how this will work:

 // REQUEST dispatch to /url/A
 AsyncContext ac = request.startAsync();
 ...
 ac.dispatch(); // ASYNC dispatch to /url/A
 
 // FORWARD dispatch to /url/B
 getRequestDispatcher("/url/B").forward(request,response);
 // Start async operation from within the target of the FORWARD
 // dispatch
 ac = request.startAsync();
 ...
 ac.dispatch(); // ASYNC dispatch to /url/A
 
 // FORWARD dispatch to /url/B
 getRequestDispatcher("/url/B").forward(request,response);
 // Start async operation from within the target of the FORWARD
 // dispatch
 ac = request.startAsync(request,response);
 ...
 ac.dispatch(); // ASYNC dispatch to /url/B
 

This method returns immediately after passing the request and response objects to a container managed thread, on which the dispatch operation will be performed.

The dispatcher type of the request is set to DispatcherType.ASYNC. Unlike forward dispatches, the response buffer and headers will not be reset, and it is legal to dispatch even if the response has already been committed.

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.

Any errors or exceptions that may occur during the execution of this method must be caught and handled by the container, as follows:

  1. Invoke, at their onError method, all AsyncListener instances registered with the ServletRequest for which this AsyncContext was created, and make the caught Throwable available via AsyncEvent.getThrowable().
  2. If none of the listeners called AsyncContext.complete() or any of the AsyncContext.dispatch() methods, perform an error dispatch with a status code equal to HttpServletResponse.SC_INTERNAL_SERVER_ERROR, and make the above Throwable available as the value of the RequestDispatcher.ERROR_EXCEPTION request attribute.
  3. If no matching error page was found, or the error page did not call AsyncContext.complete() or any of the AsyncContext.dispatch() methods, call AsyncContext.complete().

There can be at most one asynchronous dispatch operation per asynchronous cycle, which is started by a call to one of the ServletRequest.startAsync() methods. Any attempt to perform an additional asynchronous dispatch operation within the same asynchronous cycle will result in an IllegalStateException. If startAsync is subsequently called on the dispatched request, then any of the dispatch or AsyncContext.complete() methods may be called.

Specified by:
dispatch in interface AsyncContext
See Also:
ServletRequest.getDispatcherType()

expired

protected void expired()

complete

public void complete()
Description copied from interface: AsyncContext
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.

It is legal to call this method any time after a call to ServletRequest.startAsync() or ServletRequest.startAsync(ServletRequest, ServletResponse), and before a call to one of the dispatch methods of this class. If this method is called before the container-initiated dispatch that called startAsync has returned to the container, then the call will not take effect (and any invocations of AsyncListener.onComplete(AsyncEvent) will be delayed) until after the container-initiated dispatch has returned to the container.

Specified by:
complete in interface AsyncContext
Specified by:
complete in interface Continuation
See Also:
Continuation.suspend()

createListener

public <T extends AsyncListener> T createListener(java.lang.Class<T> clazz)
                                       throws ServletException
Description copied from interface: AsyncContext
Instantiates the given AsyncListener class.

The returned AsyncListener instance may be further customized before it is registered with this AsyncContext via a call to one of the addListener methods.

The given AsyncListener class must define a zero argument constructor, which is used to instantiate it.

This method supports resource injection if the given clazz represents a Managed Bean. See the Java EE platform and JSR 299 specifications for additional details about Managed Beans and resource injection.

This method supports any annotations applicable to AsyncListener.

Specified by:
createListener in interface AsyncContext
Parameters:
clazz - the AsyncListener class to instantiate
Returns:
the new AsyncListener instance
Throws:
ServletException - if the given clazz fails to be instantiated

doComplete

protected void doComplete(java.lang.Throwable ex)

recycle

protected void recycle()

cancel

public void cancel()

scheduleDispatch

protected void scheduleDispatch()

scheduleTimeout

protected void scheduleTimeout()

cancelTimeout

protected void cancelTimeout()

isCompleting

public boolean isCompleting()

isComplete

public boolean isComplete()

isAsyncStarted

public boolean isAsyncStarted()

isAsync

public boolean isAsync()

dispatch

public void dispatch(ServletContext context,
                     java.lang.String path)
Description copied from interface: AsyncContext
Dispatches the request and response objects of this AsyncContext to the given path scoped to the given context.

The path parameter is interpreted in the same way as in ServletRequest.getRequestDispatcher(String), except that it is scoped to the given context.

All path related query methods of the request must reflect the dispatch target, while the original request URI, context path, path info, servlet path, and query string may be recovered from the AsyncContext.ASYNC_REQUEST_URI, AsyncContext.ASYNC_CONTEXT_PATH, AsyncContext.ASYNC_PATH_INFO, AsyncContext.ASYNC_SERVLET_PATH, and AsyncContext.ASYNC_QUERY_STRING attributes of the request. These attributes will always reflect the original path elements, even under repeated dispatches.

There can be at most one asynchronous dispatch operation per asynchronous cycle, which is started by a call to one of the ServletRequest.startAsync() methods. Any attempt to perform an additional asynchronous dispatch operation within the same asynchronous cycle will result in an IllegalStateException. If startAsync is subsequently called on the dispatched request, then any of the dispatch or AsyncContext.complete() methods may be called.

See AsyncContext.dispatch() for additional details, including error handling.

Specified by:
dispatch in interface AsyncContext
Parameters:
context - the ServletContext of the dispatch target
path - the path of the dispatch target, scoped to the given ServletContext
See Also:
ServletRequest.getDispatcherType()

dispatch

public void dispatch(java.lang.String path)
Description copied from interface: AsyncContext
Dispatches the request and response objects of this AsyncContext to the given path.

The path parameter is interpreted in the same way as in ServletRequest.getRequestDispatcher(String), within the scope of the ServletContext from which this AsyncContext was initialized.

All path related query methods of the request must reflect the dispatch target, while the original request URI, context path, path info, servlet path, and query string may be recovered from the AsyncContext.ASYNC_REQUEST_URI, AsyncContext.ASYNC_CONTEXT_PATH, AsyncContext.ASYNC_PATH_INFO, AsyncContext.ASYNC_SERVLET_PATH, and AsyncContext.ASYNC_QUERY_STRING attributes of the request. These attributes will always reflect the original path elements, even under repeated dispatches.

There can be at most one asynchronous dispatch operation per asynchronous cycle, which is started by a call to one of the ServletRequest.startAsync() methods. Any attempt to perform an additional asynchronous dispatch operation within the same asynchronous cycle will result in an IllegalStateException. If startAsync is subsequently called on the dispatched request, then any of the dispatch or AsyncContext.complete() methods may be called.

See AsyncContext.dispatch() for additional details, including error handling.

Specified by:
dispatch in interface AsyncContext
Parameters:
path - the path of the dispatch target, scoped to the ServletContext from which this AsyncContext was initialized
See Also:
ServletRequest.getDispatcherType()

getBaseRequest

public Request getBaseRequest()

getRequest

public ServletRequest getRequest()
Description copied from interface: AsyncContext
Gets the request that was used to initialize this AsyncContext by calling ServletRequest.startAsync() or ServletRequest.startAsync(ServletRequest, ServletResponse).

Specified by:
getRequest in interface AsyncContext
Returns:
the request that was used to initialize this AsyncContext

getResponse

public ServletResponse getResponse()
Description copied from interface: AsyncContext
Gets the response that was used to initialize this AsyncContext by calling ServletRequest.startAsync() or ServletRequest.startAsync(ServletRequest, ServletResponse).

Specified by:
getResponse in interface AsyncContext
Returns:
the response that was used to initialize this AsyncContext

start

public void start(java.lang.Runnable run)
Description copied from interface: AsyncContext
Causes the container to dispatch a thread, possibly from a managed thread pool, to run the specified Runnable. The container may propagate appropriate contextual information to the Runnable.

Specified by:
start in interface AsyncContext
Parameters:
run - the asynchronous handler

hasOriginalRequestAndResponse

public boolean hasOriginalRequestAndResponse()
Description copied from interface: AsyncContext
Checks if this AsyncContext was initialized with the original or application-wrapped request and response objects.

This information may be used by filters invoked in the outbound direction, after a request was put into asynchronous mode, to determine whether any request and/or response wrappers that they added during their inbound invocation need to be preserved for the duration of the asynchronous operation, or may be released.

Specified by:
hasOriginalRequestAndResponse in interface AsyncContext
Returns:
true if this AsyncContext was initialized with the original request and response objects by calling ServletRequest.startAsync(), or if it was initialized by calling ServletRequest.startAsync(ServletRequest, ServletResponse), and neither the ServletRequest nor ServletResponse arguments carried any application-provided wrappers; false otherwise

getContextHandler

public ContextHandler getContextHandler()

isResumed

public boolean isResumed()
Specified by:
isResumed in interface Continuation
Returns:
true if the request has been redispatched by a call to Continuation.resume(). Returns false after any subsequent call to suspend
See Also:
Continuation.isResumed()

isExpired

public boolean isExpired()
Specified by:
isExpired in interface Continuation
Returns:
true after a request has been redispatched as the result of a timeout. Returns false after any subsequent call to suspend.
See Also:
Continuation.isExpired()

resume

public void resume()
Description copied from interface: Continuation
Resume a suspended request.

This method can be called by any thread that has been passed a reference to a continuation. When called the request is redispatched to the normal filter chain and servlet processing with Continuation.isInitial() false.

If resume is called before a suspended request is returned to the container (ie the thread that called Continuation.suspend() is still within the filter chain and/or servlet service method), then the resume does not take effect until the call to the filter chain and/or servlet returns to the container. In this case both Continuation.isSuspended() and Continuation.isResumed() return true. Multiple calls to resume are ignored.

Typically resume() is used after a call to Continuation.suspend() with no arguments. The dispatch after a resume call will use the original request and response objects, even if Continuation.suspend(ServletResponse) had been passed a wrapped response.

Specified by:
resume in interface Continuation
See Also:
Continuation.resume()

suspend

public void suspend(ServletResponse response)
Description copied from interface: Continuation
Suspend the processing of the request and associated ServletResponse.

After this method has been called, the lifecycle of the request will be extended beyond the return to the container from the Servlet.service(ServletRequest, ServletResponse) method and Filter.doFilter(ServletRequest, ServletResponse, FilterChain) calls. When a suspended request is returned to the container after a dispatch, then the container will not commit the associated response (unless an exception other than ContinuationThrowable is thrown).

When the thread calling the filter chain and/or servlet has returned to the container with a suspended request, the thread is freed for other tasks and the request is held until either:

Typically suspend with a response argument is uses when a call to Continuation.complete() is expected. If a call to Continuation.resume() is expected, then the Continuation.suspend() method should be used instead of this method.

Filters that may wrap the response object should check Continuation.isResponseWrapped() to decide if they should destroy/finish the wrapper. If Continuation.isResponseWrapped() returns true, then the wrapped request has been passed to the asynchronous handler and the wrapper should not be destroyed/finished until after a call to Continuation.complete() (potentially using a ContinuationListener.onComplete(Continuation) listener).

Specified by:
suspend in interface Continuation
Parameters:
response - The response to return via a call to Continuation.getServletResponse()
See Also:
Continuation.suspend()

suspend

public void suspend()
Description copied from interface: Continuation
Suspend the processing of the request and associated ServletResponse.

After this method has been called, the lifecycle of the request will be extended beyond the return to the container from the Servlet.service(ServletRequest, ServletResponse) method and Filter.doFilter(ServletRequest, ServletResponse, FilterChain) calls. When a suspended request is returned to the container after a dispatch, then the container will not commit the associated response (unless an exception other than ContinuationThrowable is thrown).

When the thread calling the filter chain and/or servlet has returned to the container with a suspended request, the thread is freed for other tasks and the request is held until either:

Typically suspend with no arguments is uses when a call to Continuation.resume() is expected. If a call to Continuation.complete() is expected, then the Continuation.suspend(ServletResponse) method should be used instead of this method.

Specified by:
suspend in interface Continuation
See Also:
Continuation.suspend()

getServletResponse

public ServletResponse getServletResponse()
Description copied from interface: Continuation
Get the suspended response.

Specified by:
getServletResponse in interface Continuation
Returns:
the ServletResponse passed to Continuation.suspend(ServletResponse).
See Also:
Continuation.getServletResponse()

getAttribute

public java.lang.Object getAttribute(java.lang.String name)
Description copied from interface: Continuation
Get a request attribute. This method is a convenience method to call the ServletRequest.getAttribute(String) method on the associated request object. This is a thread safe call and may be called by any thread.

Specified by:
getAttribute in interface Continuation
Parameters:
name - the attribute name
Returns:
the attribute value
See Also:
Continuation.getAttribute(java.lang.String)

removeAttribute

public void removeAttribute(java.lang.String name)
Description copied from interface: Continuation
Remove a request attribute. This method is a convenience method to call the ServletRequest.removeAttribute(String) method on the associated request object. This is a thread safe call and may be called by any thread.

Specified by:
removeAttribute in interface Continuation
Parameters:
name - the attribute name
See Also:
Continuation.removeAttribute(java.lang.String)

setAttribute

public void setAttribute(java.lang.String name,
                         java.lang.Object attribute)
Description copied from interface: Continuation
Set a request attribute. This method is a convenience method to call the ServletRequest.setAttribute(String, Object) method on the associated request object. This is a thread safe call and may be called by any thread.

Specified by:
setAttribute in interface Continuation
Parameters:
name - the attribute name
attribute - the attribute value
See Also:
Continuation.setAttribute(java.lang.String, java.lang.Object)

undispatch

public void undispatch()
Description copied from interface: Continuation
Undispatch the request.

This method can be called on a suspended continuation in order to exit the dispatch to the filter/servlet by throwing a ContinuationThrowable which is caught either by the container or the ContinuationFilter. This is an alternative to simply returning from the dispatch in the case where filters in the filter chain may not be prepared to handle a suspended request.

This method should only be used as a last resort and a normal return is a prefereable solution if filters can be updated to handle that case.

Specified by:
undispatch in interface Continuation
See Also:
Continuation.undispatch()


Copyright © 1995-2010 Mort Bay Consulting. All Rights Reserved.