I've encountered this same problem.  I also only see it when mixing POE and 
Proc::Daemon.  I am using POE 1.292, and perl 5.10.1 on Linux.

I've found another work-around.  Hopefully this clue will be useful to anyone 
attempting to get to the root of the problem.  

The problem is in the way Proc::Daemon is closing all (possible) open file 
descriptors -- it's using POSIX::close().  From the Proc::Daemon source --

    ## Close open file descriptors
    foreach $i (0 .. OpenMax) { POSIX::close($i); }

The work-around is to use Perl's built in close() function instead of 
POSIX::close().  To do this, replace the line above with --

    for my $fd (3 .. OpenMax()){ 
        ## See Section 17.18 in _The Perl Cookbook_
        open(my $h, "+<&=$fd");
        close($h);
    }


Note 1) I do a fancy open() call because Perl's close operates on file handles 
- not file descriptors.  That fancy open is straight out of _The Perl Cookbook_.

Note 2) You very likely want to open STDIN, STDOUT and STDERR to specific 
handles, or at least /dev/null.  That's why I loop from 3..OpenMax instead of 
0..OpenMax.


Finally, I apologize if this message doesn't make it into the correct thread.  
I'm new to this list, and thus don't have the original email message to respond 
to.  (I found the original message in the archives.)

Thanks to everyone who works to make POE such an excellent project.

--Jody



> From: "Ellery, Michael" <mell...@websense.com>
> Date: September 1, 2010 1:28:49 PM EDT
> To: "poe@perl.org" <poe@perl.org>
> Subject: unfortunate behavior after upgrading POE
> 
> 
> Hello,
> 
> We use POE to manage a group of child processes doing processing in our 
> system, using the POE::Wheel::Run plugin.
> 
> We recently upgraded our version of POE from 0.9989 to 1.284 and noticed a 
> dramatic change in the performance of the system. With the older version of 
> POE, the child processes consumed most of the CPU - which is expected since 
> they do all the processing. With the newer version of POE, however, we notice 
> that the parent process (the POE session manager) consumes all the CPU and 
> starves the children. The parent process is really just there to manage the 
> children, so it should consume very little resources.
> 
> I did some investigation with strace and noticed that the parent process was 
> doing select/read in a very tight loop...and the filehandle it is trying to 
> read from is just some perl library file on our system (I think it was 
> JSON.pm, but that doesn't matter..). What's more, the list of FDs being 
> passed to select included 10 sockets (presumably to the child processes) AND 
> this one file handle to the JSON.pm module that the perl process has open. 
> Since this file is always ready to read, select always returns true 
> indicating that this file is ready to read..thus the tight loop.
> 
> I did a little investigating in the POE code and noticed that there is a lot 
> of new code to handle signals differently. As an experiment, I tried setting 
> USE_SIGNAL_PIPE to 0 in my script before loading POE and the behavior goes 
> back to normal (that is, the parent process no longer consumes all the CPU).
> 
> So, has anyone else observed this behavior when using Wheel::Run to manage 
> child processes? Is my workaround a reasonable one or should I fix this 
> problem some other way. Based on my observations, it seems like the 
> fundamental problem is that POE is calling select() with one incorrect file 
> descriptor in its list..thus causing select to always return immediately and 
> causing POE to try to read from some disk file instead of from a socket to 
> child processes.
> 
> Thanks,
> Mike Ellery
> 
> 
> Protected by Websense Hosted Email Security -- www.websense.com 


Reply via email to