Re: POE sessions, clients, confused
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
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
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
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
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
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
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
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
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/