Bug 55331

Summary: Dispatch after async timeout fails
Product: Tomcat 7 Reporter: Peter De Wachter <pdewacht>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal CC: fratboy77
Priority: P2    
Version: 7.0.42   
Target Milestone: ---   
Hardware: PC   
OS: Linux   

Description Peter De Wachter 2013-07-31 11:50:09 UTC
With Tomcat 7.0.42 and the NIO connector, calling AsyncContext.dispatch() from an onTimeout() handler fails with this error message:

jul 31, 2013 1:40:30 PM org.apache.coyote.AbstractProtocol$AbstractConnectionHandler process
SEVERE: Error reading request, ignored
java.lang.IllegalStateException: Calling [asyncPostProcess()] is not valid for a request with Async state [STARTED]
        at org.apache.coyote.AsyncStateMachine.asyncPostProcess(AsyncStateMachine.java:204)
        at org.apache.coyote.AbstractProcessor.asyncPostProcess(AbstractProcessor.java:116)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:593)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1690)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:724)


Test code:

public class AsyncServlet extends HttpServlet {

  protected void doGet(final HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    if (request.isAsyncStarted()) {
      response.getWriter().write("asyncResult=" + request.getAttribute("asyncResult"));
    }
    else {
      final AsyncContext asyncContext = request.startAsync(request, response);

      asyncContext.addListener(new AsyncListener() {
        public void onTimeout(AsyncEvent event) throws IOException {
            request.setAttribute("asyncResult", "timeout\n");
            asyncContext.dispatch();
        }
        public void onStartAsync(AsyncEvent event) throws IOException {}
        public void onError(AsyncEvent event) throws IOException {}
        public void onComplete(AsyncEvent event) throws IOException {}
      });

      asyncContext.setTimeout(5000L);
    }
  }

}


This seems somewhat similar to the (ancient) report #50308.
Comment 1 Mark Thomas 2013-08-01 10:03:13 UTC
Thanks for the report. This has been fixed in trunk and 7.0.x and will be included in 7.0.43 onwards.

Note that the example servlet provided above will trigger an infinite loop as once the dispatch occurs, request.isAsyncStarted() will return false.