[kamaelia-list] Re: Small mod to console example doesn't work?

2009-03-03 Thread Gloria W

 Ah, I forgot the original context you were working in!
   
I did too :) I didn't communicate it clearly, I think. I was trying to 
accomplish too much too quickly.
This is exactly what I hoped for, a solution that would not force me to 
disconnect and reconnect.
Let me give this a go and get back to you tonight  EST, which is your 
morning tomorrow.
Thanks again!
Gloria
 All the suggestions I've made previously could be considered as trying to  
 this problem: that the ConsoleReader component not only reads user input,  
 but also generates a prompt for it (which it directly writes to the  
 console (standard output).

 It sounds like what you actually are after building is a simple chat  
 protocol - abstracted away from having to know about where its input is  
 coming from or where its output is going to. The ConsoleReader component  
 mixes a bit of both - it handles the sourcing of input, but also generates  
 some output itself (the prompt) and worse still, it puts this output onto  
 the console directly! :-)

 So what you're actually after is what you originally had:

  Pipeline(
  SourceOfInput(),
  MyComponent(),
  DestinationForOutput()
  )

 So for testing your chat protocol component MyComponent - we can still use  
 ConsoleReader and ConsoleEchoer. We just have to ignore the '' prompt  
 generated by the ConsoleReader and pretend its not there.

 When you plug Mycomponent into the ConnectedServer (also known as  
 SimpleServer in more recent subversion copies of Kamaelia iirc) as its  
 protocol, it gets wired up in much the same way as above - data coming  
  from the client will get send to its inbox and data send out of its outbox  
 will be sent back to the client.

 So all of the Seq stuff is not strictly necessary. All you need to do is  
 encode the sequential behaviour into the main() generator in MyComponent.  
 For example something along the lines of this (note the shutdown handling  
 makes it a little messier that it might otherwise be):

  def main(self):
  mustStop = false;

  # 1) generate login prompt
  self.send(Enter username:, outbox)

  # 2) wait for response
  mustStop = self.doShutdown()
  while not mustStop and not self.dataReady(inbox):
  self.pause()
  yield 1
  mustStop = self.doShutdown()

  if mustStop:
  return

  username = self.recv(inbox)

  # 3) welcome
  self.send(Welcome +username+! Begin chatting!)

  # 4) do chatting
  ...

 One other thing to consider is that the ConsoleReader specifically buffers  
 input until a whole line is received from the user, before outputting that  
 as a single string message to its outbox outbox. Whereas the socket  
 connection may send fragments of strings before a whole line has been  
 entered. A component such as this one can sort that out for you:  
 http://www.kamaelia.org/Components/pydoc/Kamaelia.Visualisation.PhysicsGraph.chunks_to_lines.html

 Simply pipeline it with MyComponent and make that the protocol thats given  
 to the ConnectedServer:

  def myProtocol():
  return Pipeline(
  chunks_to_lines(),
  MyComponent()
  )

  ...

  ConnectedServer(protocol=myProtocol, port=WHATEVER).run()



 Matt


 On Tue, 03 Mar 2009 04:35:07 -, Gloria W strang...@comcast.net wrote:

   
 I got the carousel example working, but it sends/receives from/to the
 original console, not any new client which connects. I realized I can
 reuse the ConsoleEchoer, but somehow make it send a string to a client
 upon connect, and have the server process the string instead of echoing
 it to the server's console.
 I tried this, but all proposed solutions so far write to the console,
 not a newly connected client. Maybe I am missing something, btu I think
 I am close.

  Aside from this, I was wondering if a carousel or seq will be
 appropriate to solve my problem.

 I am trying to simulate what happens in crude chat systems such as IRC.
 For simplicity, in this example the user connects, is prompted for a
 name, and then can chat freely.
 If I have two pipelines: one detects client connect and is prompting for
 a name, receiving the response, and then handing control over to another
 pipeline; doesn't this require a disconnect/reconnect with the client?
 If so, this would be bad, because the user would have to re-telnet in,
 would not be logged in, and would have to start again.

 So I guess if I get the data flow working, I can write this logic in one
 pipeline, and reuse the same connection, assuming the first thing a user
 types after connecting would be the name. Or maybe there is a clever way
 to hand off a connected pipline to another utility, so that my flow
 control is cleaner? (not running an if name is set check upon each
 message).

 Thanks again for your help,
 Gloria


 
  This is really 

[kamaelia-list] Re: Small mod to console example doesn't work?

2009-03-02 Thread Gloria W
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:

