使用Tornado的data_received方法而不阻塞有什么特别的要求吗?

时间:2019-01-30 07:12:06

标签: python-3.x asynchronous tornado nonblocking

我有一个POST请求处理程序,该处理程序使用streaming data as input并将其写入AWS API。数据通过多个内部请求发送到AWS,这些内部请求是通过boto3发出的。我相信boto3会阻塞,但在执行I / O时会阻塞may release the GIL:它似乎在内部使用urllib3.connection。因此,我将其包装在对run_in_executor的调用中-类似于以下缩减代码:

@stream_request_body
class Handler(RequestHandler):
    async def prepare(self):
        self.parser = BufferedParser()

    async def data_received(self, chunk):
        complete_part = self.parser.receive(chunk)
        if complete_part:
            await IOLoop.current().run_in_executor(
                None, self.send_via_boto, complete_part)

    async def post(self):
        self.set_header('Content-Type', 'text/plain')
        self.write("OK")

我的问题是:等待的send_via_boto调用会阻止客户端上传下一个块吗?我是否需要实施一些更高级的产品,还是应该已经成为非阻塞性产品?

1 个答案:

答案 0 :(得分:1)

“阻止客户端上传下一个块” -客户端不直接将数据上传到您的应用,而是上传到TCP套接字。该套接字具有一定的大小,即缓冲区,因此,如果缓冲区已满,客户端将等待直到清空后再继续上传。您的应用程序在Tornado的帮助下,将从此TCP-socket-buffer读取,并将其与读取的部分清空。即使您以阻止方式(即,没有run_in_executor,但会阻止服务器)将数据发送到AWS,将数据块发送到AWS的过程也不会阻止客户端将数据上传到TCP套接字。 >满足其他要求)。如果您将数据发送到AWS的速度比客户端上载的速度慢,则您的应用程序将成为瓶颈,并会阻止(从技术上讲,它与 blocking 不同)来阻止客户端上载更多内容。