我熟悉事件驱动编程,但我遇到了这个问题,我已经终止了可能的解决方案。我阅读了Tornado的文档,我尝试过:
但我无法解决以下问题:
我有一个只听新消息的websocket服务器 并根据消息类型调用特定函数
class WebSocketHandler(tornado.websocket.WebSocketHandler):
...
def on_message(self, message):
if message['type'] is X:
self.write(functionA(message['data']))
elif message['type'] is Y:
self.write(functionB(message['data']))
...
当执行一个计算成本高的函数时出现问题,比如functionA,它可能需要5分钟才能终止
def functionA(message):
params = extract_params(message)
cmd = "computationally_expensive_tool"
out = check_output(cmd, shell=True, stderr=STDOUT, cwd=working_dir)
...
return json.dumps({
"error": False,
"message": "computationally_expensive_tool_execution_terminated",
"type": X
})
我的问题是如何以异步方式执行该功能,以便我可以在准备好后处理其他消息和functionA的结果?
答案 0 :(得分:1)
如果functionA
是一个无法异步的阻塞函数,您可能希望在线程池中运行它:
executor = concurrent.futures.ThreadPoolExecutor()
@gen.coroutine
def on_message(self, message):
if message['type'] is X:
yield executor.submit(functionA, message['data'])
elif message['type'] is Y:
functionB(message['data'])
这将阻止此websocket直到functionA
完成,但允许其他连接继续工作。如果您需要在functionA
运行时继续处理来自相同连接的其他类型的消息,则需要更复杂的安排,可能涉及tornado.queues.Queue
。