芹菜和信号

时间:2014-09-03 14:43:03

标签: python django signals celery

我以前有这样的功能

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

2 个答案:

答案 0 :(得分:3)

问题是信号接收器没有注册。芹菜工人在自己的过程中运行,因此需要在该过程中进行信号连接。如果您知道它们是什么或可以发现它们,您可以使用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

答案 1 :(得分: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