0

我是龙卷风的新手,并且有一个 API 可以进行阻塞数据库调用。由于这个阻塞调用,如果多个请求同时出现,tornado 将无法为所有请求提供服务。

我查看了一下,发现可以使用两种方法来解决它:使代码异步和/或使用 Process Pool Executors。我在这里的假设是拥有多个进程池执行器就像在龙卷风上有多个进程来服务多个请求。我看到的每个关于实现 Process Pool Executor 的示例也使代码异步。

我暂时不能使代码异步,因为它需要更多的代码更改,所以我正在寻找使用 Process Pool Executors 的简单修复。

我目前拥有的

import tornado.ioloop
import tornado.web


def blocking_call():
    import time
    time.sleep(60)
    return "Done"


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        val = blocking_call()
        self.write(val)


if __name__ == "__main__":
    app = tornado.web.Application([(r"/", MainHandler)])
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

我试过的

import tornado.ioloop
import tornado.web
from concurrent.futures import ProcessPoolExecutor


def blocking_call():
    import time
    time.sleep(60)
    return "Done"


class MainHandler(tornado.web.RequestHandler):
    def initialize(self, executor):
        self.executor = executor

    def get(self):
        val = self.executor.submit(blocking_call)
        self.write(val)


if __name__ == "__main__":
    executor = ProcessPoolExecutor(5)

    app = tornado.web.Application(
        [(r"/", MainHandler, dict(executor=executor))])
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

我对这种方法的问题是,现在我得到的是一个future object而不是实际的响应。如何在发回响应之前让Get请求等待完成?self.executor

4

1 回答 1

1

executor.submit()返回一个concurrent.futures.Future不可等待的。

我建议你使用 Tornado 的run_in_executor方法来执行阻塞任务。

async def get(self):
    loop = tornado.ioloop.IOLoop.current()
    val = await loop.run_in_executor(self.executor, blocking_call)
    self.write(val)

于 2021-07-07T05:33:48.597 回答