How to set timeout for IOStream tornado?

How to set timeout for IOStream tornado?

I tried building IOStream with:

sock = socket.socket() sock.settimeout(5) self.stream = tornado.iostream.IOStream(sock) 

But when I call stream.read_bytes() , it still waits forever.

+6
source share
1 answer

You cannot use socket.settimeout() because it is designed to block IO, and Tornado provides non-blocking IO.

Tornado is very Web and HTTP-oriented IO, and it does not allow low-level network programming without severe pain ( IOStream sources are terrifying). A.

The best way to set a timeout on a socket is to use select.select() , select.poll() , etc., but it is a pain to integrate this approach with Tornado.

I was able to read with timeouts using a combination of gen.with_timeout and a dirty hack to clear the state of the stream.

 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

+1
source

Source: https://habr.com/ru/post/951182/


All Articles