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

Reply via email to