Re: _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]>
*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');
> }
>
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.