Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## org.eclipse.jetty.continuation
Interface Continuation

All Known Subinterfaces:
  ContinuationFilter.FilteredContinuation

All Known Implementing Classes:
  AsyncContinuation, Jetty6Continuation, Servlet3Continuation

    public interface Continuation

Continuation. A continuation is a mechanism by which a HTTP Request can be suspended and restarted after a timeout or an asynchronous event has occurred.

The continuation mechanism is a portable mechanism that will work asynchronously without additional configuration of all jetty-7, jetty-8 and Servlet 3.0 containers. With the addition of the `ContinuationFilter`, the mechanism will also work asynchronously on jetty-6 and non-asynchronously on any servlet 2.5 container.

The Continuation API is a simplification of the richer async API provided by the servlet-3.0 and an enhancement of the continuation API that was introduced with jetty-6.

# Continuation Usage

A continuation object is obtained for a request by calling the factory method `ContinuationSupport.getContinuation(ServletRequest)`. The continuation type returned will depend on the servlet container being used.

There are two distinct style of operation of the continuation API.

### Suspend/Resume Usage

The suspend/resume style is used when a servlet and/or filter is used to generate the response after a asynchronous wait that is terminated by an asynchronous handler.

     Filter/Servlet:
       // if we need to get asynchronous results
       Object results = request.getAttribute("results);
       if (results==null)
       {
         Continuation continuation = ContinuationSupport.getContinuation(request);
         continuation.suspend();
         myAsyncHandler.register(continuation);
         return; // or continuation.undispatch();
       }

     async wait ...

     Async Handler:
       // when the waited for event happens
       continuation.setAttribute("results",event);
       continuation.resume();

     Filter/Servlet:
       // when the request is redispatched
       if (results==null)
       {
         ... // see above
       }
       else
       {
         response.getOutputStream().write(process(results));
       }

### Suspend/Complete Usage

The suspend/complete style is used when an asynchronous handler is used to generate the response:

     Filter/Servlet:
       // when we want to enter asynchronous mode
       Continuation continuation = ContinuationSupport.getContinuation(request);
       continuation.suspend(response); // response may be wrapped
       myAsyncHandler.register(continuation);
       return; // or continuation.undispatch();

     Wrapping Filter:
       // any filter that had wrapped the response should be implemented like:
       try
       {
         chain.doFilter(request,wrappedResponse);
       }
       finally
       {
         if (!continuation.isResponseWrapped())
           wrappedResponse.finish()
         else
           continuation.addContinuationListener(myCompleteListener)
       }

     async wait ...

     Async Handler:
       // when the async event happens
       continuation.getServletResponse().getOutputStream().write(process(event));
       continuation.complete()

# Continuation Timeout

If a continuation is suspended, but neither `complete()` or `resume()` is called during the period set by `setTimeout(long)`, then the continuation will expire and `isExpired()` will return true.

When a continuation expires, the `ContinuationListener.onTimeout(Continuation)` method is called on any `ContinuationListener` that has been registered via the `addContinuationListener(ContinuationListener)` method. The onTimeout handlers may write a response and call `complete()`. If `complete()` is not called, then the container will redispatch the request as if `resume()` had been called, except that `isExpired()` will be true and `isResumed()` will be false.

See Also:
  `ContinuationSupport`, `ContinuationListener`

Field Summary
`static java.lang.String` | `ATTRIBUTE`

Method Summary
`void` | `addContinuationListener(ContinuationListener listener)` Add a ContinuationListener.
`void` | `complete()` Complete a suspended request.
`java.lang.Object` | `getAttribute(java.lang.String name)` Get a request attribute.
`ServletResponse` | `getServletResponse()` Get the suspended response.
`boolean` | `isExpired()`
`boolean` | `isInitial()`
`boolean` | `isResponseWrapped()` Is the suspended response wrapped.
`boolean` | `isResumed()`
`boolean` | `isSuspended()`
`void` | `removeAttribute(java.lang.String name)` Remove a request attribute.
`void` | `resume()` Resume a suspended request.
`void` | `setAttribute(java.lang.String name, java.lang.Object attribute)` Set a request attribute.
`void` | `setTimeout(long timeoutMs)` Set the continuation timeout.
`void` | `suspend()` Suspend the processing of the request and associated `ServletResponse`.
`void` | `suspend(ServletResponse response)` Suspend the processing of the request and associated `ServletResponse`.
`void` | `undispatch()` Undispatch the request.

Field Detail

### ATTRIBUTE

    static final java.lang.String ATTRIBUTE

See Also:
  Constant Field Values

Method Detail

### setTimeout

    void setTimeout(long timeoutMs)

  Set the continuation timeout.

  Parameters:
    `timeoutMs` - The time in milliseconds to wait before expiring this continuation after a call to `suspend()` or `suspend(ServletResponse)`. A timeout of <=0 means the continuation will never expire.

### suspend

    void suspend()

  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:

  - a call to `resume()`.
  - a call to `complete()`.
  - the timeout expires.

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

  Throws:
    `java.lang.IllegalStateException` - If the request cannot be suspended

### suspend

    void suspend(ServletResponse response)

  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:

  - a call to `resume()`.
  - a call to `complete()`.
  - the timeout expires.

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

  Filters that may wrap the response object should check `isResponseWrapped()` to decide if they should destroy/finish the wrapper. If `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 `complete()` (potentially using a `ContinuationListener.onComplete(Continuation)` listener).

  Parameters:
    `response` - The response to return via a call to `getServletResponse()`
  Throws:
    `java.lang.IllegalStateException` - If the request cannot be suspended

### resume

    void resume()

  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 `isInitial()` false.

  If resume is called before a suspended request is returned to the container (ie the thread that called `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 `isSuspended()` and `isResumed()` return true. Multiple calls to resume are ignored.

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

  Throws:
    `java.lang.IllegalStateException` - if the request is not suspended.
  See Also:
    `suspend()`

### complete

    void complete()

  Complete a suspended request.

  This method can be called by any thread that has been passed a reference to a suspended request. When a request is completed, the associated response object committed and flushed. The request is not redispatched.

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

  Typically resume() is used after a call to `suspend(ServletResponse)` with a possibly wrapped response. The async handler should use the response provided by `getServletResponse()` to write the response before calling `complete()`. If the request was suspended with a call to `suspend()` then no response object will be available via `getServletResponse()`.

  Once complete has been called and any thread calling the filter chain and/or servlet chain has returned to the container, the request lifecycle is complete. The container is able to recycle request objects, so it is not valid hold a request or continuation reference after the end of the life cycle.

  Throws:
    `java.lang.IllegalStateException` - if the request is not suspended.
  See Also:
    `suspend()`

### isSuspended

    boolean isSuspended()

  Returns:
    true after `suspend()` has been called and before the request has been redispatched due to being resumed, completed or timed out.

### isResumed

    boolean isResumed()

  Returns:
    true if the request has been redispatched by a call to `resume()`. Returns false after any subsequent call to suspend

### isExpired

    boolean isExpired()

  Returns:
    true after a request has been redispatched as the result of a timeout. Returns false after any subsequent call to suspend.

### isInitial

    boolean isInitial()

  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.

### isResponseWrapped

    boolean isResponseWrapped()

  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 `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)`.

  Returns:
    True if `suspend(ServletResponse)` has been passed a `ServletResponseWrapper` instance.

### getServletResponse

    ServletResponse getServletResponse()

  Get the suspended response.

  Returns:
    the `ServletResponse` passed to `suspend(ServletResponse)`.

### addContinuationListener

    void addContinuationListener(ContinuationListener listener)

  Add a ContinuationListener.

  Parameters:
    `listener` -

### setAttribute

    void setAttribute(java.lang.String name,
                      java.lang.Object attribute)

  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.

  Parameters:
    `name` - the attribute name
    `attribute` - the attribute value

### getAttribute

    java.lang.Object getAttribute(java.lang.String name)

  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.

  Parameters:
    `name` - the attribute name
  Returns:
    the attribute value

### removeAttribute

    void removeAttribute(java.lang.String name)

  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.

  Parameters:
    `name` - the attribute name

### undispatch

    void undispatch()
                    throws ContinuationThrowable

  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.

  Throws:
    `ContinuationThrowable` - thrown if the request is suspended. The instance of the exception may be reused on subsequent calls, so the stack frame may not be accurate.

Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

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