Home > Archive > PERL POE > June 2005 > Re: POE sessions, clients, confused
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Re: POE sessions, clients, confused
|
|
| David Davis 2005-06-08, 9:04 pm |
| Response within,
On Wed, 26 Jan 2005 22:36:25 +0100, Bas Schulte <bschulte@zeelandnet.nl> wrote:
> Hi David,
>
> On woensdag, jan 26, 2005, at 20:01 Europe/Amsterdam, David Davis wrote:
>
>
> 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 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 => 6666,
> 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 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/
| |
| Bas Schulte 2005-06-08, 9:04 pm |
| Hi David,
On donderdag, jan 27, 2005, at 00:45 Europe/Amsterdam, David Davis
wrote:
>
> 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 :)
>
> 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.
| |
| David Davis 2005-06-08, 9:04 pm |
| Response below.
On Thu, 27 Jan 2005 20:15:22 +0100, Bas Schulte <bschulte@zeelandnet.nl> wrote:
> Hi David,
>
> On donderdag, jan 27, 2005, at 00:45 Europe/Amsterdam, David Davis
> wrote:
>
>
> Yes, this part I understand now :)
>
>
>
> 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.
>
>
> I tried it, seems to work fine.
It seems to...
>
>
>
> 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 ]
},
);
>
>
> 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/
| |
| Rocco Caputo 2005-06-08, 9:04 pm |
| 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 <bschulte@zeelandnet.nl> wrote:
>
> 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/
| |
| Bas Schulte 2005-06-08, 9:04 pm |
| 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:
>
> 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.
|
|
|
|
|