Django दूर भविष्य में कार्य (संभवतः) चलाते हैं


9

मान लीजिए मेरे पास एक मॉडल है Event। मैं इस घटना के समाप्त होने के बाद सभी आमंत्रित उपयोगकर्ताओं को एक अधिसूचना (ईमेल, धक्का, जो कुछ भी) भेजना चाहता हूं। की तर्ज पर कुछ:

class Event(models.Model):
    start = models.DateTimeField(...)
    end = models.DateTimeField(...)
    invited = models.ManyToManyField(model=User)

    def onEventElapsed(self):
        for user in self.invited:
           my_notification_backend.sendMessage(target=user, message="Event has elapsed")

अब, निश्चित रूप से, महत्वपूर्ण हिस्सा onEventElapsedजब भी आह्वान करना है timezone.now() >= event.end। ध्यान रखें, endवर्तमान तिथि से कुछ महीने दूर हो सकते हैं।

मैंने ऐसा करने के दो मूल तरीकों के बारे में सोचा है:

  1. एक आवधिक cronनौकरी का उपयोग करें (कहते हैं, हर पांच मिनट या तो) जो यह जांचता है कि क्या पिछले पांच मिनट के भीतर कोई भी घटना हुई है और इस पद्धति को निष्पादित करता है।

  2. भविष्य में (मॉडल विधि के भीतर ) पैरामीटर का उपयोग करके उपयोग करें celeryऔर शेड्यूल करें ।onEventElapsedetasave

विकल्प 1 को देखते हुए, एक संभावित समाधान हो सकता है django-celery-beat। हालाँकि, सूचनाएं भेजने के लिए एक निश्चित अंतराल पर किसी कार्य को चलाना थोड़ा अजीब लगता है। इसके अलावा मैं एक (संभावित) मुद्दे के साथ आया था जो (शायद) एक बहुत ही सुंदर समाधान में परिणाम देगा:

  • पिछले पाँच मिनट में हुई घटनाओं के लिए हर पाँच मिनट की जाँच करें? भद्दा लगता है, हो सकता है कि कुछ घटनाएँ याद आती हों (या अन्य लोग अपनी सूचनाएँ दो बार भेजते हों?)। संभावित कार्यपटु: एक बूलियन फ़ील्ड को उस मॉडल में जोड़ें जो एक Trueबार सूचनाओं को भेजे जाने के लिए सेट है ।

फिर, विकल्प 2 में भी इसकी समस्याएं हैं:

  • जब कोई ईवेंट प्रारंभ / समाप्ति डेटटाइम ले जाया जाता है, तो मैन्युअल रूप से स्थिति का ध्यान रखें। उपयोग करते समय celery, किसी को taskID(आसान, inc) को संग्रहीत करना होगा और तिथियों को बदलने और नया कार्य जारी करने के बाद कार्य को रद्द करना होगा। लेकिन मैंने पढ़ा है, कि भविष्य में चलने वाले कार्यों से निपटने के दौरान अजवाइन की (डिज़ाइन-विशिष्ट) समस्याएं होती हैं: मिथुन पर ओपन इश्यू । मुझे एहसास है कि यह कैसे होता है और क्यों यह सब कुछ है लेकिन हल करने के लिए तुच्छ है।

