Hi guys!
I have been playing around with POE for a while, I would like to create a little script that forks subprocesses while there are tasks to process and also log the result of those tasks. It works fine except for the "logging" part
I replaced the while(1) with sleep for making the problem more obvious. The problem is that the stdout/stderr is only displayed after the parent is done with the sleep wherever I put it, the rest of the code is executed tho just fine. So the child processes might not autoflush with POE?.. If so, could you give me an advice please how to force it or some workaround.
use POE;
use POE::Component::Client::SMTP;
use POE qw( Wheel::Run );
use strict;
use warnings;
$|++;
POE::Session->create(
inline_states => {
_start => \&on_start,
got_child_stdout => \&on_child_stdout,
got_child_stderr => \&on_child_stderr,
got_child_close => \&on_child_close,
got_child_signal => \&on_child_signal,
get_next_logic => \&on_get_next_logic,
}
);
POE::Kernel->run();
exit 0;
sub on_start {
print "on_start\n";
$_[KERNEL]->yield("get_next_logic");
sleep(10);
}
sub get_next_file {
print "get_next_file\n";
}
sub on_get_next_logic {
my $child;
print("get_next_logic\n");
$child = POE::Wheel::Run->new(
Program => sub { get_next_file() },
StdoutEvent => "got_child_stdout",
StderrEvent => "got_child_stderr",
CloseEvent => "got_child_close",
#Conduit => "pty"
);
$_[KERNEL]->sig_child($child->PID, "got_child_signal");
# Wheel events include the wheel's ID.
$_[HEAP]{children_by_wid}{$child->ID} = $child;
# Signal events include the process ID.
$_[HEAP]{children_by_pid}{$child->PID} = $child;
print(
"Child pid ", $child->PID,
" started as wheel ", $child->ID, ".\n"
);
sleep(10);
}
####### signal handling stuff i haven't touched #####
# Wheel event, including the wheel's ID.
sub on_child_stdout {
my ($stdout_line, $wheel_id) = @_[ARG0, ARG1];
my $child = $_[HEAP]{children_by_wid}{$wheel_id};
print "pid ", $child->PID, " STDOUT: $stdout_line\n";
}
# Wheel event, including the wheel's ID.
sub on_child_stderr {
my ($stderr_line, $wheel_id) = @_[ARG0, ARG1];
my $child = $_[HEAP]{children_by_wid}{$wheel_id};
print "pid ", $child->PID, " STDERR: $stderr_line\n";
}
# Wheel event, including the wheel's ID.
sub on_child_close {
my $wheel_id = $_[ARG0];
my $child = delete $_[HEAP]{children_by_wid}{$wheel_id};
# May have been reaped by on_child_signal().
unless (defined $child) {
print "wid $wheel_id closed all pipes.\n";
return;
}
print "pid ", $child->PID, " closed all pipes.\n";
delete $_[HEAP]{children_by_pid}{$child->PID};
}
sub on_child_signal {
print "pid $_[ARG1] exited with status $_[ARG2].\n";
my $child = delete $_[HEAP]{children_by_pid}{$_[ARG1]};
# May have been reaped by on_child_close().
return unless defined $child;
delete $_[HEAP]{children_by_wid}{$child->ID};
}
Thank you very much!