From b318088b68bf8efd14d7e9d46388a965e97f91e9 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 21 Jun 2013 16:43:01 -0400 Subject: [PATCH] SIGTERM 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 --- 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 d8103b6..af3141d 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