अब, मैं कुछ पुस्तकालयों में आया हूँ जो संभवतः मेरी समस्या को हल कर सकते हैं:

  • celery_longterm_scheduler (लेकिन इसका मतलब यह है कि मैं अजवाइन का उपयोग नहीं कर सकता जैसा कि मैंने पहले किया था, अलग-अलग शेड्यूलर वर्ग के कारण? यह भी संभव उपयोग में शामिल होता है django-celery-beat... दोनों में से किसी भी फ्रेमवर्क का उपयोग करना, यह अभी भी नौकरियों को कतारबद्ध करने के लिए संभव है। अभी थोड़े लंबे समय से चल रहे हैं लेकिन महीनों दूर नहीं हैं? '
  • django-apscheduler , उपयोग करता है apscheduler। हालाँकि, मुझे इस बारे में कोई जानकारी नहीं मिल पा रही थी कि यह उन कार्यों को कैसे प्रबंधित करेगा जो सुदूर भविष्य में चलाए जाते हैं।

क्या जिस तरह से मैं यह आ रहा हूं, क्या कोई मौलिक दोष है? आप किसी भी इनपुट के लिए खुश हैं।

सूचना: मुझे पता है कि यह कुछ हद तक राय आधारित होने की संभावना है, हालांकि, शायद एक बहुत ही बुनियादी चीज है जो मुझे याद आती है, भले ही कुछ को बदसूरत या सुरुचिपूर्ण माना जा सकता है।


1
मैं कहूंगा कि आपका दृष्टिकोण इस बात पर निर्भर करता है कि अंतिम घटना के तुरंत बाद अंतिम उपयोगकर्ता को अधिसूचना की आवश्यकता है। मुझे इसी तरह की समस्या हुई है जिसमें उपयोगकर्ता को केवल किसी भी नियुक्ति के लिए अगले दिन जानने की जरूरत थी, पिछले दिन याद किया। इसलिए इस मामले में मैंने आधी रात को क्रोन की नौकरी की, और जैसा कि आपने सुझाव दिया था, एक बूलियन फ़ील्ड को टैग करने के लिए कि क्या सूचनाएं भेजी गई थीं। यह एक बहुत ही सरल और कम्प्यूटेशनल रूप से सस्ता तरीका था।
हेडन ईस्टवुड

1
मेरी राय में, इसका उत्तर यह है कि आपको कितनी घटनाओं को भेजने की आवश्यकता है। यदि आपके पास हर दिन सैकड़ों ईवेंट भेजे जाने हैं, तो इससे कोई फर्क नहीं पड़ता कि भविष्य में कितनी दूर तक एक ही घटना है: पहले समाधान का उपयोग करना (अपनी आवश्यकताओं के आधार पर पुनरावृत्ति समय को कम करना) आप अपडेट किए गए डेटा को पढ़ने वाले कार्य को चला सकते हैं।
डॉस

@HaydenEastwood यह महत्वपूर्ण नहीं है कि व्यक्ति इसे तुरंत सुनाता है, लेकिन अंतिम तिथि के भीतर 2-5 मिनट के भीतर ठीक होना चाहिए। तो आपने मेरे ओपिनियन 1 के समान कुछ किया?
हफ्नर्नस

1
@ हेफर्नसुस हां - मुझे लगता है कि एक साधारण क्रोन कॉल डेटाबेस में एक क्षेत्र के लिए है कि क्या संदेश भेजा गया था जो आपके मामले के लिए एक अच्छा फिट होगा।
हेडन ईस्टवुड

1
Dramatiq सेलेरी की तुलना में एक अन्य aproach का उपयोग करें जब शेड्यूलिंग कार्य (कार्यकर्ता पर भूख नहीं है) और आपके मामले में काम कर सकता है, तो नाटकीयता देखें ।io/guide.html#scheduling-messages । लेकिन जैसा कि वे कहते हैं - संदेश ब्रोकर डीबी नहीं है - जब आपको दीर्घकालिक घटना की योजना की आवश्यकता होती है तो आपका पहला समाधान बेहतर होता है। तो आप दोनों को जोड़ सकते हैं: एमबी में घटनाओं को डाल सकते हैं, 1 दिन तक कह सकते हैं, और समाप्ति के समय वे डीबी में चले जाएंगे और क्रोन के माध्यम से भेजा जाएगा।
ठंढा- nzcr4

जवाबों:


2

हम कंपनी में कुछ इस तरह से काम कर रहे हैं, और समाधान काफी सरल है।

यदि कोई नोटिफिकेशन भेजने की आवश्यकता हो तो एक क्रोन / अजवाइन को हर घंटे चलाएं। फिर उन सूचनाओं को भेजें और उन्हें चिह्नित करें। इस तरह, भले ही आपकी अधिसूचना का समय आगे हो, यह अभी भी भेजा जाएगा। ईटीए का उपयोग करना बहुत लंबे समय तक प्रतीक्षा करने का तरीका नहीं है, आपके कैश / एमक्यूपी डेटा को ढीला कर सकते हैं।

आप अपनी आवश्यकताओं के आधार पर अपने अंतराल को कम कर सकते हैं, लेकिन सुनिश्चित करें कि वे ओवरलैप न हों।

यदि एक घंटे का समय अंतर बहुत बड़ा है, तो आप क्या कर सकते हैं, हर घंटे एक अनुसूचक चलाएं। लॉजिक कुछ इस तरह होगा

  1. एक कार्य चलाएं (इस शेड्यूलर कार्य को कॉल करने की सुविधा देता है) जो प्रति घंटा सभी सूचनाएं प्राप्त करता है जिसे अगले घंटे (सेलेरी बीट के माध्यम से) भेजने की आवश्यकता होती है -
  2. Apply_async (eta) के माध्यम से उन सूचनाओं को शेड्यूल करें - यह वास्तविक भेजना होगा

उस पद्धति का उपयोग करने से आपको सर्वश्रेष्ठ दुनिया (एटा और बीट) दोनों मिलेंगे


1
धन्यवाद। ठीक यही मैंने किया है!
Hafnernuss
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.