From 8cc60399d97466c43a87df7e48e80dbc3b88c2d6 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 21 Jun 2013 16:43:01 -0400 Subject: [PATCH] LP1204123 SIGTERM causes graceful shutdown (Perl) When sent the SIGTERM signal, listener processes will wait for all child processes to complete their currently running tasks before killing all child processes and exiting. SIGQUIT and SIGINT can still be used for semi-graceful shutdowns, where the listener de-registers and cleans up child processes, but does not wait for child processes to finish their tasks. To kill with fire, SIGKILL is still your friend. Signed-off-by: Bill Erickson Signed-off-by: Jason Stephenson --- src/perl/lib/OpenSRF/Server.pm | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/perl/lib/OpenSRF/Server.pm b/src/perl/lib/OpenSRF/Server.pm index 1257a9c..7ace7cf 100644 --- a/src/perl/lib/OpenSRF/Server.pm +++ b/src/perl/lib/OpenSRF/Server.pm @@ -65,9 +65,27 @@ sub new { sub cleanup { my $self = shift; my $no_exit = shift; + my $graceful = shift; $logger->info("server: shutting down and cleaning up..."); + # de-register routers + $self->unregister_routers; + + if ($graceful) { + # graceful shutdown waits for all active + # children to complete their in-process tasks. + + while (@{$self->{active_list}}) { + $logger->info("server: graceful shutdown with ". + @{$self->{active_list}}." active children..."); + + # block until a child is becomes available + $self->check_status(1); + } + $logger->info("server: all clear for graceful shutdown"); + } + # don't get sidetracked by signals while we're cleaning up. # it could result in unexpected behavior with list traversal $SIG{CHLD} = 'IGNORE'; @@ -76,9 +94,6 @@ sub cleanup { $self->kill_child($_) for (@{$self->{idle_list}}, @{$self->{active_list}}); - # de-register routers - $self->unregister_routers; - $self->{osrf_handle}->disconnect; # clean up our dead children @@ -126,7 +141,8 @@ sub run { $logger->set_service($self->{service}); - $SIG{$_} = sub { $self->cleanup; } for (qw/INT TERM QUIT/); + $SIG{$_} = sub { $self->cleanup; } for (qw/INT QUIT/); + $SIG{TERM} = sub { $self->cleanup(0, 1); }; $SIG{CHLD} = sub { $self->reap_children(); }; $SIG{HUP} = sub { $self->handle_sighup(); }; -- 2.11.0