2012-06-18 5 views
10

장기 실행 HTTP 요청을 처리하는 부두 서버가 있습니다. 응답은 다른 프로세스 X 및 Jetty가 주기적으로 요청하는 수집기 해시로 끝납니다.Jetty 예외 처리 방법 - 장기 실행 HTTP 요청은 시간이 초과되지만 호출 프로세스는 종료되지 않고 Jetty는 불만입니다.

3 경우가 있습니다 : X는 HTTP 요청의 제한 시간 전에 완료되지

  1. 프로세스 -
  2. 프로세스 X가 요청의 제한 시간 후 종료 문제 - 아니 문제
  3. 에게 프로세스 X가 완료되지 않음 - 예외가 발생했습니다.

이 상황을 감지하고 (3) 어떻게 예외를 방지합니까? 다른 두 가지 사례가 제대로 작동하도록 할 수 있습니까?

예외 : HTTP 요청의

2012-06-18 00:13:31.055:WARN:oejut.QueuedThreadPool: 
java.lang.IllegalStateException: IDLE,initial 
   at org.eclipse.jetty.server.AsyncContinuation.complete(AsyncContinuation.java:569) 
   at server.AsyncHTTPRequestProcessor.run(AsyncHTTPRequestProcessor.java:72) 
   at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1119) 
   at org.eclipse.jetty.server.AsyncContinuation$1.run(AsyncContinuation.java:875) 
   at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599) 
   at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534) 
   at java.lang.Thread.run(Thread.java:679) 


부두 계속은 :

public class AsyncHTTPRequestProcessor implements Runnable { 

    private ConcurrentHashMap<String, String> collector; 
    private Logger logger; 
    private AsyncContext ctx; 
    //Defined this here because of strange behaviour when running junit 
    //tests and the response json string being empty... 
    private String responseStr = null; 

    public AsyncHTTPRequestProcessor(AsyncContext _ctx, 
      ConcurrentHashMap<String, String> _collector, Logger _logger) { 
     ctx = _ctx; 
     collector = _collector; 
     logger = _logger; 
    } 

    @Override 
    public void run() { 

     logger.info("AsyncContinuation start"); 

     //if(!((AsyncContinuation)ctx).isInitial()){ 
     String rid = (String) ctx.getRequest().getAttribute("rid"); 
     int elapsed = 0; 
     if(rid !=null) 
     { 

      logger.info("AsyncContinuation rid="+rid); 

      while(elapsed<ctx.getTimeout()) 
      { 
       if(collector.containsKey(rid)){ 
        responseStr = collector.get(rid); 
        collector.remove(rid); 

        logger.info("--->API http request in collector:"+responseStr); 
        ctx.getRequest().setAttribute("status",200); 
        ctx.getRequest().setAttribute("response", responseStr); 
        ctx.getRequest().setAttribute("endTime",System.currentTimeMillis()); 
        //ctx.complete(); 
        break; 
       } 
       try { 
        Thread.sleep(10); 
        elapsed+=10; 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      //} 
      logger.info("Collector in async stuff:"); 
      for(String key:collector.keySet()){ 
       logger.info(key+"->"+collector.get(key)); 
      } 

      for(Entry<String, String> x:collector.entrySet()){ 
       logger.info(x.getKey()+"->"+x.getValue()); 
      } 
      ctx.complete(); <---- this line 72 
     } 
    } 

} 
+0

동일한 문제가 있습니다. 나는 그것을 해결하려고 노력하고있다. 곧 나는 할 수있는 한 대답을 할 것입니다. –

+1

프로세스가 완료되지 않으면 예외가 어떻게 발생합니까? –

답변

0

의 try catch 블록을 사용하면이 경우에 도움이 될 수 있습니다.

try{ 
     ctx.complete() 
    } catch (IllegalStateException e){ 
     //Handle it the way you prefer. 
    } 
2

여기서의 문제는 AsyncContext # complete() 호출이 아니라 코드의 지나친 디자인입니다.

계속 (서블릿 비동기와 동일)은 비동기으로 설계되었습니다. 내부 연속 시간 제한을 사용하는 while 루프는 여기에 있지 않아야합니다. 이렇게하면 비동기식 디자인을 동기식 디자인으로 변환 할 수 있습니다. 올바른 작업은 Continuation # addContinuationListener()를 사용하여 리스너를 등록하고 onTimeout() 메소드를 구현하여 시간 초과 사례를 적절하게 처리하는 것입니다.

일단 시간 초과 논리가 없으면 프로세스 X 논리를 AsyncHTTPRequestProcessor 클래스로 이동하고 수집기를 사용해야하는 필요성을 피하는 것이 좋습니다. 처리하는 동안 현재 스레드가 절대로 시간 초과되지 않는다고 가정해야합니다. 이렇게하면 complete()를 호출하면 감각이 생기고 콜렉터에서 동시 처리 문제가 발생하지 않게됩니다.