2012-06-18 23 views
10

Uzun süren HTTP isteklerini ele alan bir Jetty sunucum var - yanıtlar farklı bir işlem X tarafından oluşturulur ve Jetty'nin periyodik olarak kontrol etmesini istediği bir kollektör hashına dönüş.Jetty istisnası nasıl kullanılır - uzun süren bir HTTP isteği zaman aşımına uğrar, ancak aramaları hiçbir zaman sona ermez ve Jetty mutsuzdur

3 durum vardır: X, HTTP isteğinin zaman aşımı süresinden önce sona

  1. Süreci -
  2. Proses X isteğinin zaman aşımı süresinden sonra bitirir hiçbir sorunu - hayır problemi
  3. X işleminin hiç bitmemesi - aşağıdaki özel durum istisnasının altından oluşur.

Bu durumu nasıl algılayabilirim (3) ve özel durumu engeller. Diğer iki vakanın düzgün çalışmasına izin vermek?

İstisna: HTTP isteğinin

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) 


İskele devamı:

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

Aynı sorunu yaşıyorum. Çözmeyi deniyorum. Elimden geldiğince, bir cevap vereceğim. –

+1

İşlem hiç bitmezse, istisna nasıl olabilir? –

cevap

0

deneyin catch bloğu kullanarak bu durumda yardımcı olabilir.

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

Buradaki sorun AsyncContext komple #() ancak kod Kapsamlı tasarım aramanız değildir.

Devamlar (Servlet async için aynı şey), asenkron olarak tasarlanmıştır. Dahili sürekliliklerin zaman aşımını kullanan süre döngüsü burada olmamalıdır. Eşzamansız bir tasarımı, bunu yaparak eşzamanlı olarak dönüştürüyorsunuz. Yapılması gereken en doğru şey, devam eden # addContinuationListener() yöntemini kullanarak bir dinleyiciyi kaydettirmek ve zaman aşımı durumunu uygun şekilde işlemek için onTimeout() yöntemini uygulamaktır.

Zamanaşımı mantığınız bittiğinde, süreç X mantığını AsyncHTTPRequest İşlemcisi sınıfına taşımanızı ve bir kolektör kullanma ihtiyacından çıkmanızı öneririm. İşleme sırasında, geçerli iş parçacığının asla zaman aşımına uğramayacağını varsaymalısınız. Bunu yaparak, tamamlamanız için çağrı() yapar ve toplayıcıda eşzamanlılık sorununa bağışıklık kazanırsınız.