10

我想添加延迟使用django-celery. 目前,我已经创建了一个类似于下面的类(只是一个例子,实际的类不止这个):

from celery.task import task

class Delayer(object):
    def delay(self, func, minutes):
        return task(func, name="%s.delayed"%self.__class__.__name__)\
            .apply_async(countdown=minutes*60)

我正在按如下方式运行 celeryd:

python manage.py celeryd -E -B -lDEBUG

当我尝试从 django shell [例如Delayer().delay(lambda: 1, 1)] 中运行我的延迟方法时,我在 celeryd 输出中收到这样的错误:

[2013-01-02 15:26:39,324: ERROR/MainProcess] Received unregistered task of type "Delayer.delayed".
The message has been ignored and discarded.

Did you remember to import the module containing this task?
Or maybe you are using relative imports?
Please see http://bit.ly/gLye1c for more information.

The full contents of the message body was:
{'retries': 0, 'task': "Delayer.delayed", 'eta': '2013-01-02T21:27:39.320913', 'args': [], 'expires': None, 'callbacks': None, 'errbacks': None, 'kwargs': {}, 'id': '99d49fa7-bd4b-40b0-80dc-57309a6f19b1', 'utc': True} (229b)

Traceback (most recent call last):
  File "/home/simon/websites/envs/delayer/local/lib/python2.7/site-packages/celery/worker/consumer.py", line 432, in on_task_received
    strategies[name](message, body, message.ack_log_error)
KeyError: "Delayer.delayed"

我的问题是,是否可以注册此类动态创建的任务?如果没有,我可以使用其他什么方法来使用芹菜达到相同的效果?

4

1 回答 1

12

简单的答案是你不能;因为 celery 在不同的进程中运行,它需要能够导入任何作为 celery 任务运行的代码;您生成的可调用对象不是,因此 celery 移动对可调用对象的引用的方式不起作用。

然而,这确实提出了一种可能的攻击方式:如果您可以想出一种不同的方式来序列化您的可调用对象,那么您可以将其作为参数提供给一个简单的 celery 任务。这个先前的问题可能会有所帮助。请注意安全性的警示性提及:-)

于 2013-01-04T22:49:31.780 回答