Bug 55331 - Dispatch after async timeout fails
Summary: Dispatch after async timeout fails
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 7.0.42
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-07-31 11:50 UTC by Peter De Wachter
Modified: 2013-10-17 02:51 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
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.