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シェル[eg Delayer().delay(lambda: 1, 1)]内からdelayメソッドを実行しようとすると、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

簡単な答えは、できないということです。セロリは別のプロセスで実行されているため、セロリ タスクとして実行されるコードをインポートできる必要があります。生成された呼び出し可能オブジェクトはそうではないため、呼び出し可能オブジェクトへの参照を移動するセロリの方法は機能しません。

ただし、これは物事を攻撃する可能性のある方法を示唆しています。呼び出し可能オブジェクトをシリアル化する別の方法を思い付くことができれば、単純なセロリ タスクへの引数としてそれを提供できます。この前の質問が役立つ場合があります。セキュリティに関する注意事項に注意してください:-)

于 2013-01-04T22:49:31.780 に答える