[英]How to set timeout for tornado IOStream?
How to set timeout for tornado IOStream? 如何设置龙卷风IOStream的超时时间?
I've tried construct IOStream by: 我尝试通过以下方式构造IOStream:
sock = socket.socket()
sock.settimeout(5)
self.stream = tornado.iostream.IOStream(sock)
But when I call stream.read_bytes()
, it still keep waiting forever. 但是当我调用
stream.read_bytes()
,它仍然永远等待着。
You cannot use socket.settimeout()
, because it is designed for blocking IO and Tornado provides non-blocking IO. 您不能使用
socket.settimeout()
,因为它是为阻塞IO而设计的,而Tornado提供了非阻塞IO。
Tornado is highly oriented on Web and HTTP IO and it does not allow to do low-level network programming without extreme pain (sources of IOStream
are terrifying). Tornado高度面向Web和HTTP IO,并且不允许进行低级网络编程而没有极大的痛苦(
IOStream
来源令人恐惧)。
The best way to set a timeout on a socket is to use select.select()
, select.poll()
, etc, but it's a pain to integrate such approach with Tornado. 设置超时套接字上的最好方法是使用
select.select()
select.poll()
等,但它的这种做法与龙卷风整合的痛苦。
I've managed to perform reads with timeouts using combination of gen.with_timeout
and a dirty hack for clearing stream's state. 我已经成功地使用
gen.with_timeout
和肮脏的hack来清除超时状态,从而执行读取操作。
from tornado import gen
from tornado.ioloop import IOLoop
from tornado.tcpclient import TCPClient
timeout = 5
io_loop = IOLoop.current()
factory = TCPClient(io_loop=io_loop)
@gen.coroutine
def run():
stream = yield factory.connect('127.0.0.1', 1234)
try:
future = stream.read_bytes(128)
data = yield gen.with_timeout(
timeout=io_loop.time() + timeout,
future=future,
io_loop=io_loop,
)
except gen.TimeoutError:
# A dirty hack to cancel reading and to clear state of the stream, so
# stream will be available for reading in future
io_loop.remove_handler(stream.socket)
state = (stream._state & ~io_loop.READ)
stream._state = None
stream._read_callback = None
stream._read_future = None
stream._add_io_state(state)
Good luck! 祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.