[kamaelia-list] Re: Small mod to console example doesn't work?

2009-03-02 Thread Matt

On Mar 2, 8:36 pm, Gloria W strang...@comcast.net wrote:
 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.

No problem.

I've just realised another way to achieve the same effect that is
probably simpler!

There *is* a component that is all about getting things done in an
order: the Seq component (The name is a homage to the OCCAM language):

http://www.kamaelia.org/Components/pydoc/Kamaelia.Chassis.Seq.html

With Seq, you provide a list of components. Seq goes through the list,
starting with the first component. It activates it and wires up its
inboxes and outboxes so that they're mapped to the Seq component's
inboxes and outboxes (just like the Carousel does). When that
component finishes, it then unwires it and moves onto the next in the
list. It therefore effectively runs them *in sequence* one after the
other.

We've got two steps: displaying the initial message, then taking user
input. Both steps need their output to be displayed. So we'll create a
Seq componet, Pipeline'd into a console echoer:

from Kamaelia.Chassis.Seq import Seq

Pipeline(
Seq( ... args to be determined! ... ),
ConsoleEchoer()
).run()

We can use a OneShot component (see 
http://www.kamaelia.org/Components/pydoc/Kamaelia.Util.OneShot.html
) to send that initial message, so that it gets sent to the
ConsoleEchoer and displayed. OneShot, rather conveniently, then
immediately terminates; so the Seq component will move onto the next
component in its list. That next component can be the Pipeline of a
ConsoleReader, sending its output into MyComponent.

So what we have is:

from Kamaelia.Chassis.Seq import Seq
from Kamaelia.Util.OneShot import OneShot

Pipeline(
Seq(
OneShot(initial message to be displayed),
Pipeline(
ConsoleReader(),
MyComponent()
)
),
ConsoleEchoer()
).run()

In this case, MyComponent doesn't need to bother to send the initial
message itself, as it did in the suggestion I previously made.

So what happens here? Well, when the system starts running, initially
the Seq component selects the first item in its list - the OneShot
component. So, what actually ends up getting wired up is something
like this:

Pipeline(
OneShot(initial message to be displayed),
ConsoleEchoer()
)

Its not actually exactly like that, because the OneShot is still
contained within the Seq component - but because all the inboxes and
outboxes are mapped to that of the Seq component, it is roughly
equivalent.

Then when the OneShot component has sent its message and terminated,
the Seq component swaps it out and replaces it with the next thing in
its list - the pipeline of a ConsoleReader and MyComponent. So the way
the system is wired up suddenly switches to something akin to this:

Pipeline(
Pipeline(
ConsoleReader(),
MyComponent()
),
ConsoleEchoer()
)

Again, the inner pipeline is, in reality, contained within the Seq
component, but it behaves roughly like it is shown.




Matt



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



[kamaelia-list] Re: Small mod to console example doesn't work?

2009-03-02 Thread Gloria W
This is really cool, and exactly what I need. I will get some time later 
to implement this and try it out, and I am sure I'll have more questions 
and comments.
Thanks again for this.
Gloria
 On Mar 2, 8:36 pm, Gloria W strang...@comcast.net wrote:
   
 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.
 

 No problem.

 I've just realised another way to achieve the same effect that is
 probably simpler!

 There *is* a component that is all about getting things done in an
 order: the Seq component (The name is a homage to the OCCAM language):

 http://www.kamaelia.org/Components/pydoc/Kamaelia.Chassis.Seq.html

 With Seq, you provide a list of components. Seq goes through the list,
 starting with the first component. It activates it and wires up its
 inboxes and outboxes so that they're mapped to the Seq component's
 inboxes and outboxes (just like the Carousel does). When that
 component finishes, it then unwires it and moves onto the next in the
 list. It therefore effectively runs them *in sequence* one after the
 other.

 We've got two steps: displaying the initial message, then taking user
 input. Both steps need their output to be displayed. So we'll create a
 Seq componet, Pipeline'd into a console echoer:

 from Kamaelia.Chassis.Seq import Seq

 Pipeline(
 Seq( ... args to be determined! ... ),
 ConsoleEchoer()
 ).run()

 We can use a OneShot component (see 
 http://www.kamaelia.org/Components/pydoc/Kamaelia.Util.OneShot.html
 ) to send that initial message, so that it gets sent to the
 ConsoleEchoer and displayed. OneShot, rather conveniently, then
 immediately terminates; so the Seq component will move onto the next
 component in its list. That next component can be the Pipeline of a
 ConsoleReader, sending its output into MyComponent.

 So what we have is:

 from Kamaelia.Chassis.Seq import Seq
 from Kamaelia.Util.OneShot import OneShot

 Pipeline(
 Seq(
 OneShot(initial message to be displayed),
 Pipeline(
 ConsoleReader(),
 MyComponent()
 )
 ),
 ConsoleEchoer()
 ).run()

 In this case, MyComponent doesn't need to bother to send the initial
 message itself, as it did in the suggestion I previously made.

 So what happens here? Well, when the system starts running, initially
 the Seq component selects the first item in its list - the OneShot
 component. So, what actually ends up getting wired up is something
 like this:

 Pipeline(
 OneShot(initial message to be displayed),
 ConsoleEchoer()
 )

 Its not actually exactly like that, because the OneShot is still
 contained within the Seq component - but because all the inboxes and
 outboxes are mapped to that of the Seq component, it is roughly
 equivalent.

 Then when the OneShot component has sent its message and terminated,
 the Seq component swaps it out and replaces it with the next thing in
 its list - the pipeline of a ConsoleReader and MyComponent. So the way
 the system is wired up suddenly switches to something akin to this:

 Pipeline(
 Pipeline(
 ConsoleReader(),
 MyComponent()
 ),
 ConsoleEchoer()
 )

 Again, the inner pipeline is, in reality, contained within the Seq
 component, but it behaves roughly like it is shown.




 Matt



 

   


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



