0

我只是想到了龙卷风和事件驱动编程的非阻塞基础设施。实际上,我正在编写一个简单的 webapp,它正在访问外部 web 服务的 HTTP-API。我明白为什么我应该将此 API 称为非阻塞。但是,如果我只做第一次非阻塞调用,这样 IOLoop 可以进一步循环,会有什么缺点吗?

例如:

@tornado.web.asynchronous
def get(self):
    nonblocking_call1(self._callback)

def _callback(self, response):
    self.write(str(response))
    self.write(str(blocking_call2()))
    self.write(str(blocking_call3()))
    self.finish()

对比

@tornado.web.asynchronous
def get(self):
    nonblocking_call1(self._nonblocking_callback1)

def _callback1(self, response):
    self.write(str(response))
    nonblocking_call2(self._nonblocking_callback2)

def _callback2(self, response):
    self.write(str(response))
    nonblocking_call3(self._nonblocking_callback3)

def _callback3(self, response):
    self.write(str(response))
    self.finish()
4

1 回答 1

1

如果您在 tornado 中使用阻塞代码,则同一 tornado 进程在任何阻塞代码等待时无法处理任何其他请求。你的应用程序不会支持多个同时用户,即使阻塞调用只需要大约 100 毫秒,它仍然是一个巨大的性能杀手。

如果这样写对你来说很累(对我来说),你可以使用 tornado 的gen模块:

class GenAsyncHandler(RequestHandler):
    @asynchronous
    @gen.engine
    def get(self):
        http_client = AsyncHTTPClient()
        response = yield gen.Task(http_client.fetch, "http://example.com")
        do_something_with_response(response)
        self.render("template.html")
于 2012-03-24T17:05:08.533 回答