适应龙卷风的celery.task.http.URL

时间:2013-09-10 05:20:42

标签: python asynchronous celery tornado nonblocking

Celery包含一个能够使用amqp或其他一些芹菜后端发出异步HTTP请求的模块。我正在使用tornado-celery生产者进行异步消息发布。据我所知tornado-celery使用鼠兔为此。问题是如何使celery.task.http.URL适应龙卷风(使其无阻塞)。基本上有两个地方需要改进:

  1. HttpDispatch.make_request()必须使用tornado async http client实现;
  2. 必须使用tornado API使用相应的非阻止代码重新实现
  3. URL.get_async(**kw)URL.post_async(**kw)。例如:

    class NonBlockingURL(celery.task.http.URL):
    
        @gen.coroutine
        def post_async(self, **kwargs):
            async_res = yield gen.Task(self.dispatcher.delay, 
                                       str(self), 'POST', **kwargs)
            raise gen.Return(async_res)
    
  4. 但我无法理解如何以恰当和简洁的方式做到这一点。如何使其完全像非异步的非阻塞?顺便说一下,我正在使用amqp后端。

    请给我一个很好的指导,甚至更好,一个例子。

1 个答案:

答案 0 :(得分:1)

实际上,你必须决定是否使用Tornado的异步方法,或者你是否使用像cellery这样的队列。没有使用两者的意义,因为队列快速回答队列的状态,所以在等待队列响应时没有龙卷风做其他事情。为了在两种解决方案之间做出决定,我会说:

芹菜:更多的模块化,易于分发到不同的核心或不同的机器,任务可以被别人使用而不是龙卷风,你必须安装并继续运行softare(amqp,cellery workers ......)

Tornado中的异步:更多单片,一个程序可以执行所有操作,更短的代码,一个程序可以运行

要使用Tornado的异步方法,请参阅文档。 这是一个使用芹菜和龙卷风的简短解决方案:

task.py

 from celery import Celery,current_task
 import time
 celery=Celery('tasks',backend='amqp',result_backend='amqp')

 @celery.task
 def MyTask(url,resid):
     for i in range(10):
         time.sleep(1)
         current_task.update_state(state='running',meta={'i': i})
     return 'done'

server.py

 import tasks
 from tornado import RequestHandler,....
 from tornado.web import Application
 dictasks={}
 class runtask(RequestHandler):
     def post(self):
         i=len(dictasks)
         dictasks[i]=task.MyTask.delay()
             self.write(i)

 class chktask(RequestHandler):
     def get(self,i):
         i=int(i)
         if dictasks[i].ready():
             self.write(dictasks[i].result)
             del dictasks[i]
         else:
             self.write(dictasks[i].state + ' i:' + dictasks[i].info.get('i',-1))


 Application = Application([
     (r"/runtask", runtask}),
     (r"/chktask/([0-9]+)", chktask),

 etc.