芹菜没有与烧瓶应用一起运行

时间:2014-02-19 09:09:15

标签: python python-2.7 flask celery flask-restful

我在烧瓶应用中使用芹菜,但芹菜(3.1.8)。这是我的烧瓶应用配置

celery.py

 from __future__ import absolute_import
 from celery import Celery
 from cuewords.settings import CELERY_BROKER_URL,CELERY_RESULT_BACKEND

 app = Celery('proj',
         broker=CELERY_BROKER_URL,
         backend=CELERY_RESULT_BACKEND)

app.conf.update(CELERY_TASK_RESULT_EXPIRES=3600)

if __name__ == '__main__':
   app.start()

setting.py

  CELERY_BROKER_URL='redis://localhost:6379/0'
  CELERY_RESULT_BACKEND='redis://localhost:6379/0'
  BROKER_TRANSPORT = 'redis'

api.py

 class Webcontent(Resource):
   def post(self,session=session):
   args = self.parser.parse_args()
   site_url = args["url"]
   url_present=Websitecontent.site_url_present(session,site_url)
    if site_url.strip() != "" and not url_present:
      try:
        #add data and commit 
        session.commit()
        websitecontent=Websitecontent(params*)
        websitecontent.update_url(id,session)
      except:
        session.rollback()
      raise
      finally:
        session.close()                
    else:
      return "No data created / data already present"

在我的模型中,我正在为任务添加方法

model.py

  from cuewords.celery import app
  class Websitecontent(Base):

    @app.task(name='update_url')
    def update_url(self,id,session):
    ...code goes here..

这就是我如何从命令提示符运行芹菜

celery -A cuewords.celery worker

我还使用花来监控任务,我可以看到一个工人正在运行,但我看不到任何任务是空的。任何想法我遗失或做错了什么.. 感谢

1 个答案:

答案 0 :(得分:7)

问题是,在运行worker时,您的任务永远不会导入Python运行时。 celery命令是您的入口点。而且你告诉Celery导入你的cuewords.celery模块,因为那是你应用实例所在的地方。但是,这是事件链结束的地方,不再导入其他Python代码。

现在,最常见的错误是将任务导入与Celery应用程序实例相同的模块中。不幸的是,这将导致两个模块尝试从彼此导入内容并导致循环导入错误。这不好。

要解决此问题,可以将任务函数导入Celery应用程序模块,并在不使用装饰器样式的情况下注册它们。例如:

from celery import Celery
from models import my_task

app = Celery()
app.task(name='my_task')(my_task)

这将消除在模型模块中导入应用程序实例的需要。

但是,您正在使用方法任务。方法任务需要与功能任务区别对待,如下所示:http://docs.celeryproject.org/en/latest/reference/celery.contrib.methods.html。方法任务与功能任务不同,因为它们与对象的实例相关联。换句话说,该函数是一个类函数。因此,要使用先前的注册任务样式,首先需要该类的实例。为了解决这个问题,您应该考虑使用您的任务而不是方法。