Bjoern Schliessmann wrote: > Hello, > > I'm currently trying to implement a simulation program with Kamaelia > and need a reliable TCP connection to a data server.
The behaviour you're seeing sounds odd (which is hopefully encouraging :-), but it's not clear from the description whether its a bug in your code or Kamaelia. One question I really have as a result is what version are you using? Current release version 0.5.0, the version on /trunk, or the bleeding edge version on /branches/private_MPS_Scratch. (I'm using the latter to run my greylisting server - as are a few others). All that said though, looking at the differences between versions, I'm not convinced they're large enough to show the problem you're seeing. I'm not about to rule out a bug I don't know about though :-) > From Twisted, I know that a method is called if the connection fails > by whatever reason. I tried to get the same results with Kamaelia's > TCPClient component. If I start up the component and try to connect > to a closed TCP port it fails and sends a message out of the signal > box, that's okay. If you'd prefer more information in that message, please let me know. (all components send out a message when they shutdown. For things that send data out as one of their primary actions send out a producerFinished message) > But if the connection attempt succeeds and, after some time, the > server drops the connection with full TCP handshake (FIN, FIN+ACK, > ACK), the component just hangs and does nothing. Is this by design, > or could there be an error in my setup? It sounds like an error in your setup... but I hate saying that. (Doesn't tell me or you what it is, and doesn't help change things to discourage or detect mistakes in usage) When the server drops the connection in my setups, the client disconnects cleanly when the server dies, with the client code looking like this: self.send(producerFinished(self,self.howDied), "signal") Meaning you get a message telling you how the component shutdown as well as the fact it shutdown. (If "howDied" is None, it's just a normal shutdown - ie as a result of being told to shut down) The function where this is managed is runClient in the class Kamaelia.Internet.TCPClient.TCPClient (fully qualified name) The actual socket connections are handled by a class called ConnectedSocketAdapter which manages all logic of checking for errors, remote shutdown etc. That works the same for both servers and clients so breakage in clients would show up as breakage in servers as well, which would be particularly bad. > Also, how long does a TCPClient component live -- or how can/should > I terminate it explicitly? I'm afraid that if I create > a "ReconnectingTCPClient" component, it could eat up memory over > long runtime with hanging TCPClients. That shouldn't be an issue (I hate the word "should"), but you can do this using a carousel component. (I ought to write that as an example of how to use the Carousel component) In the meantime - whilst I check to see if there's a bug I didn't know about, the following 2 cookbook entries may be of use: * http://kamaelia.sourceforge.net/Cookbook/TCPSystems * http://kamaelia.sourceforge.net/Cookbook/Carousels - allows you to make something that exits reusable. It's a little awkward to get your head around, but is quite useful when you do. (I've heard of others using Carousel & TCPClient to make a reconnecting TCPClient in the past) All that said, I'm not going to rule out a bug and look into it. (if you have a simple example you find fails, please forward it to me :) *thinks* The following code may also be useful when debugging: from Kamaelia.Chassis.Pipeline import Pipeline class PeriodicWakeup(Axon.ThreadedComponent.threadedcomponent): interval = 300 def main(self): while 1: time.sleep(self.interval) self.send("tick", "outbox") class WakeableIntrospector(Axon.Component.component): def main(self): while 1: Q = [ q.name for q in self.scheduler.listAllThreads() ] Q.sort() print "*debug* THREADS"+ str(Q) self.scheduler.debuggingon = False yield 1 while not self.dataReady("inbox"): self.pause() yield 1 while self.dataReady("inbox"): self.recv("inbox") Pipeline( PeriodicWakeup(), WakeableIntrospector(), ).activate() If you put this code somewhere before your "run" call, you'll get periodic output to tell you what's running. When debugging manually I'd drop the interval to 3-10 seconds or so. I use 300 for a server. Now, off to see if I can reproduce your problem... :) Regards, Michael. -- http://kamaelia.sourceforge.net/Home http://yeoldclue.com/blog -- http://mail.python.org/mailman/listinfo/python-list