[06:31] *** salmon_ has joined #kamaelia
[07:10] *** vmlemon_ has joined #kamaelia
[07:23] < vmlemon_> Hi
[07:46] < Lawouach> hi
[08:20] *** musashi has joined #kamaelia
[08:20] < musashi> hello?
[08:20] < vmlemon_> Hi, musashi
[08:20] < musashi> How is going
[08:21] < vmlemon_> OK
[08:21] < musashi> I'm developing a application with Kamaelia, and have a (newbie I think) question...
[08:22] < musashi> Can I ask? :)
[08:23] < vmlemon_> Sure, you don't need to ask, in order to ask a question ;)
[08:23] < musashi> hehehehe just to be polite
[08:23] < musashi> I have a server, built with SimpleServer
[08:23] < musashi> It runs great, and tested connecting with telnet
[08:24] < musashi> but then, I want to open a connection from a client, using TCPClient
[08:24] < musashi> just to send a string and get the results
[08:24] < musashi> I'm using OneShot, but the server doesn't receive any message...
[08:24] < musashi> The code of the client is as follows:
[08:24] < musashi> Pipeline(OneShot("insultam"),
[08:24] < musashi> ConsoleEchoer(True),
[08:24] < musashi> TCPClient("localhost",clientServerTestPort),
[08:24] < musashi> ConsoleEchoer(True),
[08:24] < musashi> ).run()
[08:25] < musashi> any hints?
[08:25] < musashi> I also tried with a DataSource but without results :(
[08:26] < vmlemon_> I'm not sure, since it's a while since I last used the server stuff, but someone else probably knows
[08:27] < musashi> OK Thanks :)
[08:28] < vmlemon_> No problem
[08:29] < vmlemon_> You'll find that although people are "in" the channel, they're usually either sleeping, or busy doing other things
[08:29] < musashi> yes I figure
[08:29] < musashi> there's activity on sundays?
[08:29] < vmlemon_> Sometimes
[08:29] < musashi> okay :)
[08:35] < Lawouach> hmm
[08:35] < Lawouach> I'm afraid the ConsoleEchoer doesn't work as you might expect in this case
[08:35] < Lawouach> have you tried without them?
[08:35] < Lawouach> at least without the one after OneShot
[08:37] < musashi> Hello Lawouach
[08:37] < musashi> Yes, but let me try again...
[08:40] < musashi> No result :(
[08:40] < musashi> Seems like the server doesn't get the message
[08:41] < Lawouach> hmm
[08:41] < musashi> The server protocol starts like that:
[08:41] < musashi> class FuncionsProtocol(Axon.Component.component):
[08:41] < musashi> def main(self):
[08:41] < musashi> self.handler = funcions()
[08:41] < musashi> while not self.shutdown():
[08:41] < musashi> yield 1
[08:41] < musashi> if self.dataReady("inbox"):
[08:41] < musashi> print "rebo dades"
[08:42] < musashi> using telnet I get the print, but using TCPClient I don't
[08:42] < Lawouach> this looks okay though
[08:44] < musashi> If I replace the OneShot with a ConsoleReader it works
[08:44] < Lawouach> right
[08:45] < musashi> But I need to use OneShot or something like that...
[08:45] < Lawouach> oh right
[08:46] < Lawouach> OneShot sends to the "signal" outbox rather than "inbox"
[08:46] < Lawouach> I mean outbox
[08:46] < Lawouach> damn no
[08:46] < Lawouach> grumble I'm confusing myself :)
[08:47] < musashi> hehehe
[08:47] < musashi> Trying also with DataSource(["insultam"]) but same results :(
[08:48] < Lawouach> oh right
[08:48] < Lawouach> your use of ConsoleEchoer was fair since you were setting the forwarder parameter to True
[08:48] < Lawouach> was the message printed to the console then?
[08:50] < musashi> yes, it gets printed
[08:51] < Lawouach> damn that's weird then
[08:51] < musashi> I know :D
[08:51] < Lawouach> I'm wondering if the message doesn't get lost before the client is actually connected
[08:52] < musashi> hmmm I understand...
[08:52] < Lawouach> well it's just a guess of course
[08:56] < musashi> Tried to move the TCPClient before the pipeline: myclient = TCPClient("localhost",port).activate,
[08:56] < musashi> and Pipeline(OneShot("message"),
[08:56] < musashi> myclient,).run()
[08:56] < musashi> but no luck also :(
[08:56] < Lawouach> activate()
[08:56] < musashi> on the pipeline or the TCPClient?
[08:56] < Lawouach> the client
[08:57] < musashi> without luck also :(
[08:57] < Lawouach> grumble
[09:00] < musashi> Ah, and anytime I run a kamaelia file I get a DeprecationWarning: the sets module is deprecated
[09:00] < musashi> import sets
[09:00] < musashi> but haven't considered this important...
[09:02] < Lawouach> this isn't
[09:02] < Lawouach> you're using Python 2.6 or above but that's fine
[09:02] < Lawouach> I do to ;)
[09:04] < musashi> Well, I actually had another question... :D
[09:05] < Lawouach> sure
[09:08] < musashi> I want to use the result of that Pipeline as the parameters of another... The first pipeline returns the host and port of a server, which is used in the next Pipeline:
[09:08] < musashi> Pipeline( ConsoleReader(eol=""),
[09:08] < musashi> TCPClient("localhost", 7000),
[09:08] < musashi> ConsoleEchoer()
[09:08] < musashi> ).run()
[09:08] < musashi> (this is the second)
[09:08] < Lawouach> right
[09:09] < musashi> Do I have to create something like a "Sink" that captures the data, or is there another way to do this? ... More "pipelined"?
[09:11] < Lawouach> a pipeline doesn't return anything in its output IIRC
[09:11] < Lawouach> meaning you might want to look at graphline perhaps
[09:11] < Lawouach> or use a backplane
[09:11] < Lawouach> I don't have a solution off the top of my head
[09:12] < musashi> Ok I'll try :)
[09:15] < musashi> But as I see graphlines, it's a way of specify the connections of the components... what I was looking is something to pass the parameters of host and port to TCPClient("localhost", 7000)... I am wrong about graph?
[09:16] < MS-> That latter question relates to this: http://www.kamaelia.org/Cookbook/Carousels
[09:17] < MS-> I think you can get a race hazard in the way you use TCPClient AFAICT if they're in the same piece of code. Specifically with sending data too soon (before the server has started)
[09:18] < MS-> Though there's something odd there, which I've not seen before as well, so looking into that as well.
[09:18] < MS-> testing with telnet would naturally just work in that scenario because delay of a person resolves the race
[09:19] < musashi> I see...
[09:20] < Lawouach> hello MS-
[09:20] < MS-> Code I'm playing with: http://code.google.com/p/kamaelia/source/browse/trunk/Sketches/MPS/Examples/OneShot_Race.py
[09:20] < MS-> Lawouach: heya
[09:20] < Lawouach> stayed up last night :)
[09:20] < MS-> I did for a while, yes
[09:20] < Lawouach> found that memory leak eventually?
[09:20] < MS-> having a rummage inside code
[09:20] < Lawouach> :)
[09:20] < MS-> I've got a candidate, yes
[09:21] < MS-> It's not due to a component not deactivating itself, it's due to the gc not collecting it.
[09:21] < MS-> Which is actually pretty easy to construct test cases for
[09:21] < MS-> musashi: client at line 35 can connect to the server, and send data
[09:21] < MS-> resulting in line 19 causing this to be emitted:
[09:22] < musashi> looking at it right now :)
[09:22] < MS-> msg 127.0.0.1 50112
[09:22] < musashi> that's just what I want :D
[09:22] < MS-> I'm currently a little inclear as to why ConsoleEchoer() doesn't *appear* to get the response, but I'm sure it'll become clear
[09:22] < musashi> trying it right now
[09:22] < MS-> I suspect buffering
[09:27] < MS-> OK, looks like that's right
[09:28] < MS-> How odd that's not come to light before...
[09:29] < MS-> Updated that example to emit several messages
[09:31] < MS-> I think it must be an issue in TCPClient, for what it's worth, because I've been running servers like this for a fair while (years)
[09:33] < MS-> OK, I'm checking in a version that allows you to telnet to a python console running inside that client/server system...
[09:33] < MS-> Way that is used:
[09:34] < MS-> ~/code.google/kamaelia/trunk/Sketches/MPS/Examples> ./OneShot_Race.py
[09:34] < MS-> Then in another window:
[09:34] < MS-> ~> telnet 127.0.0.1 8765
[09:34] < MS-> Trying 127.0.0.1...
[09:34] < MS-> Connected to 127.0.0.1.
[09:34] < MS-> Escape character is '^]'.
[09:34] < MS-> >>> self
[09:34] < MS-> Component Kamaelia.Experimental.PythonInterpreter.InterpreterTransformer_39 [ inboxes : {'control': [], 'inbox': []} outboxes : {'outbox': [], 'signal': []}
[09:35] < MS-> >>> [ str(x) for x in self.scheduler.threads.keys() ]
[09:35] < MS-> which looks like...
[09:35] < MS-> http://pastebin.com/m57619c00
[09:35] < MS-> From that we can see that the responses
[09:36] < MS-> which are missing, are rather suprisingly stuck inside the Echo component
[09:37] < MS-> I wonder if the client is sleeping...
[09:38] < MS-> Oh, that's wierd, the TCPClient isn't there!
[09:39] < MS-> Oh, I think I know what the problem is... I think it's been passed on a shutdown message, and shutdown
[09:39] < MS-> because the OneShot component has sent its message and shutdown
[09:41] < MS-> And sorted
[09:42] < MS-> Checking in a version that works
[09:44] < MS-> http://code.google.com/p/kamaelia/source/browse/trunk/Sketches/MPS/Examples/OneShot_Race.py Now uses a graphline instead
[09:45] < MS-> http://kamaelia.googlecode.com/svn/trunk/Sketches/MPS/Examples/OneShot_Race.py is the same file, but for anonymous checkouts
[09:46] < MS-> The issue with that code really is that TCPClient doesn't know if it's being used in any particular way
[09:46] < MS-> For sending, receiving or as a request/response thing
[09:46] < MS-> If it's request response you generally want to build something a little higher level to deal with that
[09:47] < MS-> Since OneShot & DataSource both emit producerFinished when they've sent their data
[09:47] < MS-> Whereas what you want to do is to get TCPClient to disconnect *after* it's recieved the response
[09:48] < MS-> Given it can't know what the response is supposed to be, or when it's supposed to get it you need something else controlling it
[09:53] < musashi> Thank you MS-! I understand the problem right now. As I just wanted to emit a message and get a single response I thought OneShot would do :)
[09:59] < MS-> In lots of cases it's fine, but there's occasionally little interactions to be aware of
[09:59] < MS-> could be argued that tcpclient needs more shutdown modes for example :)
[10:08] < MS-> Probably ought to package this up as a prefab which can just be instantiated and used in any piece of code:
[10:08] < MS-> http://pastebin.com/m2000f432
[10:37] < MS-> I am rather curious though as to what is actually going on in the original base case though
[11:48] *** salmon_ has joined #kamaelia
[12:46] < MS-> OK, it's very clear now that the key cause of the problem I'm seeing is due to something retaining a reference to socketobjects and ConnectedSocketAdapters
[12:47] < MS-> which means it's almost certainly related to cleanup issues
[12:47] < MS-> Probably inside servercore or TCPServer
[12:47] < MS-> time to start using "get_refererrers" methinks :)
[12:48] < Lawouach> the memory leak or the racing issue we saw earlier today?
[12:58] < MS-> mem leak
[12:58] < MS-> race issue was more a usage issue
[12:59] < MS-> Points at a usecase which needs a standard answer really. (eg an "expect" type component)
[13:00] < MS-> Digging through this leak is quite interesting. Certainly easier this way than it would be with either standard threads or with an event type system
[13:01] < MS-> For example, I can do this:
[13:01] < MS-> y=[x for x in Z if "Connected" in x.__class__.__name__]
[13:01] < MS-> at a prompt and rummage :)
[13:05] < Lawouach> nice
[13:08] < MS-> I'm then doing stuff like this:
[13:08] < MS-> >>> y[1]
[13:08] < MS-> Component Kamaelia.Internet.ConnectedSocketAdapter.ConnectedSocketAdapter_20
[13:08] < MS-> >>> y[0]
[13:08] < MS-> Component Kamaelia.Internet.ConnectedSocketAdapter.ConnectedSocketAdapter_12
[13:08] < MS-> To find out the specific CSA id
[13:08] < MS-> and then this to look in the scheduler:
[13:09] < MS-> [str(x) for x in self.scheduler.threads.keys() if "ConnectedSock" in str(x)]
[13:09] < MS-> Which tells me ConnectedSocketAdapter_20 is the dangling one
[13:11] < Lawouach> that's excellent
[13:11] < Lawouach> and most needed :p
[13:12] < Lawouach> it'd be nice to have a tool that performs a quick health check without having to do it manually
[13:12] < MS-> True.
[13:12] < MS-> I suppose codifying this particular sort of rummaging would help there
[13:12] < Lawouach> probably yes
[13:14] < MS-> heh, there's a dictionary that is using the actual connected socket (ie socket._socketobject) as a lookup for the CSA , and *that's* not had it's entry deleted
[13:18] *** salmon_ has joined #kamaelia
[15:06] < MS-> OK, socket object count stablised.
[15:06] < MS-> :)
[15:09] < Lawouach> sweet
[15:09] < Lawouach> that's really cool
[15:25] < MS-> Still hunting CSAs though, weirdly
[15:25] < MS-> But at least one part is sorted
[15:44] < MS-> I suppose part of the issue is this is amongst the oldest code in K and as a result has the greatest cruft factor
[15:44] < MS-> When something's not broke you don't fix it :)
[16:02] *** musashi has parted #kamaelia
[16:21] *** salmon_ has joined #kamaelia
[16:47] < MS-> Woo, think I've killed it.
[16:47] < MS-> That took longer than it should
[17:25] < MS-> That's actually quite an important bugfix, assuming I've got everything :-)
[17:37] *** vmlemon_ has joined #kamaelia
[17:55] < MS-> Yay, it really does look like that I've stomped on that memory leak in the basic TCP Server code properly :-D
[18:31] *** Lawouach has joined #kamaelia
[18:43] < MS-> Not sure if those fixes are sufficient to make the greylister stable (may have issues elsewhere), but certainly makes the server (CSA, socketobject) stable.
[20:06] < MS-> This is my bugs queue that I've started:
[20:06] < MS-> http://twitter.com/kamaeliabugs
[20:07] < MS-> When something's fixed, I delete the status update.