2012-06-18 31 views
10

मेरे पास जेटी सर्वर लंबे समय से चल रहे HTTP अनुरोधों को संभालने वाला है- प्रतिक्रियाएं एक अलग प्रक्रिया एक्स द्वारा उत्पन्न होती हैं और एक कलेक्टर हैश में समाप्त होता है जो जेटी समय-समय पर जांच करता है।जेट्टी अपवाद को कैसे संभालना है - एक लंबे समय तक चलने वाला HTTP अनुरोध समय समाप्त हो गया है, लेकिन जिस प्रक्रिया को कॉल किया जाता है वह कभी समाप्त नहीं होता है और जेटी नाखुश है

3 मामलों के होते हैं:

  1. प्रक्रिया एक्स HTTP अनुरोध का समय समाप्त अवधि से पहले खत्म - कोई समस्या नहीं
  2. प्रक्रिया एक्स अनुरोध के समय समाप्ति की अवधि के बाद खत्म - कोई समस्या
  3. प्रक्रिया एक्स कभी खत्म नहीं होता है - नीचे अपवाद होता है

मैं इस स्थिति (3) का पता कैसे लगा सकता हूं और अपवाद को रोक सकता हूं अन्य दो मामलों को ठीक से काम करने की इजाजत दी?

अपवाद:

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) 


जेट्टी एक HTTP अनुरोध की निरंतरता:

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{ 
     ctx.complete() 
    } catch (IllegalStateException e){ 
     //Handle it the way you prefer. 
    } 
2

यहां समस्या AsyncContext # पूर्ण() के कोड की नहीं है बल्कि कोड का ओवरल डिज़ाइन है।

निरंतरता (सर्वलेट एसिंक के लिए एक ही चीज़) असीमित होने के लिए डिज़ाइन की गई है। जबकि लूप जो आंतरिक निरंतरता टाइमआउट का उपयोग करता है, यहां नहीं होना चाहिए। आप ऐसा करके एक सिंक्रोनस डिज़ाइन को एक सिंक्रोनस में बदल रहे हैं। करने के लिए सही बात यह है कि निरंतरता # addContinuationListener() का उपयोग करके श्रोता को पंजीकृत करना और टाइमआउट केस को उचित रूप से संसाधित करने के लिए टाइमआउट() विधि पर लागू करना है।

एक बार आपका टाइमआउट तर्क समाप्त हो जाने के बाद, मैं प्रक्रिया एक्स तर्क को कक्षा AsyncHTTPRequestProcessor में स्थानांतरित करने और कलेक्टर का उपयोग करने की आवश्यकता से बाहर निकलने की अनुशंसा करता हूं। प्रसंस्करण के दौरान, आपको यह मानना ​​चाहिए कि वर्तमान धागा का समय कभी समाप्त नहीं होगा। ऐसा करने से आपका कॉल पूरा करने के लिए() इन्स बनाता है और आप कलेक्टर पर समवर्ती परेशानी के प्रति प्रतिरोधी होंगे।