2009-12-19 14 views
21

मेरे आवेदन के लिए मैं नौकरियां बनाता हूं और उन्हें क्रोनट्रिगर्स के साथ शेड्यूल करता हूं। प्रत्येक नौकरी में केवल एक ट्रिगर होता है और दोनों नौकरी का नाम और ट्रिगर नाम समान होते हैं। कोई नौकरियां ट्रिगर साझा नहीं करती हैं।क्वार्ट्ज जावा एक नौकरी फिर से शुरू करने से कई बार

अब जब मैं इस "0/1 * * * *" जैसे क्रॉन ट्रिगर बनाता हूं? जो हर सेकेंड को निष्पादित करने के लिए नौकरी निर्देशित करता है, यह ठीक काम करता है।

समस्या बढ़ जाता है जब मैं पहली बार फोन करके काम को थामने:

scheduler.pauseJob(jobName, jobGroup); 

और उसके बाद काम शुरू करने के बाद के साथ 50 सेकंड का कहना है:

scheduler.resumeJob(jobName, jobGroup); 

क्या मैं देख रहा है कि ये 50 के लिए अनुरोध के रूप में नौकरी निष्पादित नहीं की गई सेकंड्स। लेकिन जिस क्षण मैं नौकरी फिर से शुरू करता हूं, मुझे एक ही समय में नौकरी के 50 निष्पादन दिखाई देता है !!!

मैंने सोचा था कि इस इंजन चालू न होना शिक्षा के लिए डिफ़ॉल्ट सेटिंग की वजह से लेकिन फिर भी यह करने के लिए निर्माण पर ट्रिगर के इंजन चालू न होना Instruciton सेट करने के बाद किया गया था:

trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING); 

एक ही बात होता है। क्या कोई इसे ठीक करने का तरीका सुझा सकता है?

उत्तर

27

CronTriggernextFireTime को याद करके काम करता है। ट्रिगर बनाने के बाद nextFireTime प्रारंभ किया गया है। जब भी नौकरी ट्रिगर की जाती है nextFireTime अद्यतन किया जाता है। चूंकि nextFireTime रोके जाने पर नौकरी ट्रिगर नहीं होती है, इसलिए "पुरानी" बनी हुई है। तो जब आप नौकरी फिर से शुरू करेंगे तो ट्रिगर हर पुराने ट्रिगर समय को वापस कर देगा।

समस्या यह है कि ट्रिगर को यह नहीं पता कि इसे रोका जा रहा है। इसे दूर करने के लिए यह मिस्फीयर हैंडलिंग है। नौकरियों को फिर से शुरू करने के बाद ट्रिगर की updateAfterMisfire() विधि लागू की जाएगी जो nextFireTime को सुधारती है। लेकिन अगर nextFireTime के बीच का अंतर और अब misfireThreshold से छोटा है। फिर विधि कभी नहीं कहा जाता है। यह थ्रेसहोल्ड का डिफ़ॉल्ट मान 60,000 है। इस प्रकार यदि आपकी रोकथाम अवधि 60 से अधिक हो जाएगी तो सबकुछ ठीक होगा।

चूंकि आपको समस्याएं हैं, मुझे लगता है कि यह नहीं है। ;) इस समाधान करने के लिए आप सीमा को संशोधित करने या CronTrigger चारों ओर एक सरल आवरण का उपयोग कर सकते हैं:

public class PauseAwareCronTrigger extends CronTrigger { 
    // constructors you need go here 

    @Override 
    public Date getNextFireTime() { 
     Date nextFireTime = super.getNextFireTime(); 
     if (nextFireTime.getTime() < System.currentTimeMillis()) { 
      // next fire time after now 
      nextFireTime = super.getFireTimeAfter(null); 
      super.setNextFireTime(nextFireTime); 
     } 
     return nextFireTime; 
    } 
} 
+4

आपको बहुत बहुत धन्यवाद :) यह एक आकर्षण की तरह काम करता है। ऐसा लगता है कि नौकरी को रोकने के लिए इतना आसान काम इस तरह की समस्याएं पैदा करेगा। –

5

यदि आप नौकरी रोकते हैं, तो ट्रिगर आग जारी रहेगा, लेकिन जब तक नौकरी फिर से शुरू नहीं हो जाती तब तक निष्पादन कतारबद्ध हो जाएंगे। यह एक मिस्फायरिंग ट्रिगर नहीं है, जिससे सेटिंग का कोई असर नहीं पड़ेगा।

मैं क्या करना चाहता हूं, मुझे लगता है कि, नौकरी को रोकने के बजाए प्रोग्रामेटिक रूप से क्रॉन ट्रिगर को अक्षम या हटा दिया गया है। जब आप फिर से शुरू करना चाहते हैं, तो ट्रिगर को फिर से जोड़ें।

+0

पॉज़जोब विधि के लिए जावाडोक कहता है "दिए गए नाम के साथ जॉबडब्लैंट को रोकें - अपने सभी मौजूदा ट्रिगर्स को रोककर।" तो मुझे लगता है कि ट्रिगर को रोक दिया जा रहा है। ट्रिगर पर भी कोई विराम विधि नहीं है। या जो कुछ भी दिखता है। क्या नौकरी से ट्रिगर को हटा रहा है और इसे नौकरी रोकने के लिए मेरा एकमात्र विकल्प दोबारा जोड़ रहा है? मेरा मतलब है कि यह आपके शेड्यूलर को करना चाहता है यह एक बहुत ही छोटी बात है। यह कैसे काम नहीं करता है? –

+0

हम्म, अच्छा बिंदु। मुझे लगता है कि क्वार्ट्ज के साथ, कुछ काम करने तक विभिन्न चीजों की कोशिश करना सबसे अधिक उत्पादक दृष्टिकोण है, क्योंकि यह हमेशा टिन पर जो भी कहता है वह हमेशा नहीं करता है। – skaffman

+0

यह बेहद निराशाजनक है क्योंकि नौकरी से ट्रिगर को हटाने का कोई आसान तरीका भी नहीं है। क्या मेरे पास ट्रिगर-कम नौकरी हो सकती है? और यदि हां, तो कैसे? कोई विचार? मैं इसके साथ अपना धैर्य खोना शुरू कर रहा हूं, मैं घंटों तक कोशिश कर रहा हूं :) –

1

1.6.5 के बाद से कम से कम (अपनी उंगलियों पर क्वार्ट्ज) के जल्द से जल्द संस्करण, अनुसूचक एक pauseTrigger विधि है पैरामीटर के रूप में नाम/समूह लेता है। इसका मतलब है कि आपके पास उपयोग किए जाने वाले प्रत्येक ट्रिगर प्रकार का उप-वर्ग नहीं है, न ही आपको फंकी हटाना/सम्मिलन चाल करना है।

ये दोनों मेरे लिए महत्वपूर्ण हैं क्योंकि 1) हमारे डेटाबेस में सख्त नो-डिलीट नीति है और 2) कस्टम डेटास्टोर मैं उपयोग करता हूं ट्रिगर उप-वर्गों का समर्थन नहीं करता है।