# 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`