Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

POE child autoflush stdout

by sub_soNic (Initiate)
on Jul 24, 2017 at 16:17 UTC ( [id://1195891]=perlquestion: print w/replies, xml ) Need Help??

sub_soNic has asked for the wisdom of the Perl Monks concerning the following question:

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!

Replies are listed 'Best First'.
Re: POE child autoflush stdout
by Anonymous Monk on Jul 24, 2017 at 20:05 UTC
    POE is cooperative multitasking, meaning no piece of your POE can sleep for long, that stops the whole program

    If you want test IPC you cant fake it with sleep in the parent poe process, you have to actually create a child proc to talk to, you can use perl, you can sleep in the child,

    $^X '-le', 'for(1..10){print; sleep rand5;}';

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1195891]
Front-paged by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2024-04-26 08:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found