[Python-Dev] Socket timeout patch
Fri, 7 Jun 2002 00:26:23 -0400
On Fri, Jun 07 @ 00:01, Guido van Rossum wrote:
> I've more or less completed the introduction of timeout sockets.
> Executive summary: after sock.settimeout(T), all methods of sock will
> block for at most T floating seconds and fail if they can't complete
> within that time. sock.settimeout(None) restores full blocking mode.
> I've also done some long-needed rigorous cleanup of the socket module
> source code, e.g. I got rid of the PySock* static names.
Good stuff. The module needed a little work as I discovered as well
> Remaining issues:
> - A test suite. There's no decent test suite for the timeout code.
> The file test_timeout.py doesn't test the functionality (as I
> discovered when the test succeeded while I had several blunders in
> the select code that made everything always time out).
Er, hopefully Bernard is still watching this thread as he wrote
the test_timeout.py. He's been pretty quiet though as of late... I'm
willing to rewrite the tests if he doesn't have the time.
I think the tests should follow the same pattern as the
test_socket.py. While adding my regression tests, I noted that the
general socket test suite could use some re-writing but I didn't feel
it appropriate to tackle it at that point. Perhaps a next patch?
> - Cross-platform testing. It's possible that the cleanup broke things
> on some platforms, or that select() doesn't work the same way. I
> can only test on Windows and Linux; there is code specific to OS/2
> and RISCOS in the module too.
This was a concern from the beginning but we had some chat on the
dev list and concluded that any system supporting sockets has to
support select or some equivalent (hence the initial reason for using
the select module, although I agree it was expensive).
> - I'm not sure that the handling of timeout errors in accept(),
> connect() and connect_ex() is 100% correct (this code sniffs the
> error code and decides whether to retry or not).
I've tested these on linux (manually) and they seem to work just
fine. I didn't do as much testing with connect_ex but the code is
very similar to connect, so confidence is high-er. The reason for the
two-pass is because the initial connect needs to be made to start the
process and then try again, based on the error codes, for non-blocking
connects. It's weird like that.
> - Should sock.settimeout(0.0) mean the same as sock.setblocking(0)?
> Currently it sets a timeout of zero seconds, and that behaves pretty
> much the same as setting the socket in nonblocking mode -- but not
> exactly. Maybe these should be made the same?
I thought about this and whether or not I wanted to address this. I
kinda decided to leave them separate though. I don't think setting a
timeout means anything equivalent to setblocking(0). In fact, I can't
see why anyone should ever set a timeout of zero and the immediate
throwing of the exception is a good alert as to what's going on. I
vote, leave them separate and as they are now...
> - A socket filedescriptor passed to fromfd() is now assumed to be in
> blocking, non-timeout mode.
> - The socket.py module has been changed too, changing the way
> buffering is done on Windows. I haven't reviewed or tested this
> code thoroughly.
I added a regression test to test_socket.py to test this, that works
on both the old code (I used 2.1.3) and the new code. Hopefully, this
will be instrumental for those testing it and it reflects my manual
For my gpg public key: