# Class AsyncContextImpl

java.lang.Object
org.apache.catalina.core.AsyncContextImpl

All Implemented Interfaces:
  `AsyncContext, AsyncContextCallback`

public class AsyncContextImpl extends Object implements AsyncContext, AsyncContextCallback
Implementation of `AsyncContext` that manages the lifecycle of an asynchronous request processing operation. Each instance is associated with a single request object. If an asynchronous request starts multiple cycles of asynchronous processing, the AsyncContextImpl is re-used for all cycles. Once complete is called or an async dispatch does not trigger a new asynchronous request the AsyncContextImpl is recycled and discarded. It is not re-used.

There is a concurrency risk that comes from applications retaining references to an AsyncContext in non-container threads and trying to use those references beyond the point the references are valid. This has most frequently been observed at shutdown but shutdown is an instance of the more general case of the async request timing out, Tomcat cleaning it up but the application continuing to process on a non-container thread. Other application bugs can have similar results.

To mitigate against concurrency issues:

- AsyncContext methods that can be called by an application take local copies of any instance variables used, validate the instance is in a valid state and then execute the method.
- AsyncContext methods that can only be called by Tomcat internal methods don't check state on the basis that Tomcat manages state and only calls those methods when the state is valid.
- To avoid concurrency issues with the state of the local variables, a dedicated atomic flag `hasBeenRecycled` tracks whether recycled has been called.

## Field Summary

Fields
Modifier and Type
Field
Description
`protected static final StringManager`
`sm`
String manager for localized log messages.

### Fields inherited from interface AsyncContext

`ASYNC_CONTEXT_PATH, ASYNC_MAPPING, ASYNC_PATH_INFO, ASYNC_QUERY_STRING, ASYNC_REQUEST_URI, ASYNC_SERVLET_PATH`

## Constructor Summary

Constructors
Constructor
Description
`AsyncContextImpl(Request request)`
Constructs an AsyncContextImpl for the given request.

## Method Summary

Modifier and Type
Method
Description
`void`
`addListener(AsyncListener listener)`
Adds an event listener that will be called for different AsyncEvents fire
`void`
`addListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse)`
Adds an event listener that will be called when different AsyncEvents fire
`void`
`complete()`
Completes the async request processing and closes the response stream
`<T extends AsyncListener>
T`
`createListener(Class<T> clazz)`
Creates and returns an AsyncListener object
`void`
`decrementInProgressAsyncCount()`
Used to notify the Context that async processing has ended.
`void`
`dispatch()`
Dispatches the request to the resource at the original request URI, as specified in the original request.
`void`
`dispatch(ServletContext servletContext, String path)`
Dispatches the request to the resource at the specified path relative to the given `ServletContext`.
`void`
`dispatch(String path)`
Dispatches the request to the resource at the specified path relative to the `ServletContext` from which this async request was started.
`protected void`
`doInternalDispatch()`
Performs the internal dispatch for the pending async dispatch operation.
`void`
`fireOnComplete()`
Fires the onComplete event to the associated async context.
`ServletRequest`
`getRequest()`
Returns the `ServletRequest` associated with this asynchronous operation.
`ServletResponse`
`getResponse()`
Returns the `ServletResponse` associated with this asynchronous operation.
`long`
`getTimeout()`
Get the current timeout.
`boolean`
`hasOriginalRequestAndResponse()`
Determines whether the request and response objects are the original ones passed to `ServletRequest.startAsync()`, or if they are new objects created by the container.
`void`
`incrementInProgressAsyncCount()`
Used to notify the Context that async processing has started.
`boolean`
`isAvailable()`
Reports if the web application associated with this async request is available.
`boolean`
`isStarted()`
Checks whether async processing has been started for this context.
`void`
`recycle()`
Recycles this async context, resetting all internal state for reuse.
`void`
`setErrorState(Throwable t, boolean fireOnError)`
Sets the error state and optionally fires onError events to all registered listeners.
`void`
`setStarted(Context context, ServletRequest request, ServletResponse response, boolean originalRequestResponse)`
Initializes this async context with the given parameters and fires onStartAsync events.
`void`
`setTimeout(long timeout)`
Set the timeout.
`void`
`start(Runnable run)`
Starts a new thread to process the asynchronous request
`boolean`
`timeout()`
Fires the timeout event for this async context.

### Methods inherited from class Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Field Details

### sm

protected static final StringManager sm
String manager for localized log messages.

## Constructor Details

### AsyncContextImpl

public AsyncContextImpl(Request request)
Constructs an AsyncContextImpl for the given request.

Parameters:
  `request` - The request associated with this async context

## Method Details

### complete

public void complete()
Description copied from interface: `jakarta.servlet.AsyncContext`
Completes the async request processing and closes the response stream

Specified by:
  `complete` in interface `AsyncContext`

### fireOnComplete

public void fireOnComplete()
Description copied from interface: `AsyncContextCallback`
Fires the onComplete event to the associated async context.

Specified by:
  `fireOnComplete` in interface `AsyncContextCallback`

### timeout

public boolean timeout()
Fires the timeout event for this async context.

Returns:
  `true` if the timeout was handled successfully

### dispatch

public void dispatch()
Description copied from interface: `jakarta.servlet.AsyncContext`
Dispatches the request to the resource at the original request URI, as specified in the original request. After the dispatch, the async request processing is complete and the response is committed.

Specified by:
  `dispatch` in interface `AsyncContext`

### dispatch

public void dispatch(String path)
Description copied from interface: `jakarta.servlet.AsyncContext`
Dispatches the request to the resource at the specified path relative to the `ServletContext` from which this async request was started. After the dispatch, the async request processing is complete and the response is committed.

Specified by:
  `dispatch` in interface `AsyncContext`
