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