4

I have been trying to use the timeout feature of the async context. But the behavior is highly intermittent. Sometimes the timeout happens, and many a times it doesn't. I am pasting my code here.

@WebServlet(name = "TestServlet", urlPatterns = {"/test"},asyncSupported = true)
public class TestServlet extends HttpServlet{

private static final long serialVersionUID = 1L;

private static PriorityBlockingQueue<Runnable> pq = new PriorityBlockingQueue<Runnable>(1000);

private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,1,10, TimeUnit.SECONDS,pq);

public void service(final ServletRequest servletRequest, final ServletResponse response)
    throws ServletException, IOException {
    TestListener listener = new TestListener();
    final AsyncContext asyncContext = servletRequest.startAsync();
    asyncContext.addListener(listener);
    asyncContext.setTimeout(100);
    Handler handler = new Handler(asyncContext);
    threadPoolExecutor.execute(handler);
}
}

The listener and the handler code is included below.

public class TestListener implements AsyncListener {
public void onComplete(AsyncEvent event) throws IOException {
    System.out.println("Event completed");
}

public void onError(AsyncEvent event) throws IOException {
    event.getAsyncContext().complete();
}

public void onStartAsync(AsyncEvent event) throws IOException {
    // TODO Auto-generated method stub
}



public void onTimeout(AsyncEvent event){
    System.out.println("Timeout ");
    event.getAsyncContext().complete();
}
}

public class Handler implements Runnable {

private AsyncContext asyncContext;

public Handler(AsyncContext asyncContext){
    this.asyncContext = asyncContext;
}
public void run(){
    try {
        long currtime = System.currentTimeMillis();
        Thread.sleep(500);
        System.out.println("slept for " + (System.currentTimeMillis() - currtime));
    } catch (InterruptedException e) {
        System.out.println("Error in thread ");
    }

    try{
        if(asyncContext != null){
            System.out.println("Completing async context " + " timeout is " + asyncContext.getTimeout());
            asyncContext.complete();
        }
    }catch (Exception e){
        System.out.println("Exception in completing async context ");
    }
}
}

And the output is intermittent. Including the same here -

[ops@root combinedlogs]$ time curl "http://localhost:9001/mockresponse/test"

real    0m0.506s
user    0m0.001s
sys 0m0.003s
[ops@root combinedlogs]$ time curl "http://localhost:9001/mockresponse/test"

real    0m0.159s
user    0m0.001s
sys 0m0.003s

Catalina logs -

slept for 500
Completing async context  timeout is 100
Event completed

Timeout 
Event completed
slept for 500
Exception in completing async context

I don't understand why this is happening. Please help! Thanks for your time.

PS: The tomcat version is 7.0.37

4

1 回答 1

0

尝试将超时和睡眠间隔增加到 1 秒以上。
例如:尝试 2 秒的超时间隔和 5 秒的睡眠。
servlet 容器可能不会始终检测到少于 1 秒的超时。
早先在 tomcat 中有几个与这种亚秒级超时相关的错误(勉强),比如这个
我知道您使用的是比该错误中提到的更高版本的 tomcat,仍然值得一试。

于 2013-05-14T00:39:42.707 回答