[kamaelia-list] Re: Small mod to console example doesn't work?

2009-03-02 Thread Gloria W
I got the carousel example working, but it sends/receives from/to the 
original console, not any new client which connects. I realized I can 
reuse the ConsoleEchoer, but somehow make it send a string to a client 
upon connect, and have the server process the string instead of echoing 
it to the server's console.
I tried this, but all proposed solutions so far write to the console, 
not a newly connected client. Maybe I am missing something, btu I think 
I am close.

 Aside from this, I was wondering if a carousel or seq will be 
appropriate to solve my problem.

I am trying to simulate what happens in crude chat systems such as IRC.
For simplicity, in this example the user connects, is prompted for a 
name, and then can chat freely.
If I have two pipelines: one detects client connect and is prompting for 
a name, receiving the response, and then handing control over to another 
pipeline; doesn't this require a disconnect/reconnect with the client? 
If so, this would be bad, because the user would have to re-telnet in, 
would not be logged in, and would have to start again.

So I guess if I get the data flow working, I can write this logic in one 
pipeline, and reuse the same connection, assuming the first thing a user 
types after connecting would be the name. Or maybe there is a clever way 
to hand off a connected pipline to another utility, so that my flow 
control is cleaner? (not running an if name is set check upon each 
message).

Thanks again for your help,
Gloria


  This is really cool, and exactly what I need. I will get some time 
 later to implement this and try it out, and I am sure I'll have more 
 questions and comments.
 Thanks again for this.
 Gloria
 On Mar 2, 8:36 pm, Gloria W strang...@comcast.net wrote:
   
 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.
 

 No problem.

 I've just realised another way to achieve the same effect that is
 probably simpler!

 There *is* a component that is all about getting things done in an
 order: the Seq component (The name is a homage to the OCCAM language):

 http://www.kamaelia.org/Components/pydoc/Kamaelia.Chassis.Seq.html

 With Seq, you provide a list of components. Seq goes through the list,
 starting with the first component. It activates it and wires up its
 inboxes and outboxes so that they're mapped to the Seq component's
 inboxes and outboxes (just like the Carousel does). When that
 component finishes, it then unwires it and moves onto the next in the
 list. It therefore effectively runs them *in sequence* one after the
 other.

 We've got two steps: displaying the initial message, then taking user
 input. Both steps need their output to be displayed. So we'll create a
 Seq componet, Pipeline'd into a console echoer:

 from Kamaelia.Chassis.Seq import Seq

 Pipeline(
 Seq( ... args to be determined! ... ),
 ConsoleEchoer()
 ).run()

 We can use a OneShot component (see 
 http://www.kamaelia.org/Components/pydoc/Kamaelia.Util.OneShot.html
 ) to send that initial message, so that it gets sent to the
 ConsoleEchoer and displayed. OneShot, rather conveniently, then
 immediately terminates; so the Seq component will move onto the next
 component in its list. That next component can be the Pipeline of a
 ConsoleReader, sending its output into MyComponent.

 So what we have is:

 from Kamaelia.Chassis.Seq import Seq
 from Kamaelia.Util.OneShot import OneShot

 Pipeline(
 Seq(
 OneShot(initial message to be displayed),
 Pipeline(
 ConsoleReader(),
 MyComponent()
 )
 ),
 ConsoleEchoer()
 ).run()

 In this case, MyComponent doesn't need to bother to send the initial
 message itself, as it did in the suggestion I previously made.

 So what happens here? Well, when the system starts running, initially
 the Seq component selects the first item in its list - the OneShot
 component. So, what actually ends up getting wired up is something
 like this:

 Pipeline(
 OneShot(initial message to be displayed),
 ConsoleEchoer()
 )

 Its not actually exactly like that, because the OneShot is still
 contained within the Seq component - but because all the inboxes and
 outboxes are mapped to that of the Seq component, it is roughly
 equivalent.

 Then when the OneShot component has sent its message and terminated,
 the Seq component swaps it out and replaces it with the next thing in
 its list - the pipeline of a ConsoleReader and MyComponent. So the way
 the system is wired up suddenly switches to something akin to this:

 Pipeline(
 Pipeline(
 ConsoleReader(),
 MyComponent()
 ),
 ConsoleEchoer()
 )

 Again, the inner pipeline is, in reality, contained within the Seq
 component, but it behaves roughly like it is shown.




 Matt





   


 



