> I'm not sure what you mean by this, so I'll explain what's going on in server > core, first of all from a historical perspective, then raw mechanics, and > then by analogy - and then relate your examples back to the analogy. > > The file Kamaelia/Chassis/ConnectedServer.py contains two classes that define > components, which are defined as follows: > > class ServerCore(Axon.AdaptiveCommsComponent.AdaptiveCommsComponent): > ....[major snip] > > and: > class SimpleServer(ServerCore): > ....[major snip] > > Historically speaking, the latter name (SimpleServer) came first, and lasted > us very well for a long while. Then I needed to start creating protocol > handlers which had some information about each connection. Specifically > I started writing a greylister. > > To do that, I wrote a modified version of SimpleServer which captured the > information and passed it onto the protocol handler. This modified version > was rather unimaginatively called "MoreComplexServer" :) > Yes, I think you're getting to the crux of my question, which was how to determine and even control the protocol used below the component layer. Maybe I should not be thinking of doing this below the component layer, but instead as a separate component? > After that was known stable, it was obvious that "MoreComplexServer" had a > superset of functionality of SimpleServer. Specifically, the only difference > between them in practice (after refactoring both) was this: > > def mkProtocolHandler(self, **sock_info): > return (self.protocol)() > vs > def mkProtocolHandler(self, **sock_info): > > return (self.protocol)(peer = sock_info["peer"], > peerport = sock_info["peerport"], > localip = sock_info["localip"], > localport = sock_info["localport"]) > > At that point it made sense to consolidate the two, under the don't repeat > yourself principle, and simply make simpleserver a subclass of server core. > > In terms of operation, ServerCore is somewhat like the organiser at a dance, > or the manager of an office. It doesn't actually do any of the real work > itself - for example: > * It doesn't listen on the main listener socket > * It doesn't handle accepting connections > * It doesn't handle the mechanics of handling the connections. >
> * It doesn't handle the protocol itself. > !!!!! Thank you. That caused an 'Ah-ha' moment. I'm getting this now. > But what it DOES know, is it knows a whole bunch of components who DO know > how > to do those things, and organises them to get the work done. > > Indeed, when it starts up it looks like this: > * http://www.kamaelia.org/t/LifeCycle1.png > > So... > * ServerCore (SC) creates a TCPServer[1] (TCPS) instance, which: > * http://www.kamaelia.org/t/LifeCycle2.png > > * Listens on the server socket > > * Waits for people to connect, and when they do it accepts the > connection, and creates a new ConnectedSocketAdapter (CSA) > component to handle to raw mechanics of talking to the connection: > > http://www.kamaelia.org/t/LifeCycle2a.png > > Since it needs to know when that component is finished, among other > things it does, a links the ConnectedSocketAdapter (CSA) back to > the TCPServer (TCPS) to enable cleanup. > > * TCPServer (TCPS) knows that the ConnectedSocketAdapter (CSA) is > competent at handling the connection, it also knows it's rather > dumb/boring. Specifically, it only forwards data from the socket > to "outbox" and data from "inbox" to the socket. > > * TCPServer (TCPS) therefore sends the ConnectedSocketAdapter (CSA) to > ServerCore (SC), effectively saying "New Connection, please handle > this somehow". > Fantastic. Thanks for breaking out the protocol layer in this way. It helped. I am so used to such a tight binding between protocol and transport layer, and this abstraction is really nice. > * As noted ServerCore (SC) doesn't know how to do anything itself, but we > did give it a protocol factory when we started it, so what it does > next is create a Protocol Handler (PH) using that, and wires it up to > the ConnectedSocketAdapter - cf: > * http://www.kamaelia.org/t/LifeCycle2b.png > > * Finally the ServerCore creates a bunch of admin links to enable > shutdown: > * http://www.kamaelia.org/t/LifeCycle3.png > > [1] Perhaps better called a TCPListener in retrospect. > Got it, thanks. > [snip amusing informative info] > > (you might be able to blame TRON for me thinking like this =) > I just recently re-watched TRON and remembered why I enjoyed it the first time (I must have been about ten years old when I first saw it, and I distinctly remember spending whatever money I had on that great video game). > [2] I know, I know, analogies break down after a while. > > Now in this example: > * http://pastebin.com/m77f942a9 > > SimpleServerTest takes the role of the chef, and: > * Takes the orders he's sent and prints the to stdout > * Sends the order back to the customer > > In this example: > * http://pastebin.com/m1314ebb0 > > Each chef looks like this: > > Pipeline( > PureTransformer(lambda x: " %s:%s says %s" % (str(peer), > str(peerport), str(x))), > PublishTo("CHAT"), > # ---------------------------- > SubscribeTo("CHAT"), > PureTransformer(lambda x: "Chat:"+ str(x).strip()+"\n"), > ) > > Which says: > * Post every order we recieve on the backplane "Chat", after reformatting > it slightly. > * Post every message seen on the backplane "Chat" back to the customer, > after reformatting slightly. > Yeah, the backplane really rocks. I compared it to the two to three pages of Twistd code I had to write to accomplish the exact same thing, a simple publish/subscribe broadcast channel, and wow, what a difference. I am definitely using this in my PyCon tutorial, but I want to be able to intelligently talk about how the backplace and the underlying protocol interact. I feel like I can do that now. Yaay! > At the end of the day, all this means is this: > * In order to create a protocol handler, you just create write code that > handles the core interaction. > To learn about this, I am poking around in the Kamaelia/Protocl dir, looking at the HTTPServer, and the socket handlers, the level of socket control and notification, looks so nice. In Twistd, it's not exposed to you, and for long keepalive times, you're stuck handling the write error if the socket state changes, wherever you attempt to write. Of course, I am still be stuck getting unexpected socket states from the client, and handling them, but at least this is abstracted from my logic, and handled within the protocol. Very nice indeed. I think I will experiment with my own protocol definition and see what happens (probably a simple UDP implementation, just for demo purposes). > BTW, I'll see if I can knock up a simple staged protocol later today (I've > got > a few things I have to do today, but will try and make time to do that). > Do you mean ServerCore using a different protocol other than a TCP listener internally, or another example of a protocol passed to ServerCore, or something else? Thanks again for taking the time and energy to do this. I think at PyCon, when people mask the hard questions, we're going to be walking through Kamaelia code. It is the best way to see what's going on. It would be great to have you on live chat, to answer the stuff we cannot figure out directly from the code, or if we get stuck somewhere. Can this work? Thanks again! Gloria --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "kamaelia" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/kamaelia?hl=en -~----------~----~----~----~------~----~------~--~---
