Package org.apache.catalina.core
Class AsyncContextImpl
- java.lang.Object
-
- org.apache.catalina.core.AsyncContextImpl
-
- All Implemented Interfaces:
AsyncContext,AsyncContextCallback
public class AsyncContextImpl extends java.lang.Object implements AsyncContext, AsyncContextCallback
Implementation ofAsyncContextthat 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
hasBeenRecycledtracks whether recycled has been called.
-
-
Field Summary
Fields Modifier and Type Field Description protected static StringManagersmString manager for localized log messages.-
Fields inherited from interface jakarta.servlet.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
All Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaddListener(AsyncListener listener)Adds an event listener that will be called for different AsyncEvents firevoidaddListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse)Adds an event listener that will be called when different AsyncEvents firevoidcomplete()Completes the async request processing and closes the response stream<T extends AsyncListener>
TcreateListener(java.lang.Class<T> clazz)Creates and returns an AsyncListener objectvoiddecrementInProgressAsyncCount()Used to notify the Context that async processing has ended.voiddispatch()Dispatches the request to the resource at the original request URI, as specified in the original request.voiddispatch(ServletContext servletContext, java.lang.String path)Dispatches the request to the resource at the specified path relative to the givenServletContext.voiddispatch(java.lang.String path)Dispatches the request to the resource at the specified path relative to theServletContextfrom which this async request was started.protected voiddoInternalDispatch()Performs the internal dispatch for the pending async dispatch operation.voidfireOnComplete()Fires the onComplete event to the associated async context.ServletRequestgetRequest()Returns theServletRequestassociated with this asynchronous operation.ServletResponsegetResponse()Returns theServletResponseassociated with this asynchronous operation.longgetTimeout()Get the current timeout.booleanhasOriginalRequestAndResponse()Determines whether the request and response objects are the original ones passed toServletRequest.startAsync(), or if they are new objects created by the container.voidincrementInProgressAsyncCount()Used to notify the Context that async processing has started.booleanisAvailable()Reports if the web application associated with this async request is available.booleanisStarted()Checks whether async processing has been started for this context.voidrecycle()Recycles this async context, resetting all internal state for reuse.voidsetErrorState(java.lang.Throwable t, boolean fireOnError)Sets the error state and optionally fires onError events to all registered listeners.voidsetStarted(Context context, ServletRequest request, ServletResponse response, boolean originalRequestResponse)Initializes this async context with the given parameters and fires onStartAsync events.voidsetTimeout(long timeout)Set the timeout.voidstart(java.lang.Runnable run)Starts a new thread to process the asynchronous requestbooleantimeout()Fires the timeout event for this async context.
-
-
-
Field Detail
-
sm
protected static final StringManager sm
String manager for localized log messages.
-
-
Constructor Detail
-
AsyncContextImpl
public AsyncContextImpl(Request request)
Constructs an AsyncContextImpl for the given request.- Parameters:
request- The request associated with this async context
-
-
Method Detail
-
complete
public void complete()
Description copied from interface:jakarta.servlet.AsyncContextCompletes the async request processing and closes the response stream- Specified by:
completein interfaceAsyncContext
-
fireOnComplete
public void fireOnComplete()
Description copied from interface:AsyncContextCallbackFires the onComplete event to the associated async context.- Specified by:
fireOnCompletein interfaceAsyncContextCallback
-
timeout
public boolean timeout()
Fires the timeout event for this async context.- Returns:
trueif the timeout was handled successfully
-
dispatch
public void dispatch()
Description copied from interface:jakarta.servlet.AsyncContextDispatches 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:
dispatchin interfaceAsyncContext
-
dispatch
public void dispatch(java.lang.String path)
Description copied from interface:jakarta.servlet.AsyncContextDispatches the request to the resource at the specified path relative to theServletContextfrom which this async request was started. After the dispatch, the async request processing is complete and the response is committed.- Specified by:
dispatchin interfaceAsyncContext- Parameters:
path- the path to which the request/response should be dispatched relative to theServletContextfrom which this async request was started
-
dispatch
public void dispatch(ServletContext servletContext, java.lang.String path)
Description copied from interface:jakarta.servlet.AsyncContextDispatches the request to the resource at the specified path relative to the givenServletContext. After the dispatch, the async request processing is complete and the response is committed.- Specified by:
dispatchin interfaceAsyncContext- Parameters:
servletContext- theServletContextto which the request/response should be dispatchedpath- the path to which the request/response should be dispatched relative to the specifiedServletContext
-
getRequest
public ServletRequest getRequest()
Description copied from interface:jakarta.servlet.AsyncContextReturns theServletRequestassociated with this asynchronous operation.- Specified by:
getRequestin interfaceAsyncContext- Returns:
- the ServletRequest object
-
getResponse
public ServletResponse getResponse()
Description copied from interface:jakarta.servlet.AsyncContextReturns theServletResponseassociated with this asynchronous operation.- Specified by:
getResponsein interfaceAsyncContext- Returns:
- the ServletResponse object
-
start
public void start(java.lang.Runnable run)
Description copied from interface:jakarta.servlet.AsyncContextStarts a new thread to process the asynchronous request- Specified by:
startin interfaceAsyncContext- Parameters:
run- a Runnable that the new thread will run
-
addListener
public void addListener(AsyncListener listener)
Description copied from interface:jakarta.servlet.AsyncContextAdds an event listener that will be called for different AsyncEvents fire- Specified by:
addListenerin interfaceAsyncContext- 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.AsyncContextAdds an event listener that will be called when different AsyncEvents fire- Specified by:
addListenerin interfaceAsyncContext- Parameters:
listener- an AsyncListener that will be called with AsyncEvent objectsservletRequest- the ServletRequest that will be passed with the AsyncEventservletResponse- the ServletResponse that will be passed with the AsyncEvent
-
createListener
public <T extends AsyncListener> T createListener(java.lang.Class<T> clazz) throws ServletException
Description copied from interface:jakarta.servlet.AsyncContextCreates and returns an AsyncListener object- Specified by:
createListenerin interfaceAsyncContext- 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:
trueif 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 operationrequest- The servlet requestresponse- The servlet responseoriginalRequestResponse-trueif the request/response are the original ones
-
hasOriginalRequestAndResponse
public boolean hasOriginalRequestAndResponse()
Description copied from interface:jakarta.servlet.AsyncContextDetermines whether the request and response objects are the original ones passed toServletRequest.startAsync(), or if they are new objects created by the container.- Specified by:
hasOriginalRequestAndResponsein interfaceAsyncContext- Returns:
trueif the request and response are the original objects,falseotherwise
-
doInternalDispatch
protected void doInternalDispatch() throws ServletException, java.io.IOExceptionPerforms the internal dispatch for the pending async dispatch operation.- Throws:
ServletException- if a servlet error occursjava.io.IOException- if an I/O error occurs
-
getTimeout
public long getTimeout()
Description copied from interface:jakarta.servlet.AsyncContextGet the current timeout.- Specified by:
getTimeoutin interfaceAsyncContext- Returns:
- The timeout in milliseconds. 0 or less indicates no timeout.
-
setTimeout
public void setTimeout(long timeout)
Description copied from interface:jakarta.servlet.AsyncContextSet the timeout.- Specified by:
setTimeoutin interfaceAsyncContext- Parameters:
timeout- The timeout in milliseconds. 0 or less indicates no timeout.
-
isAvailable
public boolean isAvailable()
Description copied from interface:AsyncContextCallbackReports if the web application associated with this async request is available.- Specified by:
isAvailablein interfaceAsyncContextCallback- Returns:
trueif the associated web application is available, otherwisefalse
-
setErrorState
public void setErrorState(java.lang.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, ornullfireOnError-trueif onError should be fired to listeners
-
incrementInProgressAsyncCount
public void incrementInProgressAsyncCount()
Description copied from interface:AsyncContextCallbackUsed 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 theAsyncStateMachinetransitions from DISPATCHED to any other state.- Specified by:
incrementInProgressAsyncCountin interfaceAsyncContextCallback
-
decrementInProgressAsyncCount
public void decrementInProgressAsyncCount()
Description copied from interface:AsyncContextCallbackUsed 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 theAsyncStateMachinetransitions to DISPATCHED from any other state.- Specified by:
decrementInProgressAsyncCountin interfaceAsyncContextCallback
-
-