Agreed, a _child(lose) before the _child(create) is bad.

It should either be a _child(create)/_child(lose) pair, or nothing in this case. I'm tempted to go with "nothing" since it would be hard to fix the create/lose timing. Also the new(detached => 1) seems good, but I admit I haven't given it much though yet. Sometimes I change my mind after thinking about things too hard.

If you haven't already, please submit this to bug-...@rt.cpan.org. I'm liable to forget about POE bugs, patches, tests, etc. if they're not in POE's bug tracker.

Thank you again for all your help.

--
Rocco Caputo - rcap...@pobox.com


On Nov 19, 2009, at 14:00, Olivier Mengué wrote:

Hi POE fellows,

I'm in the process of rewriting the backend of my POE::Component::Schedule to make the backend session independent of others session in the system. The point is that session is just backend stuff, so it should not fire _child events to the session from which the API may have been called. Also, the schedule session is a singleton that may be used by multiple session, so it
has no reason for being attached to a particular session.
To achieve that, I'm calling POE::Kernel->detach_myself in the _start
handler of the session. POE does'nt fire _child(create) as I expected.
However I also found out that POE still fires _child(lose).

My opinion is that POE should not fire a _child(lose) event if the session
is detached from its parent in the _start handler as a 'lose' without
'create'/'gain' is inconsistent.
Also it would be better if 'detach => 1' was an argument to
POE::Session->create(): it would make the 'not attached' particularity of
this session more explicit for people reading the code.

Here is a test case that shows the current flawed behavior (tested with POE
1.006, POE 1.280):

use strict;
use warnings;

use Test::More tests => 7;
use POE;

my $_child_fired = 0;

POE::Session->create(
   inline_states => {
       _start => sub {
           $_[KERNEL]->alias_set('First');
           pass "_start First";
           POE::Session->create(
               inline_states => {
                   _start => sub {
                       $_[KERNEL]->alias_set('Second');
                       pass "_start Second";
                   },
               },
           );
           POE::Session->create(
               inline_states => {
                   _start => sub {
                       $_[KERNEL]->alias_set('Detached');
                       pass "_start Detached";
diag "Detaching session 'Detached' from its parent";
                       $_[KERNEL]->detach_myself;
                   },
               },
           );
       },
       _child => sub {
           $_child_fired++;
           ok($_[KERNEL]->alias_list($_[ARG1]) ne 'Detached',
               "$_[STATE]($_[ARG0]) fired for "
                 .$_[KERNEL]->alias_list($_[ARG1]->ID));
       },
   },
);

POE::Kernel->run();

pass "_child not fired for session detached in _start" unless $_child_fired
!= 2;
pass "Stopped";


Olivier Mengué
http://o.mengue.free.fr/

Reply via email to