Re: POE sessions, clients, confused

2005-01-28 Thread Bas Schulte
Hi,
On vrijdag, jan 28, 2005, at 03:10 Europe/Amsterdam, Rocco Caputo wrote:
On Thu, Jan 27, 2005 at 12:40:56PM -0800, David Davis wrote:
Response below.
On Thu, 27 Jan 2005 20:15:22 +0100, Bas Schulte 
[EMAIL PROTECTED] wrote:
Hi David,
On donderdag, jan 27, 2005, at 00:45 Europe/Amsterdam, David Davis
wrote:
Don't pass the client wheel, that's bad when using post.
Argh. I don't understand why I can't pass the reference to the wheel
though. Why is it bad?
It has to do with garbage collection.  Wheels are linked to the
session, and if you want to have it properly clean up and disconnect,
don't pass it around.
Rocco, please chime in if I'm wrong.
Here's a previous message where I explained it:
http://aspn.activestate.com/ASPN/Mail/Message/2096709
In that message, it says this:
Rather, you create an event handler for your TCP connections.  The
handler accepts messages from the outside and transmits their payloads
from within the proper context.  It's as if the session has opened a
port through which data can enter its context.
(with some more explanation)
Right. There we have it :)
When the ClientInput state runs, it receives a command from the client, 
the (translated) command is sent to another session like this:

$kernel-post($heap-{controllingSession}, 'do_the_actual_start', 
$with_parameter_1, $and_parameter_2);

Then in the do_the_actual_start state, this gets the parameters:
sub controller_start
{
   my ($kernel, $heap, $session, $parameter1, $parameter2) = @_[KERNEL, 
HEAP, SESSION, ARG0, ARG1];

   # do the POE::Wheel::Run thing here
   # And send response via client tcp session (the SENDER):
   $kernel-post($_[SENDER] = send_response = OK);
}
Thanks all for the learning experience!
Cheers,
Bas.


Re: POE sessions, clients, confused

2005-01-27 Thread Bas Schulte
Hi David,
On donderdag, jan 27, 2005, at 00:45 Europe/Amsterdam, David Davis 
wrote:

Can I start a new session in client_input, start a new POE::Wheel::Run
from there *in* the ClientInput state? Or does that create a
(parent-child?) dependency with the POE::Component::Server::TCP
session? That runs sour when the client disconnects?
Yes it does create a wheel in that session handling the input for that 
client.
Your session_stdout even is getting sent to that session, and you
don't have an event by that name in that session created by
Server::TCP.
Yes, this part I understand now :)

