[Twisted-Python] ENOBUF and Twisted

Jp Calderone exarkun at divmod.com
Sat Aug 21 17:59:12 EDT 2004


James Y Knight wrote:
> 
> On Aug 21, 2004, at 3:50 AM, Jp Calderone wrote:
> 
>>  How many clients are we talking about?  A bit of investigation leads 
>> me to believe this can be caused by reaching the maximum number of 
>> open sockets.  Having unreliable connections can exacerbate this, 
>> since TIME_WAIT sockets are counted towards the limit (Windows NT 4.0 
>> seems to leave sockets in this state for 4 minutes).
>>
>>   Twisted should still probably handle it, but if this is the true 
>> cause, it should be handled in a fashion similar to errors from 
>> accept(), possibly (a better understanding of the problem is probably 
>> still required).
> 
> 
> I don't think that's the case, or rather, it is the case for accept() 
> but not write().
> 

   Indeed, I had never heard of this ENOBUFS behavior before.  But it is 
the only documented behavior I can find for WSAENOBUFS.  And it is 
_Windows_, so it needn't make sense.  I just wanted to point out this 
possibility, since it seemed no one had considered it yet.

> 
> Screwtape (I guess that's probably not your real name, but you don't 
> seem to have given a real name),
> Can you try this patch and see if it fixes the problem? It assumes 
> you'll always be able to send a 64K buffer *eventually*, which I hope is 
> the case. If you could also try it with just the "or se.args[0] == 
> ENOBUFS", and not the buffer(.., 0, 65535), that'd also be appreciated.
> 
> 
> James
> 
> Index: twisted/internet/tcp.py
> ===================================================================
> --- twisted/internet/tcp.py     (revision 11325)
> +++ twisted/internet/tcp.py     (working copy)
> @@ -58,6 +58,7 @@
>      EISCONN     = 10056
>      ENOTCONN    = 10057
>      EINTR       = 10004
> +    from errno import WSAENOBUFS as ENOBUFS
>  elif os.name != 'java':
>      from errno import EPERM
>      from errno import EINVAL
> @@ -68,6 +69,7 @@
>      from errno import EISCONN
>      from errno import ENOTCONN
>      from errno import EINTR
> +    from errno import ENOBUFS
>  from errno import EAGAIN
> 
>  # Twisted Imports
> @@ -262,11 +264,11 @@
>          (which is negative)
>          """
>          try:
> -            return self.socket.send(data)
> +            return self.socket.send(buffer(data, 0, 65535))
>          except socket.error, se:
>              if se.args[0] == EINTR:
>                  return self.writeSomeData(data)
> -            elif se.args[0] == EWOULDBLOCK:
> +            elif se.args[0] == EWOULDBLOCK or se.args[0] == ENOBUFS:
>                  return 0
>              else:
>                  return main.CONNECTION_LOST
> 

   I'm not sure I like this :/  How about attempting a length-limited 
write only on ENOBUFS (assuming we can confirm the meaning of 
WSAENOBUFS)?  It'd be nice to leave the common code path alone, as it is 
a pretty darn common code path.

   Jp




More information about the Twisted-Python mailing list