[Python-Dev] Minor socket timeout quibble - timeout raises socket.error

Guido van Rossum guido@python.org
Fri, 12 Jul 2002 16:00:21 -0400


> > The way I restructured the code it is impossible to distinguish a
> > timeout error from other errors; you simply get the "no data
> > available" error from the socket operation.  This is the same error
> > you'd get in non-blocking mode.
> > 
> 
> To distinguish a timeout error, the caller can check s->sock_timeout
> when a non-blocking mode error occured, or just return an error code
> from internal_select() (I guess you must have your reason to taken it
> out in the first place)

I don't understand your first suggestion.  Not all errors mean that
the timeout triggered!

I took it out because it is much less code this way.

> > Before I recomplicate the code so that it can raise a separate error
> > when the select fails, I'd like to understand the use case better.
> > Why would you want to make this distinction?  Requeueing the request
> > (as in Skip's example) doesn't make sense IMO: you set the timeout for
> > a reason, and that reason is that you want to give up if it takes too
> > long.  If you really intend to retry you're better of disabling the
> > timeout!
> >
> 
> How about the following (assume we have socket.setDefaultTimeout()):
> 
>     import socket
>     import urllib
> 
>     socket.setDefaultTimeout(5.0)
>     retry = 0
>     url = 'some url'
> 
>     while retry < 3:
>         try:
>             file = urllib.urlretrieve(url)
>         except socket.TimeoutError:
>             if retry == 2:
>                 print "Server too busy, given up!"
>                 raise
>             else:
>                 print "Server busy, retry!"
>                 retry += 1
>         else:
>             break
> 
> MS IIS behave strangely to http request.  When the server is very busy,
> it will randomly drop some requests without disconnecting the client. 
> So the best approach for the client is to timeout and retry.  I guess
> that might be the reason why people needed timeoutsocket in the first
> place.

One of the reasons (there are lots of reasons why a connect or receive
attempt may be very slow to time out, or even never time out).

Of course, this stll doesn't distinguish between a timeout from
connect() and one from recv().

Have you ever written code like this?

> > If you really want to, you can already distinguish the timeout case,
> > because you get an EAGAIN error then (maybe something else on Windows
> > -- Bernard, if you have a fix for that, please send it to me).
> 
> I am struggling with the test case for the new socket code.  The timeout
> test case I've send you works with the old socketmodule.c (attached),
> but not with the lastest version (on linux or windows).  It's strange,
> your new implementation looks much cleaner.

No need to attach copies of old versions -- just give me the CVS
revision number. :-)

> Please bear with me a bit longer for a patch  :.(

OK.

Anyway, I have no time to play with this right now, so I'm glad you
aren't giving up just yet. :-)

--Guido van Rossum (home page: http://www.python.org/~guido/)