sub client_input
{
my ($session, $heap, $kernel, $input, $wheel) = @_[ SESSION, HEAP,
KERNEL, ARG0, ARG1 ];
## pass client's input and reference to our wheel
$kernel-post($heap-{controllingSession}, 'do_the_start', $input,
$heap-{client});
Don't pass the client wheel, that's bad when using post.
Argh. I don't understand why I can't pass the reference to the wheel 
though. Why is it bad?


 It would be
better if you used $kernel-post($_[SENDER] = send = 'OK');  and
setup an inline_state called send that did a if ($heap-{client}) {
$heap-{client}-put($_[ARG0]); }
I tried it, seems to work fine.

You could also change this to a call() and be ok with using it as a
hack.  Just don't pass wheel handles around freely.
I don't want a hack :)
I still don't understand what the right solution is though. I saw 
something about detaching a session from it's parent as well. Maybe I 
can create a session in the tcp server session, start the wheel in that 
child session and then detach that session from the tcp server's 
session. Sounds ok to me but I'm still not sure what the right way is.


Just don't pass wheel handles around freely.
Does that mean I can't pass the result of POE::Wheel::Run-new(...) 
around as well? I have this:

my $child = new POE::Wheel::Run();
Then I keep the $child around so I can kill it later on. Is that bad?
Thanks,
Bas.


Re: POE sessions, clients, confused

2005-01-27 Thread David Davis
Response below.

On Thu, 27 Jan 2005 20:15:22 +0100, Bas Schulte [EMAIL PROTECTED] wrote:
 Hi David,
 
 On donderdag, jan 27, 2005, at 00:45 Europe/Amsterdam, David Davis
 wrote:
 
  Can I start a new session in client_input, start a new POE::Wheel::Run
  from there *in* the ClientInput state? Or does that create a
  (parent-child?) dependency with the POE::Component::Server::TCP
  session? That runs sour when the client disconnects?
 
  Yes it does create a wheel in that session handling the input for that
  client.
  Your session_stdout even is getting sent to that session, and you
  don't have an event by that name in that session created by
  Server::TCP.
 
 Yes, this part I understand now :)
 
 
  sub client_input
  {
  my ($session, $heap, $kernel, $input, $wheel) = @_[ SESSION, HEAP,
  KERNEL, ARG0, ARG1 ];
 
  ## pass client's input and reference to our wheel
 
  $kernel-post($heap-{controllingSession}, 'do_the_start', $input,
  $heap-{client});
 
  Don't pass the client wheel, that's bad when using post.
 
 Argh. I don't understand why I can't pass the reference to the wheel
 though. Why is it bad?

It has to do with garbage collection.  Wheels are linked to the
session, and if you want to have it properly clean up and disconnect,
don't pass it around.

Rocco, please chime in if I'm wrong.

 
   It would be
  better if you used $kernel-post($_[SENDER] = send = 'OK');  and
  setup an inline_state called send that did a if ($heap-{client}) {
  $heap-{client}-put($_[ARG0]); }
 
 I tried it, seems to work fine.

It seems to...

 
 
  You could also change this to a call() and be ok with using it as a
  hack.  Just don't pass wheel handles around freely.
 
 I don't want a hack :)

Nor do I want to suggest one.

 I still don't understand what the right solution is though. I saw
 something about detaching a session from it's parent as well. Maybe I
 can create a session in the tcp server session, start the wheel in that
 child session and then detach that session from the tcp server's
 session. Sounds ok to me but I'm still not sure what the right way is.
 

You could do that.  I have never tried it though.  Something like this
might work:

POE::Session-create(
  inline_states = {
_start = {
$_[HEAP]-{wheel} = POE::Wheel::Run-...
$_[KERNEL]-detach_myself();
},
 [ other events ]
  },
);

 
  Just don't pass wheel handles around freely.
 
 Does that mean I can't pass the result of POE::Wheel::Run-new(...)
 around as well? I have this:
 
 my $child = new POE::Wheel::Run();
 
 Then I keep the $child around so I can kill it later on. Is that bad?

No, keeping it in the heap is fine. When the wheel dies off (program
finishes) the session will clean itself up and go away.

 
 Thanks,
 
 Bas.
 
 

-- 
David Davis
Perl Programmer
http://teknikill.net/

Try CPAN Suggest!
http://cpan.teknikill.net/


Re: POE sessions, clients, confused

2005-01-27 Thread Rocco Caputo
On Thu, Jan 27, 2005 at 12:40:56PM -0800, David Davis wrote:
 Response below.
 
 On Thu, 27 Jan 2005 20:15:22 +0100, Bas Schulte [EMAIL PROTECTED] wrote:
  Hi David,
  
  On donderdag, jan 27, 2005, at 00:45 Europe/Amsterdam, David Davis
  wrote:
  
   Don't pass the client wheel, that's bad when using post.
  
  Argh. I don't understand why I can't pass the reference to the wheel
  though. Why is it bad?
 
 It has to do with garbage collection.  Wheels are linked to the
 session, and if you want to have it properly clean up and disconnect,
 don't pass it around.
 
 Rocco, please chime in if I'm wrong.

Here's a previous message where I explained it:

http://aspn.activestate.com/ASPN/Mail/Message/2096709

-- 
Rocco Caputo - http://poe.perl.org/


Re: POE sessions, clients, confused

2005-01-26 Thread David Davis
Setup another session to handle wheel run, and use $_[SENDER] to reply
back if the client is still connected.

-- 
David Davis
Perl Programmer
http://teknikill.net/

Try CPAN Suggest!
http://cpan.teknikill.net/

On Wed, 26 Jan 2005 19:43:15 +0100, Bas A. Schulte
[EMAIL PROTECTED] wrote:
 Hi all,
 
 I have a conceptual question about POE and it's sessions that I have
 some trouble with.
 
 I'm trying to write a POE::Component::Server::TCP server that reads
 command lines from the client (well, not really, in reality it's some
 sort of reference that gets fed to another application on it's command
 line), then needs to execute that command, and respond with feedback
 that the process was started. The new process will run for quite some
 time, whilst the client will disconnect before that.
 
 In short: clients logs in on some port, says launch b, then a process
 launch is exec-ed using POE::Wheel::RUN, and that child is monitored
 by the main session.
 
 My simple initial approach was this:
 
 my $server = new POE::Component::Server::TCP(
Alias   = lala,
Port= ,
ClientInput = \client_input,
 );
 
 $poe_kernel-run();
 
 sub client_input
 {
my ($input) = @_[ ARG0 ];
 
...
 
my $child = new POE::Wheel::Run(
 
   Program= $input,  ## Not recommended :)
 
   ...
 
   StdoutEvent= 'session_stdout',
 
   ...
);
 
$heap-{client}-put(Ok, I started $input for you successfully);
 }
 
 This doesn't work: the 'StdoutEvent' event is posted to the session
 that's running client_input (session created by
 POE::Component::Server::TCP for this connection).
 
 How am I supposed to handle this?
 
 Right now, I validate the client input, then put the request to start on
 a queue that I check in another session. This works but it won't report
 back a failure to launch the process to the client. For example, when
 the process to launch is a perl script that fails to compile or
 something.
 
 Maybe I need to put the request to start on the queue, AND somehow add
 the client session reference to it as well, and respond back from my
 main session instead of directly in client_input?
 
 I'm somewhat confused right now, hope someone can clear this one up :)
 
 Thanks in advance,
 
 Bas.



