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。
对于龙卷风,我使用多处理来创建一个子进程来完成压缩工作。而子进程直接通过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。