On Sunday 08 March 2009 07:27:09 Gloria W wrote:
> And ServerCore seems to be two components linked together, while the
> first example is a derivative component.

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" :)

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.

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".

    * 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.

ie effectively, ServerCore (SC) organises a dance of people who do know what
they're doing, creates links between them so they can do their jobs and gets
out of the way until they're needed to handle something. (in a way, a bit like
an ideal manager - gets you resources, enables you to do your job provides you
with tasks within your skillset, but otherwise stays out of your way).

Further anthropomorphising.... (humour me, it's a sunday :)
    * Sam Charles (SC) buys a sushi bar, but doesn't know anything about how
       how to do this, aside from manage people.

    * So he hires Thomas Charles Peter Smith (TCPS) to stand at front of house
       to meet and greet customers. TCPS has a direct line to a temp agency
       who can supply waiting staff on demand. 

    * A customer walks in, and TCPS calls "Catering Staff Assured" who
       send over one of their staff (CSA). The customer is now their
       responsibility. CSA can't cook, but can take orders and give them to a
       chef, and take food from the chef to the customer.

    * Thomas (TCPS) understands this, and tells Sam (SC) that there's a new
       customer, this CSA is handling them and they need a chef, pronto.

    * Sam (SC) wanted his restaurant to allocate one chef per customer, and
       has close ties to another agency - Paul Henri ltd - which supplies
       sushi chefs on demand.[2] Anyone, he calls them, and gets a Paul Henri
       (PH) in. Sam introduces PH to CSA. CSA handles the interaction with the
       customer, and PH transforms orders into food.

(you might be able to blame TRON for me thinking like this =)

[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.

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.

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).

Regards,


Michael.
-- 
http://yeoldeclue.com/blog
http://twitter.com/kamaelian
http://www.kamaelia.org/Home

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to