Почему Celery работает в оболочке Python, но не в моих представлениях Django? (проблема импорта)
Я установил сельдерей (последняя стабильная версия).
У меня есть каталог под названием /home/myuser/fable/jobs
. Внутри этого каталога у меня есть файл под названием tasks.py:
from celery.decorators import task
from celery.task import Task
class Submitter(Task):
def run(self, post, **kwargs):
return "Yes, it works!!!!!!"
Внутри этого каталога у меня также есть файл celeryconfig.py:
BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "abc"
BROKER_PASSWORD = "xyz"
BROKER_VHOST = "fablemq"
CELERY_RESULT_BACKEND = "amqp"
CELERY_IMPORTS = ("tasks", )
В моем /etc/profile
у меня есть эти настройки как мой PYTHONPATH:
-
PYTHONPATH=/home/myuser/fable:/home/myuser/fable/jobs
Итак, я запускаю своего работника из сельдерея с помощью консоли ($ celeryd --loglevel=INFO
), и я пробовал это.
Я открываю консоль Python и импортирую задачи. Затем я запускаю Отправитель.
>>> import fable.jobs.tasks as tasks
>>> s = tasks.Submitter()
>>> s.delay("abc")
<AsyncResult: d70d9732-fb07-4cca-82be-d7912124a987>
Все работает, как вы можете видеть на моей консоли
[2011-01-09 17:30:05,766: INFO/MainProcess] Task tasks.Submitter[d70d9732-fb07-4cca-82be-d7912124a987] succeeded in 0.0398268699646s:
Но когда я вхожу в мои Django views.py и запускаю точные 3 строки кода, как указано выше, я получаю следующее:
[2011-01-09 17:25:20,298: ERROR/MainProcess] Unknown task ignored: "Task of kind 'fable.jobs.tasks.Submitter' is not registered, please make sure it imported.": {'retries': 0, 'task': 'fable.jobs.tasks.Submitter', 'args': ('abc',), 'expires': None, 'eta': None, 'kwargs': {}, 'id': 'eb5c65b4-f352-45c6-96f1-05d3a5329d53'}
Traceback (most recent call last):
File "/home/myuser/mysite-env/lib/python2.6/site-packages/celery/worker/listener.py", line 321, in receive_message
eventer=self.event_dispatcher)
File "/home/myuser/mysite-env/lib/python2.6/site-packages/celery/worker/job.py", line 299, in from_message
eta=eta, expires=expires)
File "/home/myuser/mysite-env/lib/python2.6/site-packages/celery/worker/job.py", line 243, in __init__
self.task = tasks[self.task_name]
File "/home/myuser/mysite-env/lib/python2.6/site-packages/celery/registry.py", line 63, in __getitem__
raise self.NotRegistered(str(exc))
NotRegistered: "Task of kind 'fable.jobs.tasks.Submitter' is not registered, please make sure it imported."
Это странно, потому что клиент celeryd показывает, что он зарегистрировался при запуске.
[2011-01-09 17:38:27,446: WARNING/MainProcess]
Configuration ->
. broker -> amqp://[email protected]:5672/fablemq
. queues ->
. celery -> exchange:celery (direct) binding:celery
. concurrency -> 1
. loader -> celery.loaders.default.Loader
. logfile -> [stderr]@INFO
. events -> OFF
. beat -> OFF
. tasks ->
. tasks.Decayer
. tasks.Submitter
Может кто-нибудь помочь?
Ответы
Ответ 1
Я считаю, что ваш файл tasks.py должен быть в приложении django (зарегистрированном в settings.py) для импорта. Кроме того, вы можете попробовать импортировать задачи из файла __init__.py
в свой основной проект или в одно из приложений.
Также попробуйте запустить celeryd из manage.py:
$ python manage.py celeryd -E -B -lDEBUG
(-E
и -B
может быть или не быть необходимым, но то, что я использую).
Ответ 2
Это то, что я сделал, который наконец-то работал
в Settings.py Я добавил
CELERY_IMPORTS = ("myapp.jobs", )
в папке myapp Я создал файл под названием jobs.py
from celery.decorators import task
@task(name="jobs.add")
def add(x, y):
return x * y
Затем пробег из командной строки: python manage.py celeryd -l info
в другой оболочке я запущена оболочка python manage.py, затем
>>> from myapp.jobs import add
>>> result = add.delay(4, 4)
>>> result.result
и я получаю:
16
Важным моментом является то, что при добавлении новой функции необходимо перезапустить обе командные оболочки. Вы должны зарегистрировать имя как на клиенте, так и на сервере.
: -)
Ответ 3
См. "Автоматическое именование и относительный импорт" в документах:
http://celeryq.org/docs/userguide/tasks.html#automatic-naming-and-relative-imports
Название задачи - "tasks.Submitter" (как указано в выводе celeryd)
но вы импортируете задачу как "fable.jobs.tasks.Submitter"
Я думаю, лучшее решение здесь, если работник также видит его как "fable.jobs.tasks.Submitter",
это имеет больше смысла с точки зрения приложения.
CELERY_IMPORTS = ("fable.jobs.tasks", )