LP1204123 SIGTERM causes graceful shutdown (Perl)
authorBill Erickson <berick@esilibrary.com>
Fri, 21 Jun 2013 20:43:01 +0000 (16:43 -0400)
committerJason Stephenson <jstephenson@mvlc.org>
Wed, 4 Sep 2013 15:07:58 +0000 (11:07 -0400)
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 <berick@esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson@mvlc.org>

src/perl/lib/OpenSRF/Server.pm

index 1257a9c..7ace7cf 100644 (file)
@@ -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(); };