2014-09-03 20 views
10

मैं इसअजवाइन और संकेत

def calculate(self, input): 
    result = input * 2 

    if result > 4: 
     result_higher_then_four.send(result) 

    return result 

कहाँ result_higher_then_four स्पष्ट रूप से एक संकेत का प्रतिनिधित्व करता है की तरह एक समारोह किया करते थे।

तब मैंने अजवाइन पेश किया और मेरा कार्य नीचे जैसा दिखता था और मुझे फिर कभी संकेत नहीं मिला। मुझे लगता है कि संकेत प्रति प्रक्रियाबद्ध हैं और जैसे ही अजवाइन एक अलग प्रक्रिया में चलता है, इसका मतलब है कि मैं मुख्य प्रक्रिया में संकेत नहीं पकड़ सकता। क्या मुझे इसे ठीक करने के लिए thread_local का उपयोग करना चाहिए? या मैं स्पष्ट दिख रहा हूँ?

धन्यवाद

@task 
def calculate(self, input): 
    result = input * 2 

    if result > 4: 
     result_higher_then_four.send(result) 

    return result 
+0

@ChillarAnand हाँ – user2298943

उत्तर

2

समस्या यह है कि सिग्नल रिसीवर पंजीकृत नहीं हो रहा है। अजवाइन श्रमिक अपनी प्रक्रिया में भागते हैं ताकि सिग्नल कनेक्शन को उस प्रक्रिया में बनाया जाना चाहिए। यदि आप जानते हैं कि वे क्या हैं या उन्हें खोज सकते हैं, तो आप उन्हें this technique का उपयोग करके कार्य प्रारंभिकरण के दौरान पंजीकृत कर सकते हैं।

बेशक, यह पहली जगह सिग्नल का उपयोग करने के कुछ लाभ को समाप्त करता है क्योंकि आपको पहले से कनेक्शन पता होना चाहिए।

एक विचार यह मानना ​​है कि सिग्नल रिसीवर हमेशा प्रत्येक ऐप के मॉडल मॉड्यूल में पंजीकृत होंगे। इस मामले में निम्नलिखित काम करेगा।

class CalculateTask(celery.Task): 

    def __init__(self): 
     from django.conf import settings 
     for app in settings.INSTALLED_APPS: 
      app_models = '{}.{}'.format(app,'models') 
      __import__(app_models, globals=globals())         

    def run(self, input): 
     result = input * 2 
     if result > 4: 
      result_higher_then_four.send(result) 

     return result 
0

अगर मैं सही ढंग से समझ में आ आप एक ही प्रक्रिया भेज ans संकेत इसे भेजा प्राप्त करना चाहते हैं? यदि ऐसा है तो क्यों नहीं उपयोग करें:

os.kill(os.getpid(), signal.SIGUSER1) 

और सिगसआर 1 के अनुसार हैंडलर को परिभाषित करें?

यदि आप इसे प्राप्त करने के लिए एक और प्रक्रिया चाहते हैं तो आपको इसके लिए सिग्नल भेजने के लिए अपनी पिड रखना होगा, इसलिए बस उसी आदेश का उपयोग करें जो मैंने os.getpid() के बजाय उचित पिड के साथ दिया था। जब तक मुझे कुछ याद नहीं आया?

2

आप celeryd_init संकेत का उपयोग कर सकते अपने कार्यकर्ताओं और संकेतों http://celery.readthedocs.org/en/latest/userguide/signals.html#celeryd-init

आप क्या प्रदान की के आधार पर प्रारंभ करने में, मैं के साथ परीक्षण किया है:

from celery.signals import celeryd_init 
from celery.utils.dispatch import Signal 

def process_result(result, *args, **kwargs): 
    print "signals received: %s" % result 

result_higher_then_four = Signal() 

@celeryd_init.connect 
def init_signals(*args, **kwargs): 
    result_higher_then_four.connect(process_result) 

@task(bind=True) 
def calculate(self, input): 
    result = input * 2 

    if result > 4: 
     result_higher_then_four.send(result=result, sender=self) 

    return result 
+0

यह सही है । मुझे लगता है कि ओपी एक ही चीज़ को प्राप्त करने के लिए चेन का उपयोग भी कर सकता है लेकिन बहुत पठनीय है। यहां उदाहरण देखें http://docs.celeryproject.org/en/latest/userguide/tasks.html#avoid-launching-synchronous-subtasks – chhantyal

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