*This definitely has to do with the open EasyDBI session
I tested this by shutting down the EasyDBI session from inside the child
manually before a Ctrl-C and indeed the shutdown works fine with no orphaned
processes.
(Called this before Control-C)
sub my_test_handler_before_ctrl_c{
POE::Kernel->post( 'EasyDBI', 'shutdown' => 'NOW' );
}
.......program running.......
(CONTROL-C HERE)
(All 3 children reaped)
MAIN STOP CALLED
!!! Child process PID:18268 reaped:
!!! Child process PID:18267 reaped:
!!! Child process PID:18266 reaped:
So the real question is, how do I handle this correctly......Do I handle
this in the parent by looking for open sessions or do I handle this on the
child side by adding signal handlers?
Any and all suggestions welcome. Thanks in advance for any advice
On Fri, May 8, 2009 at 5:48 PM, Josh803316 <[email protected]> wrote:
> Hello once again POE world,
>
> *I have a problem with a child daemon process not being killed when I hit
> Ctrl-C for the parent. All other children are reaped but one remains. This
> child happens to be the one using EasyDBI.
> *I have noticed that when I hit Ctrl-C......I don't see the _stop event
> called for any of the spawned children. This _stop event is what calls
> $kernel->post(
> 'EasyDBI', 'shutdown' => 'NOW' );
> *I'm assuming that the reason the child stays around is because the EasyDBI
> session is still alive.
>
> 1)Parent uses wheel::run to spawn workers (database worker only one that
> stays alive)
>
> 2)Database worker child spawns EasyDbi session as well as other sessions
>
> 3)Everything runs normally then I hit Ctrl-C which kills the parent
> process, then shows all the other children reaped but hangs on the final one
> !!! Child process PID:17843 reaped:
> !!! Child process PID:17842 reaped:
> ....hangs here
>
> 4)A second Ctrl-C ends the program (with child process still running)
> # ps aux | grep perl
> root 17841 2.7 1.0 153992 21276 pts/5 S 17:18 0:00
> /usr/bin/perl ./WorkerDbd (This process should be gone)
>
>
> (PARENT Daemon)
> ##################################################
> foreach my $key (keys %$workers ){
> foreach my $worker ( @{$workers->{$key}} ){
> print "The worker is $worker\n";
> POE::Session->create(
> inline_states => {
> _start => \&on_start,
> _child => \&_child,
> got_child_stdout => \&on_child_stdout,
> got_child_stderr => \&on_child_stderr,
> got_child_close => \&on_child_close,
> got_child_signal => \&on_child_signal,
> _stop => \&_stop
> },
> args => [$worker]
> );
> }
> }
>
> sub on_start {
> my ( $kernel, $session, $heap, $worker ) = @_[ KERNEL, SESSION, HEAP,
> ARG0 ];
> my $child = POE::Wheel::Run->new(
> Program => [ "./$worker" ],
> StdoutEvent => "got_child_stdout",
> StderrEvent => "got_child_stderr",
> CloseEvent => "got_child_close",
> );
>
> $_[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"
> );
> }
>
> ##########################################################
> (Database Worker CHILD Daemon)
> POE::Kernel->stop();
> POE::Component::IKC::Responder->spawn();
>
> POE::Component::EasyDBI->spawn( # or new(), witch returns an obj
> alias => 'EasyDBI',
> dsn =>
> 'DBI:mysql:database=foobaz;host=localhost;port=3306',
> username => 'username',
> password => 'password',
> options => {
> AutoCommit => 0,
> },
> );
>
> App::Database->__spawn();
>
> POE::Kernel->run();
>
> (Package)
> App::Database
> sub __spawn {
> my $class = shift;
>
> my $addr = $class->IP || '127.0.0.1';
> my $port = $class->PORT || 5667;
> my $trace = $class->TRACE || 0;
> my $debug = $class->DEBUG || 0;
> my $client = $class->ALIAS || "Client$$";
> my $workername = $client . 'Worker';
>
> ## spawn the ikc client with unique workername
> my $server = POE::Component::IKC::Client->spawn(
> ip => $addr,
> port => $port,
> name => $workername,
>
> on_connect => sub {
> $_[HEAP]->{channel} = $poe_kernel->get_active_session()->ID;
> print STDERR Dumper($_[HEAP]);
> POE::Session->create(
>
> package_states =>
> ## extract all subroutines that don't start with "__"
> ## and allocate them as states:
> [
> (__PACKAGE__) => [ do {
> no strict 'refs';
> grep { !/^__/ and defined &$_ } keys %{
> __PACKAGE__ . "::" };
> } ],
> ($class) => [ $class->SUBSCRIBE_METHODS ]
>
> ],
> ## pass args into _start:
> args => [$class,@_],
> options => { trace => $trace, debug => $debug },
>
> );
> }
> );
>
> return $server;
> }
>
> sub _start {
> my ( $kernel, $session, $heap, $class, $arg1 ) = @_[ KERNEL, SESSION,
> HEAP, ARG0, ARG1 ];
>
> my $states;
> my $alias = $class->ALIAS;
>
> # name this session
> if($class){
> $kernel->alias_set($alias);
> $kernel->post( 'IKC', 'publish', $alias,
> [$class->SUBSCRIBE_METHODS] );
> $class->__startup($kernel,$session,$heap);
> }
> }
>
> sub _stop {
> my ( $kernel, $session, $heap, $arg ) = @_[ KERNEL, SESSION, HEAP, ARG0
> ];
> print STDERR "STOP WAS CALLED FOR THE WORKER TEMPLATE $session->ID\n";
> $kernel->post( 'EasyDBI', 'shutdown' => 'NOW' );
> $kernel->post(IKC=>'retract' );
> $kernel->yield('__shutdown');
> }
>