From: Bill Erickson Date: Fri, 21 Jun 2013 20:43:01 +0000 (-0400) Subject: SIGTERM graceful shutdown (Perl) X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=b318088b68bf8efd14d7e9d46388a965e97f91e9;p=working%2FOpenSRF.git 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 --- 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(); };