2013-05-13 1 views
4

Я пытался использовать тайм-аут асинхронного контекста. Но поведение очень прерывисто. Иногда происходит тайм-аут, и много раз он этого не делает. Я вставляю свой код здесь.Async контекст не тайм-аут

@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); 
} 
} 

Код слушателя и код обработчика приведен ниже.

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 "); 
    } 
} 
} 

И выход прерывистый. В том числе здесь же -

[[email protected]root combinedlogs]$ time curl "http://localhost:9001/mockresponse/test" 

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

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

Каталина журналы -

slept for 500 
Completing async context timeout is 100 
Event completed 

Timeout 
Event completed 
slept for 500 
Exception in completing async context 

Я не понимаю, почему это происходит. Пожалуйста помоги! Спасибо за ваше время.

PS: версия является кот 7.0.37

ответ

0

Попробуйте увеличить время ожидания и интервал ожидания более чем на 1 сек.
Например: Попробуйте интервал времени ожидания 2 секунды и сон на 5 секунд.
Возможно, контейнер сервлета не обнаруживает тайм-ауты менее 1 секунды.
Были пара ошибок (незначительно), связанных с такими подсекундными таймаутами ранее в tomcat, например this one.
Насколько я понимаю, вы используете более позднюю версию tomcat, чем упоминалось в этой ошибке, но все же стоит попробовать.

+0

Благодарим вас за ответ! Более высокий тайм-аут и значение сна гарантируют тайм-аут в каждом случае. Я тоже проверил это раньше! Но для меня это не служит, когда для меня может быть время от 100 до 10000 миллисов. Я тоже ошибся в этом, и поэтому решил использовать последнюю версию tomcat. Во всяком случае, я не думаю, что могу использовать тайм-аут контекста, я скорее должен использовать поток таймера или HashWheeledTimer. Благодаря! –

Смежные вопросы