SERVLET_SPEC-109: AsyncContext#complete will not take effect
I am looking at an issue about AsyncContext#complete [1]
Let us consider the following scenario inside a HttpServlet#doGet:
AsyncContext ac = req.startAsync();
...
ac.complete();
boolean start = req.isAsyncStarted(); (A)
Is 'start' true or false in (A)?
We have the following from Javadoc:
a) AsyncContext#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.
b) ServletRequest#isAsyncStarted:
Checks if this request has been put into asynchronous mode.
A ServletRequest is put into asynchronous mode by calling startAsync() or
startAsync(ServletRequest,ServletResponse) on it.
This method returns false if this request was put into asynchronous mode,
but has since been dispatched using one of the AsyncContext.dispatch()
methods or released from asynchronous mode via a call to
AsyncContext.complete().
However, in Servlet spec, we have the following for AsyncContext#complete.
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 until after the
container-initiated dispatch has returned to the container. Invocation of the
AsyncListener.onComplete(AsyncEvent) will also be delayed till after the
container-initiated dispatch has returned to the container.
Note that there is a similar paragraph in AsyncContext#dispatch as follows:
If any of the dispatch methods are called before the container-initiated dispatch
that called startAsync has returned to the container, then the call will not take
effect until after the container-initiated dispatch has returned to the container.
Invocation of the AsyncListener.onComplete(AsyncEvent), AsyncListener.onTimeout(AsyncEvent)and
AsyncListener.onError(AsyncEvent) will also be delayed till after the
container-initiated dispatch has returned to the container.
Since AsyncContext#complete "will not take effect until after the container-initiated
dispatch has returned to the container.", we will have
start = true // in (A) above
I plan to clarify the spec as follows:
a) AsyncContext#complete:
If this method is invoked before the container-initiated dispatch that called startAsync
has returned to the container, the following conditions must hold during that time
between the invocation of complete and the return of control to the container:
* the behavior specified for complete will not take effect until after
the startAsync caller has returned to the container.
* any AsyncListener.onComplete(AsyncEvent) invocations will
also be delayed until after the startAsync caller has returned to the
container.
* any calls to request.isAsyncStarted() must return true until
after the startAsync caller has returned to the container.
b) AsyncContext#dispatch
If any of the dispatch methods are invoked before the container-initiated dispatch
that called startAsync has returned to the container, the following conditions must
hold during that time between the invocation of complete and the return of control
to the container:
* any dispatch invocations invoked during that time will not take
effect until after the startAsync caller has returned to container.
* any AsyncListener.onComplete(AsyncEvent),
AsyncListener.onTimeout(AsyncEvent) or
AsyncListener.onError(AsyncEvent) invocations will also be delayed
until after the startAsync caller has returned to the container.
* any calls to request.isAsyncStarted() must return true until
after the startAsync caller has returned to the container.
Please let me know your comments.
Thanks.
Shing Wai Chan
[1]
https://java.net/jira/browse/SERVLET_SPEC-109