Hi,

 

We encountered a problem during asynchronous operations (tomcat 7 with
servlet 3). 

Description:  

One client continuously sends post requests to the server. On the server
side for each request created AsyncContext with timeout 20 seconds:

AsyncContext asyncContext = req.startAsync(req, resp);

      asyncContext.setTimeout(20000);

As expected after approximately 20 sec the requests are completed. Then
another client also begins to send requests to the server but in this case
they are explicitly completed after 500 milliseconds. Something like this:

AsyncContext asyncContext = req.startAsync(req, resp);

      asyncContext.setTimeout(20000);

      

      try {

         Thread.sleep(500);

      } catch (Exception e) {

      }

 

      asyncContext.complete();

 

The problem is that after running the second client all the requested
waiting for timeout (from the first client) are stuck and not released
(onTimeout method of AsyncEvent is not called) until the second client stops
sending requests.

It looks like the problem occurs on Linux but not on Windows.

 

Below is a simple test that may help to reproduce this issue. The following
servlet accepts URL parameter "complete".

When "complete=1" the request will be completed after 500ms.

Otherwise the request will wait till timeout (20 seconds).

 

Run client that periodically sends requests to /servlet?complete=0. (I have
tested it with 10 parallel threads that run in a loop)

Then run another client that periodically sends requests to
/servlet?complete=1 (This client can use only a single thread)

See that the first client does not receive any responses while the second
client is running.

 

 

public class WebTestServlet extends HttpServlet {

    private static final Logger LOG =
LoggerFactory.getLogger(WebTestServlet.class);

 

    @Override

    protected void service(final HttpServletRequest req, final
HttpServletResponse resp) throws ServletException, IOException {

        LOG.debug("Received request: {}", req);

        final long startTime = System.currentTimeMillis();

        String isComplete = req.getParameter("complete");

 

        AsyncContext asyncContext = req.startAsync(req, resp);

        asyncContext.setTimeout(20000);

        asyncContext.addListener(new AsyncListener() {

            public void onTimeout(AsyncEvent event) throws IOException {

                long duration = System.currentTimeMillis() - startTime;

                LOG.debug("Async Timeout. Request: {}. Waiting time: {}",
event.getSuppliedRequest(), duration);

                event.getAsyncContext().complete();

            }

 

            public void onStartAsync(AsyncEvent event) throws IOException {

                LOG.debug("Start async. Request: {}",
event.getSuppliedRequest());

            }

 

            public void onError(AsyncEvent event) throws IOException {

                LOG.debug("Error occured. Request: {}. Error: {}",
event.getSuppliedRequest(), event.getThrowable());

            }

 

            public void onComplete(AsyncEvent event) throws IOException {

                long duration = System.currentTimeMillis() - startTime;

                LOG.debug("Async Complete. Request: {}. Request process
time: {}", event.getSuppliedRequest(), duration);

            }

        }, req, resp);

 

        if ("1".equals(isComplete)) {

            try {

                Thread.sleep(500);

            } catch (Exception e) {

            }

 

            asyncContext.complete();

        }

    }

}

 

Regards,

Slava

 

 

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to