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');
}

Reply via email to