2011-05-28 9 views
10

एसिंक्रोनस प्रसंस्करण करने के लिए मान लीजिए कि मैं इस तरह एक सरल नियंत्रक करते हैं:सुझाव Grails

class FooController { 

    def index = { 
    someVeryLongCompution() //e.g crawl a set of web pages 
    render "Long computation was launched." 
    } 
} 

जब सूचकांक कार्रवाई शुरू हो जाती है, मैं विधि उपयोगकर्ता के लिए तुरंत वापस करना चाहते जबकि चल रहा है असीमित रूप से लंबी गणना।

मैं समझता हूं कि ऐसा करने का सबसे मजबूत तरीका वास्तुकला में एक संदेश दलाल का उपयोग करना होगा, लेकिन मैं सोच रहा था कि ऐसा करने का एक आसान तरीका है या नहीं।

मैंने निष्पादक प्लगइन की कोशिश की लेकिन यह लंबे समय तक गणना के बाद http अनुरोध को लौटने से रोकता है।

मैं क्वार्ट्ज प्लगइन की कोशिश की, लेकिन वह

कैसे तुम लोगों Grails में इस तरह के अनुरोध संभाल रहे हैं (जब तक वहाँ सिर्फ एक बार एक काम चलाने के लिए? एक तरीका है) समय-समय पर कार्यों के लिए अच्छा हो रहा है?

+1

निष्पादक प्लगइन को http अनुरोध को अवरुद्ध नहीं करना चाहिए और यह मेरे लिए अपेक्षित काम करता है, मैं सुझाव दूंगा कि आप इसे एक और देखें। – wwwclaes

उत्तर

3

यदि आप Grails क्वार्ट्ज में एक साधारण ट्रिगर का उपयोग करते हैं और दोहराना सेट 0 पर सेट करते हैं, तो नौकरी केवल एक बार चलती है। यह उपयोगकर्ता अनुरोधों से अलग है, हालांकि, इसे पूरा होने पर उपयोगकर्ता को संवाद करने के लिए आपको कुछ रास्ता समझना होगा।

0

इस प्रकार की समस्या का सबसे अच्छा समाधान JMS plugin के माध्यम से जेएमएस का उपयोग करना है।

एक सरल कार्यान्वयन के लिए, किसी बाहरी सर्वर/सेवा की आवश्यकता नहीं है, तो आप Spring Events प्लगइन को आजमा सकते हैं।

5

आप एक ही Grails सर्वर, या एक अलग सर्वर पर veryLongComputation() को संसाधित करना चाहते हैं?

यदि वही सर्वर है, तो आपको जेएमएस की आवश्यकता नहीं है, दूसरा विकल्प केवल एक नया धागा बनाना है और गणना को अतुल्यकालिक रूप से संसाधित करना है।

def index = { 
    def asyncProcess = new Thread({ 
      someVeryLongComputation() 
    } as Runnable) 
    asyncProcess.start() 

    render "Long computation was launched." 
    } 
+0

एक्जिक्यूटर्स प्लगइन का उपयोग करना बेहतर है, खासकर जब यह पृष्ठभूमि थ्रेड पर हाइबरनेट सत्र संलग्न करेगा। –

+1

@ पीटर मैं निष्पादक प्लगइन के सत्र एकीकरण से अवगत हूं, लेकिन ओपी ने हाइबरनेट का कोई उल्लेख नहीं किया है, इसलिए यदि आपको इसकी आवश्यकता नहीं है तो आवश्यक ओवरहेड जोड़ने का कोई कारण नहीं है। – raffian

+0

मेरा कहना था "अनावश्यक 'ओवरहेड जोड़ने का कोई कारण नहीं है, – raffian

1

Spring events plugin प्रयास करें - यह अतुल्यकालिक घटना श्रोताओं का समर्थन करता है।

3

मुझे पता है कि यह एक बहुत पुराना सवाल है, बस एक अद्यतन उत्तर देना चाहता था।

grails 2.3 के बाद से, ढांचा सर्वलेट 3.0 async निपटने अनुरोध का उपयोग async कॉल का समर्थन करता है (बेशक, एक सर्वलेट 3.0 कंटेनर इस्तेमाल किया जाना चाहिए और सर्वलेट संस्करण विन्यास है, जो यह डिफ़ॉल्ट प्रति है में 3.0 होना चाहिए)

यह यहाँ प्रलेखित है: http://grails.org/doc/latest/guide/async.html

सामान्य में, वहाँ प्राप्त करने के लिए आप क्या पूछा दो तरीके हैं:

import static grails.async.Promises.* 
    def index() { 
     tasks books: Book.async.list(), 
      totalBooks: Book.async.count(), 
      otherValue: { 
       // do hard work 
      } 
    } 

या सर्वलेट Async रास्ता:

