tornado 如何使用管道将数据异步发送到客户端?

How can tornado use pipe to async send data to client?

对于龙卷风,我使用多处理来创建一个子进程来完成压缩工作。而子进程直接通过os.pipe

向主进程发送数据

对了,现在的问题是self.stream.read_until_close阻塞调用,并没有tar_worker关闭管道的另一端。

我的代码列表如下:

def tar_worker(fd, path):
    '''Tar worker to do the compressing work, directly write data to pipe.'''
    fp = os.fdopen(fd, 'w')
    tar = tarfile.open(mode='w|', fileobj=fp, dereference=True)
    tar.add(path)
    tar.close()
    fp.close()


class getTarFileHandler(tornado.web.RequestHandler):

    @tornado.web.asynchronous
    @gen.coroutine
    def get(self):
        recv, sender = os.pipe()
        self.p = multiprocessing.Process(target=tar_worker, args=(sender, '/boot/'))
        self.p.start()
        self.fd = recv

        # Create PipeIOStream
        self.stream = tornado.iostream.PipeIOStream(self.fd)
        self.stream.read_until_close(callback=self.f, streaming_callback=self.send_data)


    def f(self, s):
        print 'done send work'
        self.finish() #close connection

    def send_data(self, chunk):
        self.write(chunk)
        self.flush()

文件句柄可以跨多个进程共享;在这种情况下,parent 和 child 进程都有文件描述符指向同一底层管道的 两端 。 parent 和 child 进程都必须关闭 sender 才能真正关闭。在启动 multiprocessing.Process 后,parent 进程必须执行 os.close(sender) 以关闭其管道写入端的副本。这不会阻止 child 进程写入其副本;一旦 parent 和 child 都关闭了管道写入端的副本,管道的读取端将报告 EOF 并且 IOStream 读取方法将引发 StreamClosedError。