Matt, thanks for this response. It took me a while to get through it and 
make sure I understood each point. I appreciate it, comments are below.

>> This is true, thanks. Now let's say I wanted to write to the client's
>> console before reading anything from their console.
>>
>> With no other changes, this Pipeline setting doesn't work:
>> Pipeline(
>>                  MyComponent(),
>>                  ConsoleReader(),
>> ).run()
>>
>> but I am expecting it to work. What am I missing?
>>     
>
> "Pipeline" isn't about saying what order to run things in - its more like  
> expressing how to plug things together: The declaration above is saying:  
> """ Make two components - an instance of MyComponent and an instance of  
> ConsoleReader; now plug them together so that the "outbox" of  
> "MyComponent" is joined to the "inbox" of "ConsoleReader" """
>   
I was assuming an order of operations here, Thanks for the correction. 
It makes sense.
>   
>> This is true, thanks. Now let's say I wanted to write to the client's
>> console before reading anything from their console.
>>     
>
> So you want a program where the flow of data is as follows:
>
>     input from console ---> MyComponent ----> output to console
>   
I guess it would be more like:

         send a one-time prompt for input to the client's console ---> 
read client's response and send to MyComponent

then create the flow you specified:

input from console ---> MyComponent ----> output to console



Imagine, for example, taking the SimpleChatServer example, and sending 
an "Enter your chat name" prompt, getting a response, and THEN 
connecting the user to the server.
[snip]
> Thats the simple version. Now a little more complexity! ...
>
> The above code won't guarantee is whether the "initial message for the  
> console" is displayed before the prompt that is displayed by the  
> ConsoleReader. Why is this? Because the Pipeline declaration effectively  
> says "make all these and start them all at teh same time".
>   
Got it. Thanks. This helped greatly.
> If you want explicit behaviour where a component isn't created or  
> activated, or wired up until a later point in the execution (ie. you want  
> to control the order things happen in) then you need to express it  
> explicitly.
>
> Here's *a* way to do it:
>
> We can use the Carousel component do delay the creation and wiring up of  
> the ConsoleReader component until MyComponent sends a message telling it  
> to do so. There's some explanation of Carousel here:  
> http://www.kamaelia.org/Cookbook/Carousels if it helps.
>
> In short, Carousel is designed to contain another component. When it  
> receives a message, it calls a helper function (that you supply) to create  
> a component. It then takes that component and wires it up so that its  
> "outbox" and "inbox" are mapped to the "outbox" and "inbox" of the  
> Carousel component itself. We'll declare this helper globally for now:
>
>      def makeConsoleReader(message):         # we ignore the parameter
>          return ConsoleReader()
>
>
> So that MyComponent can send a message to the Carousel, we'll need to add  
> an extra outbox to MyComponent, and get it to send that signal:
>
>      Class MyComponent(component):
>          Outboxes = {"outbox"      : "some data out",
>                      "signal"      : "Shutdown signal",
>                      "ready"       : "Sends a message when initialisation  
> is complete",
>                     }
>
>          ...
>
>          def main(self):
>          self.send("Initial message for the console", "outbox")
>
>          yield 1
>
>          self.send("OK", "ready")
>
>          while not self.doShutdown():
>              if self.dataReady("inbox"):
>              data = self.recv("inbox")
>              # let's echo what we received...
>              self.send(data, 'outbox')
>
>              if not self.anyReady():
>                  self.pause()
>
>              yield 1
>
> Note the 'yield' statements - which give other components a chance to run  
> - giving the ConsoleEchoer a chance to display that initial message.  
>   
Makes sense, thanks!
> Remember that we don't control the precise order in which components  
> execute: if we sent the initial message and the ready message without a  
> yield in between, we might be unlucky, and the Carousel might get executed  
> first!
>
> We cannot use a simple pipeline now, since we need to also wire up the  
> "ready" outbox of MyComponent to the Carousel's "next" inbox. A Pipeline  
> only wires up the standard "inbox" and "control" inboxes and "outbox" and  
> "signal" outboxes. So we'll use a Graphline instead, where we specify each  
> linkage explicitly:
>
>      from Kamaelia.Chassis.Carousel import Carousel
>      from Kamaelia.Chassis.Graphline import Graphline
>
>      ....
>
>      Graphline(
>          READER = Carousel(makeConsoleReader),
>          MYCOMP = MyComponent(),
>          OUTPUT = ConsoleEchoer(),
>          linkages = {
>              # main flow of data:
>              ("READER", "outbox") : ("MYCOMP", "inbox"),
>              ("MYCOMP", "outbox") : ("OUTPUT", "inbox"),
>
>              # the 'ready' message:
>              ("MYCOMP", "ready")  : ("READER", "next"),
>
>              # the 'signal' and 'control' boxes used for shutdown:
>              ("READER", "signal") : ("MYCOMP", "control"),
>              ("MYCOMP", "signal") : ("OUTPUT", "control"),
>
>          }
>      ).run()
>
> So what should happen when this runs?
>
> 1) The components are created and wired up as shown above.
>
> 2) They all start executing.
>
> 2a) The Carousel and ConsoleEchoer only do stuff in response to messages  
> they receive, so they sit there waiting. Only MyComponent really starts  
> doing anything significant
>
> 3) MyComponent sends out its "initial message" out of its "outbox". The  
> ConsoleEchoer receives this and displays the message on the console
>
> 4) MyComponent sends a message out of its "ready" outbox, and it is  
> received at the "next" inbox of the Carousel.
> 4a) The Carousel uses the makeConsoleReader() function we wrote to create  
> a ConsoleReader component. It gets wired up so that it uses the outboxes  
> and inboxes of the Carousel.
> 4b) The ConsoleReader component also gets activated, and so its main()  
> method starts running. It therefore displays its prompt for user input
>
> 5) When the user enters input, the ConsoleReader sends out of its "outbox"  
> to the "inbox" of MyComponent.
>
>
>
> Hmm, more long winded than I originally hoped this would be. Hope it helps  
> though.
>   
This helped greatly. I'll run this and play some more. 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 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