CloseEvent Problem
"Simon Taylor" <[email protected]>
| Newsgroups | gmane.comp.lang.perl.poe |
|---|---|
| Message-ID | <CF268C57160BE84289D36FF46801A2C8083951C6@zharhxm0.corp.nortel.com> |
POE 1.280
I'm trying to have POE trigger the addition of new tasks on the
CloseEvent of existing children. Been following the example here:-
http://poe.perl.org/?POE_Cookbook/Child_Processes_3
It appears that the CloseEvent handler is never called.
It spawns 3 children upto the value of MaxConcurrent children but never
spawns any more.
Ran it trace mode and i would expect to see the CloseEvent handler
called there:-
[sdu@qharvnd55d cmd]$ ./new_batch_handler.pl
11919: 2 -> _start (from /usr/lib/perl5/site_perl/5.8.5/POE/Kernel.pm at
1469)
11919: 2 -> sig_child (from
/usr/lib/perl5/site_perl/5.8.5/POE/Resource/Signals.pm at 551)
11919: 2 -> sig_child (from
/usr/lib/perl5/site_perl/5.8.5/POE/Resource/Signals.pm at 551)
11919: 2 -> sig_child (from
/usr/lib/perl5/site_perl/5.8.5/POE/Resource/Signals.pm at 551)
11919: 2 -> _stop (from
/usr/lib/perl5/site_perl/5.8.5/POE/Resource/Sessions.pm at 528)
11919: a '_stop' event was sent from
/usr/lib/perl5/site_perl/5.8.5/POE/Resource/Sessions.pm at 528 to
session 2 (POE::Session=ARRAY(0x1cf7eb0)) but session 2
(POE::Session=ARRAY(0x1cf7eb0)) has neither a handler for it nor one for
_default
I note a similar issue reported here:-
http://rt.cpan.org/Public/Bug/Display.html?id=38908
Is it still an active issue in 1.280 OR have I misconfigured.
Rest of it appears to be working fine - im using object states and they
seem to map in - where sig_child is concerned anyway.
The POE related config of my program looks like:-
sub _IterateChildrenParallel{
=Head3 _IterateChildrenParallel
Moved in from the BatchHandler so we can override behaviour
The objective is to ensure we can parallelise the processing of children
Use the POE model
=cut
my ($self, @args) = @_;
$self->{_logger}->debug("Iterating children");
POE::Session->create(
options => { trace => 1, debug => 1, default => 1 },
object_states => [
$self => {
_start => '_start',
handle_task_result => 'handle_task_result',
handle_task_done => 'handle_task_done',
handle_task_debug => 'handle_task_debug',
sig_child => 'sig_child'
}
]
);
$poe_kernel->run();
}
sub _start {
=Head3 _start
Function called when POE wants to start tasks
Shouldnt start any more than MAX_CONCURRENT_TASKS
When it does it spawns children
Event handlers allow information to be passed back to the parent process
Mapping between state and function is done in the object states line in
the POE::Session->create in _IterateChildrenParallel
=cut
my ($kernel, $self, $heap) = @_[KERNEL, OBJECT];
my ($child);
$self->{_logger}->debug("Beginning of start tasks - if it has executed
this we have an object ref");
while (keys(%{$heap->{task}}) < MAX_CONCURRENT_TASKS) {
if (ref($self->{_children}) eq "ARRAY"){
$child = shift @{$self->{_children}};
last unless defined $child;
$self->{_logger}->debug("ARRAY "."Child = $child");
my $task = POE::Wheel::Run->new(
Program => sub {$self->_CreateChild($child)},
StdoutFilter => POE::Filter::Reference->new(),
StdoutEvent => "handle_task_result",
StderrEvent => "handle_task_debug",
CloseEvent => "handle_task_done",
);
$heap->{task}->{$task->ID} = $task;
$self->{_logger}->debug(Dumper($heap));
$kernel->sig_child($task->PID, "sig_child");
} elsif (ref($self->{_children}) eq "HASH") {
$self->{_logger}->debug("HASH "."Child = $child");
$self->_CreateChild($child);
} else {
$self->{_logger}->debug("SCALAR "."Child = $child");
$self->_CreateChild($child);
} # If end
} # While end
}
sub handle_task_result {
my $result = $_[ARG0];
print "Result for $result->{task}: $result->{status}\n";
}
sub handle_task_debug {
# Catch and display information from the child's STDERR. This was
# useful for debugging since the child's warnings and errors were not
# being displayed otherwise.
my ($self,$result) = @_[OBJECT, ARG0];
$self->{_logger}->debug("Debug: $result\n");
}
sub handle_task_done {
# The task is done. Delete the child wheel, and try to start a new
# task to take its place.
my ($kernel, $heap, $self, $task_id ) = @_[KERNEL, HEAP, OBJECT, ARG0,
];
$self->{_logger}->warn("Task ID: $task_id completed \n");
delete $heap->{task}->{$task_id};
$kernel->yield("_start");
}
sub sig_child {
# Detect the CHLD signal as each of our children exits.
my ($heap, $self, $sig, $pid, $exit_val ) = @_[HEAP, OBJECT, ARG0,
ARG1, ARG2];
my $details = delete $heap->{$pid};
$self->{_logger}->warn("$$: Child $pid exited");
$self->{_logger}->debug(Dumper($heap));
}
Thanks
Simon Taylor
Development Team Lead NMS Applications
Network Managed Services
Nortel Networks
(e) [email protected]
(p) +44 1279 402291 ESN 6 742 2291
(m) +44 7740 533743 ESN 6 748 3743
(yim) setuk_nortel