Parameters:
  `path` - the path to which the request/response should be dispatched relative to the `ServletContext` from which this async request was started

### dispatch

public void dispatch(ServletContext servletContext, String path)
Description copied from interface: `jakarta.servlet.AsyncContext`
Dispatches the request to the resource at the specified path relative to the given `ServletContext`. After the dispatch, the async request processing is complete and the response is committed.

Specified by:
  `dispatch` in interface `AsyncContext`
Parameters:
  `servletContext` - the `ServletContext` to which the request/response should be dispatched
  `path` - the path to which the request/response should be dispatched relative to the specified `ServletContext`

### getRequest

public ServletRequest getRequest()
Description copied from interface: `jakarta.servlet.AsyncContext`
Returns the `ServletRequest` associated with this asynchronous operation.

Specified by:
  `getRequest` in interface `AsyncContext`
Returns:
  the ServletRequest object

### getResponse

public ServletResponse getResponse()
Description copied from interface: `jakarta.servlet.AsyncContext`
Returns the `ServletResponse` associated with this asynchronous operation.

Specified by:
  `getResponse` in interface `AsyncContext`
Returns:
  the ServletResponse object

### start

public void start(Runnable run)
Description copied from interface: `jakarta.servlet.AsyncContext`
Starts a new thread to process the asynchronous request

Specified by:
  `start` in interface `AsyncContext`
Parameters:
  `run` - a Runnable that the new thread will run

### addListener

public void addListener(AsyncListener listener)
Description copied from interface: `jakarta.servlet.AsyncContext`
Adds an event listener that will be called for different AsyncEvents fire

Specified by:
  `addListener` in interface `AsyncContext`
Parameters:
  `listener` - an AsyncListener that will be called with AsyncEvent objects

### addListener

public void addListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse)
Description copied from interface: `jakarta.servlet.AsyncContext`
Adds an event listener that will be called when different AsyncEvents fire

Specified by:
  `addListener` in interface `AsyncContext`
Parameters:
  `listener` - an AsyncListener that will be called with AsyncEvent objects
  `servletRequest` - the ServletRequest that will be passed with the AsyncEvent
  `servletResponse` - the ServletResponse that will be passed with the AsyncEvent

### createListener

public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException
Description copied from interface: `jakarta.servlet.AsyncContext`
Creates and returns an AsyncListener object

Specified by:
  `createListener` in interface `AsyncContext`
Type Parameters:
  `T` - The type to create that extends AsyncListener
Parameters:
  `clazz` - The class to instantiate to create the listener
Returns:
  the newly created AsyncListener object
Throws:
  `ServletException` - if the listener cannot be created

### recycle

public void recycle()
Recycles this async context, resetting all internal state for reuse.

### isStarted

public boolean isStarted()
Checks whether async processing has been started for this context.

Returns:
  `true` if async processing has started

### setStarted

public void setStarted(Context context, ServletRequest request, ServletResponse response, boolean originalRequestResponse)
Initializes this async context with the given parameters and fires onStartAsync events.

Parameters:
  `context` - The context for this async operation
  `request` - The servlet request
  `response` - The servlet response
  `originalRequestResponse` - `true` if the request/response are the original ones

### hasOriginalRequestAndResponse

public boolean hasOriginalRequestAndResponse()
Description copied from interface: `jakarta.servlet.AsyncContext`
Determines whether the request and response objects are the original ones passed to `ServletRequest.startAsync()`, or if they are new objects created by the container.

Specified by:
  `hasOriginalRequestAndResponse` in interface `AsyncContext`
Returns:
  `true` if the request and response are the original objects, `false` otherwise

### doInternalDispatch

protected void doInternalDispatch() throws ServletException, IOException
Performs the internal dispatch for the pending async dispatch operation.

Throws:
  `ServletException` - if a servlet error occurs
  `IOException` - if an I/O error occurs

### getTimeout

public long getTimeout()
Description copied from interface: `jakarta.servlet.AsyncContext`
Get the current timeout.

Specified by:
  `getTimeout` in interface `AsyncContext`
Returns:
  The timeout in milliseconds. 0 or less indicates no timeout.

### setTimeout

public void setTimeout(long timeout)
Description copied from interface: `jakarta.servlet.AsyncContext`
Set the timeout.

Specified by:
  `setTimeout` in interface `AsyncContext`
Parameters:
  `timeout` - The timeout in milliseconds. 0 or less indicates no timeout.

### isAvailable

public boolean isAvailable()
Description copied from interface: `AsyncContextCallback`
Reports if the web application associated with this async request is available.

Specified by:
  `isAvailable` in interface `AsyncContextCallback`
Returns:
  `true` if the associated web application is available, otherwise `false`

### setErrorState

public void setErrorState(Throwable t, boolean fireOnError)
Sets the error state and optionally fires onError events to all registered listeners.

Parameters:
  `t` - The throwable that caused the error, or `null`
  `fireOnError` - `true` if onError should be fired to listeners

### incrementInProgressAsyncCount

public void incrementInProgressAsyncCount()
Description copied from interface: `AsyncContextCallback`
Used to notify the Context that async processing has started. Specifically, for the counting of in-progress async requests to work correctly, this must be called exactly once every time the `AsyncStateMachine` transitions from DISPATCHED to any other state.

Specified by:
  `incrementInProgressAsyncCount` in interface `AsyncContextCallback`

### decrementInProgressAsyncCount

public void decrementInProgressAsyncCount()
Description copied from interface: `AsyncContextCallback`
Used to notify the Context that async processing has ended. Specifically, for the counting of in-progress async requests to work correctly, this must be called exactly once every time the `AsyncStateMachine` transitions to DISPATCHED from any other state.

Specified by:
  `decrementInProgressAsyncCount` in interface `AsyncContextCallback`