def index() { 
    def ctx = startAsync() 
    ctx.start { 
     new Book(title:"The Stand").save() 
     render template:"books", model:[books:Book.list()] 
     ctx.complete() 
    } 
} 

छोटा नोट - grails विधि वादे का उपयोग कर रहा है, जो एक प्रमुख (async) आगे बढ़ता है। किसी भी वादे को आगे वादा करने के लिए जंजीर किया जा सकता है, सफलता और कॉल आदि पर कॉलबैक है।

1

यदि आप क्वार्ट्ज प्लगइन (जैसा कि हम हमेशा करते हैं) का उपयोग करना चाहते हैं, तो आप इसे ऐसा कर सकते हैं।यह हमारे लिए अच्छी तरह से काम करता है:

एक नौकरी परिभाषा (कोई समय चलाता साथ)

static triggers = { 
    simple name:'simpleTrigger', startDelay:0, repeatInterval: 0, repeatCount: 0 
} 

कॉल < काम > .triggerNow() मैन्युअल अतुल्यकालिक मोड में काम निष्पादित करने के लिए ।

MyJob.triggerNow([key1:value1, key2: value2]); 

प्रो टिप # 1

बाहर दूसरी तरफ नाम वाले पैरामीटर प्राप्त करने के लिए ...

def execute(context) { 
    def value1 = context.mergedJobDataMap.get('key1'); 
    def value2 = context.mergedJobDataMap.get('key2'); 
    ... 
    if (value1 && value2) { 
     // This was called by triggerNow(). We know this because we received the parameters. 
    } else { 
     // This was called when the application started up. There are no parameters. 
    } 
} 

प्रो टिप # 2

विधि पर अमल हमेशा जैसे ही एप्लिकेशन शुरू होता है, उसे कॉल किया जाता है, लेकिन नामित पैरामीटर शून्य के रूप में आते हैं।

प्रलेखन: http://grails.org/version/Quartz%20plugin/24#Dynamic%20Jobs%20Scheduling

0

Grails 2.2.1 समाधान मैं एक अतिरिक्त आवश्यकता है कि ने कहा कि रिपोर्ट ऑटो पड़ा एक विंडो पॉप जब यह पूरा हो गया था। तो मैंने मोड़ के साथ ऊपर से सर्वलेट रास्ता चुना। मैंने एक जेसन स्वरूपित स्ट्रिंग रिटर्न के साथ एक दृश्य प्रस्तुत करने की जगह इसे बदल दिया। साथ ही मेरे मुवक्किल की ओर नहीं एक जीएसपी देखने के लिए, यह ExtJS 4.1.1 (एक एचटीएमएल 5 उत्पाद)

enter code here 
def index() { 
    def ctx = startAsync() 
    ctx.start ({ 

     Map retVar = [reportId: reportId, success: success]; 
     String jsonString = retVar as JSON; 

     log.info("generateTwoDateParamReport before the render out String is: " + jsonString); 

     ctx.getOriginalWebRequest().getCurrentResponse().setContentType("text/html"); 
     ctx.getOriginalWebRequest().getCurrentResponse().setCharacterEncoding("UTF-8"); 
     log.info("current contentType is: "ctx.getOriginalWebRequest().getCurrentResponse().contentType); 
     try { 
      ctx.getOriginalWebRequest().getCurrentResponse().getWriter().write(jsonString); 
      ctx.getOriginalWebRequest().getCurrentResponse().getWriter().flush(); 
      ctx.getOriginalWebRequest().getCurrentResponse().setStatus(HttpServletResponse.SC_OK); 
     } 
     catch (IOException ioe) 
     { 
      log.error("generateTwoDateParamReport flush data to client failed."); 
     } 
     ctx.complete(); 
     log.info("generateNoUserParamsReport after complete"); 
    }); 
} 
+0

स्टैक ओवरव्लो पर एक प्रश्न का उत्तर देने के लिए धन्यवाद। ऐसा प्रतीत नहीं होता है कि उपरोक्त आपका कोड या टिप्पणियां इस सवाल को हल करने की कोशिश करती हैं कि कितनी लंबी गणना को अतुल्यकालिक रूप से कैसे किया जाए। क्या आप इसे संपादित कर सकते हैं ताकि यह उस पर केंद्रित हो? – spikeheap

+0

कोड अब और अधिक पूर्ण है मैंने पहले के ऊपर एक समाधान का संदर्भ दिया। मुझे लगता है मुझे ऐसा नहीं करना चाहिए। यह कोड एक grails नियंत्रक कार्रवाई दिखाता है, और उत्पादन में चल रहा है। –

2

आप की कोशिश की Grails Promisses एपीआई है क्या है? यह

import static grails.async.Promise 
import static grails.async.Promises 

class FooController { 

    def index = { 
    Promise p = Promises.task { 
     someVeryLongCompution() //e.g crawl a set of web pages 
    } 
    render "Long computation was launched." 
    } 
}