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