_stop state isn't called on child when parent gets Ctrl-C (EasyDBI session still active)

Josh803316 <[email protected]>
Newsgroups gmane.comp.lang.perl.poe
Message-ID <[email protected]>
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');
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.