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/