Michael,

Thank you again for looking into this.  Also, I don't have a lot of
network code experience in python, so please take all this with ample
salt.

> I'm beginning to think I ought to start up a windows VM and see if I can
> reproduce this there.

I would like to see big K be well supported on windows.  And I'd be
happy to help in anyway I could.  I can't donate a microsoft license
to you, but I can test locally.  I bet you could get MS to donate a
license.  But if you need any help setting up a VM, let me know.  I
use vmware and virtualbox.

> Now there's several ways that I could go down this, but I can see that
> probably the simplest would be to add a connection timeout this way:
>
> class TCPClient(Axon.Component.component):
>    def __init__(self,host,port,delay=0,connect_timeout=60):
>         self.connect_timeout = connect_timeout
> ...
>                connect_start = time.time()
>                while not self.safeConnect(sock,(self.host, self.port)):
>                   if self.shutdown():
>                       return
>                   if ( time.time() - connect_start ) > self.connect_timeout:
>                       self.howDied = "timeout"
>                       raise Finality
>                   yield 1


I am +1 to the idea of including a timeout parameter.  In fact, I
think every network operation call inside Kamaelia should expose a
defaulted timeout parameter.  That said, my gut feeling is that the
timeout should be handled at the lowest level possible and then
exposed all the way up the call tree.  For example:

> connection, it would hit this logic path in safeConnect:
>       try:
>          sock.connect(*sockArgsList); # Expect socket.error: (115, 'Operation 
> now in progress')
> ....
>       except socket.error, socket.msg:
>          (errorno, errmsg) = socket.msg.args
>          if errorno==errno.EALREADY:
>             # The socket is non-blocking and a previous connection attempt 
> has not yet been completed
>             # We handle this by allowing  the code to come back and 
> repeatedly retry
>             # connecting. This is a valid, if brute force approach.
>             assert(self.connecting==1)
>             return False
>          elif errorno==errno.EINPROGRESS or errorno==errno.EWOULDBLOCK:
>             #The socket is non-blocking and the connection cannot be 
> completed immediately.
>             # We handle this by allowing  the code to come back and 
> repeatedly retry
>             # connecting. Rather brute force.
>             self.connecting=1
>             return False # Not connected should retry until no error

Here we have EALREADY, EINPROGRESS and EWOULDBLOCK.  I think there
needs to be a way to timeout these connection attempts rather than
simply not starting another attempt after some timeout period.  Why
would we want to keep retrying the connection during the timeout
period?  I think it should only make 1 single connection attempt and
wait at most timeout period for success.

On an only slightly related note, I remember reading a posting once by
Glyph where he was promoting one of the values for using twisted.  He
said that they had spent considerable time testing and debugging the
frustratingly disparate socket behaviors on the 3 major platforms and
only twisted really "did the right thing" while still exposing a
uniform framework interface.  My brain doesn't fit twisted, but now
I'm starting to appreciate what he was talking about.

Thanks,
Steve
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"kamaelia" group.
To post to this group, send email to kamaelia@googlegroups.com
To unsubscribe from this group, send email to 
kamaelia+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/kamaelia?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to