[kamaelia-list] Re: Small mod to console example doesn't work?

2009-03-01 Thread Michael Sparks

On Sunday 01 March 2009 06:51:09 Gloria W wrote:
  Hi all,
  I am testing things, trying to get a small modification to this example
 working correctly: http://www.kamaelia.org/Home

By this, I'm assuming you mean this:

http://pastebin.com/m529b7499

  I've simple added this line:

  self.send(Testing..1.2.3...,'outbox')

  between these two lines:


 while not self.doShutdown():
 if self.dataReady(inbox):

Like this?
http://pastebin.com/m70a968b7

ie (diff) :
http://pastebin.com/pastebin.php?diff=m70a968b7

 and it does nothing. yielding it also does nothing. I should be able to
 write to the console without receiving data from it, I hope. What am I
 missing?

I'm not sure. The pastebin above works. (floods the screen
with Testing..1.2.3... )

 Also, this is interesting:
ChatServer(port=1501).run()
...
 /usr/lib/python2.5/site-packages/Kamaelia/Internet/TCPServer.py, line
 144, in makeTCPServerPort s.bind((HOST,PORT))
    File string, line 1, in bind
  socket.error: (98, 'Address already in use')


  It locks the port for about a minute after every run, then finally frees
 it, this error goes away, and I can finally reconnect.

That's normal and part of the TCP stack's normal behaviour. In that 60 
seconds, if you quickly type:

  netstat -natp |grep TIME_WAIT

You'll see a line like this:
tcp0  0 127.0.0.1:1500  127.0.0.1:48846 TIME_WAIT

From this diagram:
http://ssfnet.org/Exchange/tcp/Graphics/tcpStateDiagram1.gif

You'll see that if the server side ends up in this state (bottom middle of the 
diagram) that it's expected to wait for 2 segment lifetimes ... which is your 
60 seconds.

Can you change this behaviour ? Yes. 2 ways: 1) on the system globally. 
Generally considered a bad idea, unless you really know what you're doing.
2) Change the behaviour of the server to say yes, allow this port to be 
reused, even within the 2 segment lifetimes.

The latter you do by changing the socket options.

Assuming you've done this:

class ChatServer(ServerCore):


You add in this:

class ChatServer(ServerCore):
socketOptions=(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)


Alternatively, if you don't want change the ChatServer class definition, you 
can change this line:
ChatServer(port=1501).run()

To:
ChatServer(port=1501,
socketOptions=(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
).run()

One thing I've thought about several times is whether this reuse of the socket 
address should be the default or not. There are pros and cons.

Pros:
1 Don't have this explanation periodically :)
2 Allows instant server respawn
3 Simplifies many setups

Cons:
1 When it goes wrong harder to explain why :)
2 Instant server respawn means that clients connected which are expecting
   segments can get confused. Generally this means they'll get a socket
   error and need to reconnect. That said, if the server restarts, that'd
   be necessary anyway, with or without the MSL behaviour.
   - Specifically what's happening in this scenario is the server is
shutting down without the clients being disconnected, leaving each
connection in an unexpected state, hence the TIME_WAIT state on the
server socket.
3 Need a way of switching off this behaviour.

Personally I think pro.3 outweighs everything else, but I don't generally like 
reusing default behaviours.

  Thanks in advance for your help!

You're welcome :)


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