我在tornado.ioloop
工作者中使用celery
因为我需要使用mongodb。
class WorkerBase():
@gen.engine
def foo(self,args,callback)
bar = ['Python','Celery','Javascript','HTML']
# ... process something ....
callback(bar)
@gen.engine
def RunMyTask(self,args):
result = yield gen.Task(self.foo,args=args)
# Stop IOLoop instance
IOLoop.instance().stop()
@task(name="MyWorker",base=WorkerBase)
def CeleryWorker(args):
# This works because i'm adding base as WorkerBase
CeleryWorker.RunMyTask(args)
IOLoop.instance().start()
return True
当我调用任务时,它会出错:
[2014-10-02 12:12:11,561: ERROR/Worker-4] Exception in callback None
Traceback (most recent call last):
File "/var/www/myapp/env/local/lib/python2.7/site-packages/tornado/ioloop.py", line 832, in start
fd_obj, handler_func = self._handlers[fd]
KeyError: 16
或
[2014-10-02 12:12:11,561: ERROR/Worker-4] Exception in callback None
Traceback (most recent call last):
File "/var/www/myapp/env/local/lib/python2.7/site-packages/tornado/ioloop.py", line 832, in start
fd_obj, handler_func = self._handlers[fd]
KeyError: 14
这些错误并不一致。是否有任何加薪条件?
答案 0 :(得分:1)
这看起来像是一个线程问题。我不熟悉芹菜的线程模型,但看起来它正在启动CeleryWorker的多个副本,每个副本都试图运行相同的单例IOLoop.instance()。如果您要像这样运行它,每个工作线程都需要自己的IOLoop - 查看同步tornado.httpclient.HTTPClient创建和运行临时IOLoop的内容
答案 1 :(得分:0)
看起来你的工作任务只是在ioloop停止之前返回并被视为已完成,因此gen.engine的回调无法找到原始的stack_context。
@task(name="MyWorker",base=WorkerBase) def CeleryWorker(args): # This works because i'm adding base as WorkerBase CeleryWorker.RunMyTask(args) IOLoop.instance().start() return True
我有一些建议
1)删除返回
@task(name="MyWorker",base=WorkerBase)
def CeleryWorker(args):
# This works because i'm adding base as WorkerBase
CeleryWorker.RunMyTask(args)
IOLoop.instance().start()
2)使用run_sync
import functools
@task(name="MyWorker",base=WorkerBase)
def CeleryWorker(args):
# This works because i'm adding base as WorkerBase
func = functools.partial(CeleryWorker.RunMyTask, args)
IOLoop.instance().run_sync(func)