Re: POE sessions, clients, confused

2005-01-26 Thread Ofer Nave
David Davis wrote:
Setup another session to handle wheel run, and use $_[SENDER] to reply
back if the client is still connected.
 

Also, check out POE::Component::Child.  I just started using it, and it 
works quite nicely.  It's a wrapper around POE::Wheel::Run and is 
stand-alone, so you don't need to set up a session just to contain the 
wheel.

-ofer


Re: POE sessions, clients, confused

2005-01-26 Thread Erick Calder
 Also, check out POE::Component::Child.

which reminds me I have some patches I need to release, and I better
do it before my upcoming vacation in mid Feb too!


Re: POE sessions, clients, confused

2005-01-26 Thread Bas Schulte
Hi David,
On woensdag, jan 26, 2005, at 20:01 Europe/Amsterdam, David Davis wrote:
Setup another session to handle wheel run, and use $_[SENDER] to reply
back if the client is still connected.
That's a bit too compact for me :)
Where do I do what, that's basically my problem:
Can I start a new session in client_input, start a new POE::Wheel::Run 
from there *in* the ClientInput state? Or does that create a 
(parent-child?) dependency with the POE::Component::Server::TCP 
session? That runs sour when the client disconnects?

I'm confused as to what session should manage the events fired by the 
POE::Wheel that manages my child. I think I need to detach the 
started wheel from the tcp session but don't know how.

I now do this:
POE::Session-create(
   inline_states =
   {
  _start= \controller_start,
  do_the_start = \do_the_start,
  ...
   },
);
sub controller_start
{
   my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION ];
   $heap-{server} = new POE::Component::Server::TCP(
 Alias   = controld,
 Port= ,
 ClientInput = \client_input,
 ClientConnected = \client_connected,
 Args= [ $session ],
   );
}
sub do_the_start
{
   my ($kernel, $heap, $session, $input, $client) = @_[KERNEL, HEAP, 
SESSION, ARG0, ARG1];

   my $child = new POE::Wheel::Run(
  Program= $input,  ## Not recommended :)
  ...
  StdoutEvent= 'session_stdout',
  ...
   );
   ## If this went well, send response back to client:
   client-put(OK);
}
...
$poe_kernel-run();
sub client_connected
{
   my ($session, $heap, $kernel, $controllingSession) = @_[ SESSION, 
HEAP, KERNEL, ARG0];

   $heap-{controllingSession} = $controllingSession;
}
sub client_input
{
   my ($session, $heap, $kernel, $input, $wheel) = @_[ SESSION, HEAP, 
KERNEL, ARG0, ARG1 ];

   ## pass client's input and reference to our wheel
   $kernel-post($heap-{controllingSession}, 'do_the_start', $input, 
$heap-{client});
}

