2011-08-24 12 views
5

मैंने पाया कि मैं here से विशिष्ट समय पर विशिष्ट अंतराल पर चलाने के लिए कार्य सेट कर सकता हूं, लेकिन यह केवल कार्य घोषणा के दौरान किया गया था। समय-समय पर गतिशील रूप से चलाने के लिए मैं एक कार्य कैसे निर्धारित करूं? उदाहरण आप तो आप नया बनाने के बाद एक्स सेकंड के लिए कुछ करना चाहते हैं चलाने के लिए Ddjango अजवाइन: विशिष्ट अंतराल पर चलाने के लिए कार्य को कैसे सेट करें

:

उत्तर

7

शेड्यूल derived from a setting है, और इस प्रकार रनटाइम पर अपरिवर्तनीय प्रतीत होता है।

आप शायद Task ETAs का उपयोग करके जो कुछ भी ढूंढ रहे हैं उसे पूरा कर सकते हैं। यह गारंटी देता है कि आपका कार्य से पहले वांछित समय से पहले नहीं चलाएगा, लेकिन निर्दिष्ट समय पर कार्य को चलाने का वादा नहीं करता है- यदि नामित ईटीए में श्रमिकों को अधिभारित किया जाता है, तो कार्य बाद में चलाया जा सकता है।

कि प्रतिबंध कोई मुद्दा नहीं है, तो आप एक काम है जो पहले की तरह ही चल पाएंगे लिख सकते हैं:

@task 
def mytask(): 
    keep_running = # Boolean, should the task keep running? 
    if keep_running: 
     run_again = # calculate when to run again 
     mytask.apply_async(eta=run_again) 
    # ... do the stuff you came here to do ... 

इस दृष्टिकोण का प्रमुख नकारात्मक पक्ष यह है कि आप कार्यों को याद करने के लिए taskstore पर भरोसा कर रहे हैं उड़ान में यदि उनमें से एक अगले को गोलीबारी करने से पहले विफल रहता है, तो कार्य फिर कभी नहीं चलेगा। यदि आपका ब्रोकर डिस्क पर नहीं रहता है और यह मर जाता है (इसके साथ सभी इन-फ्लाइट कार्यों को लेना), तो उनमें से कोई भी कार्य फिर से चलाएगा।

आप इन मुद्दों को किसी प्रकार के लेनदेन लॉगिंग और आवधिक "नानी" कार्य के साथ हल कर सकते हैं जिसका काम यह दोहराव वाले कार्यों को ढूंढना है जो एक असामयिक मौत की मृत्यु हो गई और उन्हें पुनर्जीवित कर दिया।

अगर मुझे आपके द्वारा वर्णित किए गए कार्यों को लागू करना पड़ा, तो मुझे लगता है कि मैं इस तरह से संपर्क करूंगा।

+3

हां, शेड्यूलर को गतिशील शेड्यूल के लिए अनुकूलित नहीं किया गया है, लेकिन आप ऊपर वर्णित अनुसार 'is_due' विधि के साथ अपनी' शेड्यूल 'को कार्यान्वित कर सकते हैं, कार्य को फिर से निर्धारित करने का विकल्प भी कई विकल्प है, लेकिन फिर आपको सुनिश्चित करें कि पहला कार्य हमेशा ट्रिगर होता है, जो इतना आसान नहीं है। एक अन्य विकल्प डेटाबेस शेड्यूलर का उपयोग django-celery में करना है, यह गतिशील शेड्यूल का समर्थन करता है, और इसका उपयोग Django परियोजनाओं के बाहर भी किया जा सकता है। इसके अलावा, अपने स्वयं के शेड्यूलर बनाना मुश्किल नहीं है। – asksol

+0

@asksol, django-celery के लिए दस्तावेज खाली है।डेटाबेस शेड्यूलर का उपयोग करने के तरीके पर मैं कहां से पता लगा सकता हूं? – goh

+1

@amateur ठीक है, प्रलेखन वास्तव में यहां दुर्लभ है: – asksol

0

यहाँ देख http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html

मुझे लगता है कि आप यह गतिशील नहीं कर सकते हैं ... सबसे अच्छा तरीका काम में कार्य बना है एक्स सेकंड विलंब के साथ कार्य करें और इस कार्य में एन * एक्स सेकंड देरी के लिए एक और कार्य बनाएं ...

1

celery.task.base.PeriodicTaskis_due परिभाषित करता है जो निर्धारित करता है कि अगला रन कब होना चाहिए। आप अपने कस्टम गतिशील चल रहे तर्क को शामिल करने के लिए इस फ़ंक्शन को ओवरराइड कर सकते हैं। यहाँ डॉक्स देखें: http://docs.celeryproject.org/en/latest/reference/celery.task.base.html?highlight=is_due#celery.task.base.PeriodicTask.is_due

एक उदाहरण:

import random 
from celery.task import PeriodicTask 

class MyTask(PeriodicTask): 

    def run(self, **kwargs): 
     logger = self.get_logger(**kwargs) 
     logger.info("Running my task") 

    def is_due(self, last_run_at): 
     # Add your logic for when to run. Mine is random 
     if random.random() < 0.5: 
      # Run now and ask again in a minute 
      return (True, 60) 
     else: 
      # Don't run now but run in 10 secs 
      return (True, 10) 
+0

क्या आप मुझे रनटाइम के दौरान ओवरराइड करने का उदाहरण दे सकते हैं? मुझे लगता है कि मैं इसका उपयोग नहीं कर सकता। डेले क्योंकि आवधिक टास्क क्लासेस – goh

+0

के लिए कोई रन नहीं है() आप कस्टम is_due विधि के साथ अपना खुद का शेड्यूल क्लास (celery.schedules.schedule) परिभाषित करते हैं। 'CELERYBEAT_SCHEDULE = {" मेरा नाम ": {" कार्य ":" myapp.mytask ", शेड्यूल": myschedule()}} ' – asksol

0

यह आपको मदद करनी चाहिए कुछ ... http://celery.readthedocs.org/en/latest/faq.html#can-i-change-the-interval-of-a-periodic-task-at-runtime

एक बार जब आप एक कस्टम अनुसूची परिभाषित किया है, यह आपके काम के लिए आवंटित के रूप में asksol है ऊपर सुझाया गया।

CELERYBEAT_SCHEDULE = {  
    "my_name": { 
     "task": "myapp.tasks.task", 
     "schedule": myschedule(),  
    } 
} 

तुम भी CELERYBEAT_MAX_LOOP_INTERVAL संशोधित करने के लिए यदि आप अपने कार्यक्रम को अधिक बार हर पाँच मिनट से अपडेट करना चाहते हैं चाहते हो सकता है।

संबंधित मुद्दे