[英]Tornado celery integration hacks
由於沒有人提供這個帖子的解決方案以及我迫切需要一個解決方法的事實,這里是我的情況和一些抽象的解決方案/想法供辯論。
我的堆棧:
我的問題:為Tornado找到一種方法來調度芹菜任務(已解決),然后異步收集結果(任何想法?)。
場景1 :(請求/響應黑客加上webhook)
這會發生嗎? 它有任何邏輯嗎?
場景2 :(龍卷風加長輪詢)
這有效嗎?
還有其他想法/架構嗎?
我的解決方案涉及從龍卷風到芹菜的輪詢:
class CeleryHandler(tornado.web.RequestHandlerr):
@tornado.web.asynchronous
def get(self):
task = yourCeleryTask.delay(**kwargs)
def check_celery_task():
if task.ready():
self.write({'success':True} )
self.set_header("Content-Type", "application/json")
self.finish()
else:
tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(0.00001), check_celery_task)
tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(0.00001), check_celery_task)
這是關於它的帖子 。
這是我們解決問題的方法。 由於我們在應用程序中查找了幾個處理程序的結果,因此我們將芹菜查找為mixin類。
這也使得tornado.gen模式的代碼更具可讀性。
from functools import partial
class CeleryResultMixin(object):
"""
Adds a callback function which could wait for the result asynchronously
"""
def wait_for_result(self, task, callback):
if task.ready():
callback(task.result)
else:
# TODO: Is this going to be too demanding on the result backend ?
# Probably there should be a timeout before each add_callback
tornado.ioloop.IOLoop.instance().add_callback(
partial(self.wait_for_result, task, callback)
)
class ARemoteTaskHandler(CeleryResultMixin, tornado.web.RequestHandler):
"""Execute a task asynchronously over a celery worker.
Wait for the result without blocking
When the result is available send it back
"""
@tornado.web.asynchronous
@tornado.web.authenticated
@tornado.gen.engine
def post(self):
"""Test the provided Magento connection
"""
task = expensive_task.delay(
self.get_argument('somearg'),
)
result = yield tornado.gen.Task(self.wait_for_result, task)
self.write({
'success': True,
'result': result.some_value
})
self.finish()
我偶然發現了這個問題並且反復對結果發出后果對我來說並不是最佳選擇。 所以我使用Unix套接字實現了類似於你的場景1的Mixin。
它會在任務完成后立即通知Tornado(准確地說,只要鏈中的下一個任務運行),並且只會在后端命中一次結果。 這是鏈接 。
現在, https://github.com/mher/tornado-celery來救援......
class GenAsyncHandler(web.RequestHandler):
@asynchronous
@gen.coroutine
def get(self):
response = yield gen.Task(tasks.sleep.apply_async, args=[3])
self.write(str(response.result))
self.finish()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.