I basically do not respond from within the ClientInput state, but do a 
post to another session, with both the client's input and a reference 
to the tcp wheel.

This works but I'm somewhat confused as to why I can't just fork a 
child from within the ClientInput state using POE::Wheel::Run, 
conceptually that is. So I'd love someone explain me the concept ;)

Regards,
Bas.


Re: POE sessions, clients, confused

2005-01-26 Thread David Davis
Response within,

On Wed, 26 Jan 2005 22:36:25 +0100, Bas Schulte [EMAIL PROTECTED] wrote:
 Hi David,
 
 On woensdag, jan 26, 2005, at 20:01 Europe/Amsterdam, David Davis wrote:
 
  Setup another session to handle wheel run, and use $_[SENDER] to reply
  back if the client is still connected.
 
 That's a bit too compact for me :)
 
 Where do I do what, that's basically my problem:
 
 Can I start a new session in client_input, start a new POE::Wheel::Run
 from there *in* the ClientInput state? Or does that create a
 (parent-child?) dependency with the POE::Component::Server::TCP
 session? That runs sour when the client disconnects?

Yes it does create a wheel in that session handling the input for that client.
Your session_stdout even is getting sent to that session, and you
don't have an event by that name in that session created by
Server::TCP.

 
 I'm confused as to what session should manage the events fired by the
 POE::Wheel that manages my child. I think I need to detach the
 started wheel from the tcp session but don't know how.
 
 I now do this:
 
 POE::Session-create(
 inline_states =
 {
_start= \controller_start,
 
do_the_start = \do_the_start,
 
...
 },
 );
 
 sub controller_start
 {
 my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION ];
 
 $heap-{server} = new POE::Component::Server::TCP(
   Alias   = controld,
   Port= ,
   ClientInput = \client_input,
   ClientConnected = \client_connected,
   Args= [ $session ],
 );
 }
 
 sub do_the_start
 {
 my ($kernel, $heap, $session, $input, $client) = @_[KERNEL, HEAP,
 SESSION, ARG0, ARG1];
 
 my $child = new POE::Wheel::Run(
 
Program= $input,  ## Not recommended :)
 
...
 
StdoutEvent= 'session_stdout',
 
...
 );
 
 ## If this went well, send response back to client:
 
 client-put(OK);

Missing a $ here

 }
 
 ...
 
 $poe_kernel-run();
 
 sub client_connected
 {
 my ($session, $heap, $kernel, $controllingSession) = @_[ SESSION,
 HEAP, KERNEL, ARG0];
 
 $heap-{controllingSession} = $controllingSession;
 }
 
 sub client_input
 {
 my ($session, $heap, $kernel, $input, $wheel) = @_[ SESSION, HEAP,
 KERNEL, ARG0, ARG1 ];
 
 ## pass client's input and reference to our wheel
 
 $kernel-post($heap-{controllingSession}, 'do_the_start', $input,
 $heap-{client});

Don't pass the client wheel, that's bad when using post.  It would be
better if you used $kernel-post($_[SENDER] = send = 'OK');  and
setup an inline_state called send that did a if ($heap-{client}) {
$heap-{client}-put($_[ARG0]); }

You could also change this to a call() and be ok with using it as a
hack.  Just don't pass wheel handles around freely.

 }
 
 I basically do not respond from within the ClientInput state, but do a
 post to another session, with both the client's input and a reference
 to the tcp wheel.
 
 This works but I'm somewhat confused as to why I can't just fork a
 child from within the ClientInput state using POE::Wheel::Run,
 conceptually that is. So I'd love someone explain me the concept ;)

See above. The wheel becomes a child of the client control session.

 
 Regards,
 
 Bas.
 
 

I hope this helps.

-- 
David Davis
Perl Programmer
http://teknikill.net/

Try CPAN Suggest!
http://cpan.teknikill.net/