2014-10-03 64 views
1

我使用tornado.ioloopcelery工人,因为我需要使用mongodb。旋风IOLoop回调异常在芹菜工人无

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 

这些错误并不一致。有没有任何提升条件?

回答

1

这看起来像一个线程问题。我对芹菜的线程模型并不熟悉,但它看起来像启动了CeleryWorker的多个副本,每个副本都试图运行同一个单例IOLoop.instance()。每个工作线程都需要自己的IOLoop,如果你要这样运行 - 看看同步的tornado.httpclient.HTTPClient如何创建并运行临时IOLoop

+0

感谢您的回答!事实证明,芹菜与IOLoop的效果不佳,因为它与方法相互作用的方式。我们的主要原因是让它与Motor一起工作。所以我们决定停止使用它,而不是使用PyMongo驱动程序。 – Maddy 2014-10-11 19:05:07

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) 
+0

谢谢!事实证明,芹菜与IOLoop的效果不佳,因为它与方法相互作用的方式。 我们的主要原因是使它与Motor(MongoDB驱动程序的龙卷风)工作。所以我们决定停止使用它,而不是使用PyMongo驱动程序。 – Maddy 2014-10-11 19:04:02

+0

很好,所以切换到电机后,原来的代码工作? – 2014-10-12 00:12:43

+0

我们从Motor改为PyMongo,它可以无缝工作:-) – Maddy 2014-10-12 01:14:06