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

2009-05-08 Thread Josh803316
*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  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/5S17: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

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

2009-05-08 Thread Josh803316
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/5S17: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' );
$