]> git.etc.gen.nz Git - spong.git/commitdiff
Changed child process management to make it easier to scale. Update processes
authorStephen L Johnson <sjohnson@monsters.org>
Wed, 5 Jan 2000 15:26:33 +0000 (15:26 +0000)
committerStephen L Johnson <sjohnson@monsters.org>
Wed, 5 Jan 2000 15:26:33 +0000 (15:26 +0000)
can now be selectively enabled.

src/spong-server.pl

index f8f6b11c2640f97f4cbd0b8578599324b7a61aa5..1c043cdab3f8b74795341dc47d8510c5e55a5204 100755 (executable)
@@ -47,14 +47,26 @@ $HOST        =~ tr/A-Z/a-z/;
 &load_data_funcs();
 &debug("Done loading data plugins");
 
-$upd_pid = 0;
-$bb_pid  = 0;
+%PROCS = ();   # All of the procs that we will be monitoring in the main process
+
 $shutdown = 0;
 
 &load_config_files(); # Loads the user specified configuration information
 Spong::Daemon::Daemonize() unless ($debug || $restart || $kill) ;
 &handle_signals();    # Set up handlers, and signal the current server if asked
 
+# Determine all of the update processes that will need to be running
+$PROCS{'query'} = { func => \&listen_for_queries, pid => undef };
+
+if ( defined $SPONG_BB_UPDATE_PORT ) {
+   $PROCS{'bb-update'} = { func => \&listen_for_bb_updates, pid => undef };
+}
+
+if (defined $SPONG_UPDATE_PORT ) {
+   $PROCS{'spong-update'} = { func => \&listen_for_updates, pid => undef };
+}
+
+
 # Establish a list of all the services that we monitor so that we can be
 # consistant in the output that we display regardless of the group that we
 # are showing.
@@ -64,31 +76,37 @@ Spong::Daemon::Daemonize() unless ($debug || $restart || $kill) ;
 foreach $host ( Spong::HostList->new( "all" )->hosts() ) {
    foreach $service ( $host->service_names() ) { $main::SERVICES{$service}=1;}}
 
-# Split into two processes, one process listens at port 1970 for update
-# messages, and the other process listens at port 1960 and responds to query  
-# messages.  Both processes are "single-threaded", they don't fork off
+# Split into lots of processes, the main process is the master process spawns
+# off the rest of the processes as children and restarted them when they die.
+# One mandatory processes listens at port 1999 for query messages. The rest
+# of the processes are that listen for update messages via various different
+# protocols
+# All child processes are "single-threaded", they don't fork off
 # additional subprocesses, they just deal with the message setting at their
 # queue, and then process the next message as it comes in.
 
 $SIG{'CHLD'} = \&chld_handler;
 
-if( $upd_pid = fork() ) {
-   if( $bb_pid = fork() ) {
-      &listen_for_queries();
-   } elsif( defined $bb_pid ) {
-      &listen_for_bb_updates();
+while ( my($name,$proc) = each %PROCS ) {
+   my $pid = fork();
+   if (! defined $pid ) {
+      die "Error: Could not fork for $name process: $!";
+   } elsif ($pid) {
+      # I'm the parent, save the child's pid.
+      $proc->{'pid'} = $pid;
    } else {
-      die "Can't bb fork: $!";
+      # I'm the child, call function I'm assigned
+      $0 = "spong-server ($name)";
+      &{$proc->{'func'}}();
    }
-} elsif( defined $upd_pid ) {
-   &listen_for_updates();
-} else {
-   die "Can't update fork: $!";
 }
 
-# We should not get here, if we do then something is wrong...
+$0 = "spong-server (main)";
 
-die "Error: Exiting spong-server!\n";
+# At this point we just sleep, and handle dead children
+while ( 1 ) {
+   sleep 30;
+}
 
 
 # This procedure listens for connections at port 1970 (the update port), and
@@ -101,10 +119,10 @@ sub listen_for_updates {
    # Set up the socket to listen to
 
    $SIG{'PIPE'} = 'IGNORE';
-   $SIG{'QUIT'} = sub {&debug('spong updates caught QUIT signal, exiting');
-                       close SERVER; exit;};
-   $SIG{'HUP'} = sub {&debug('spong updates caught HUP signal, exiting');
-                       close SERVER; exit;};
+   $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub {
+      &debug('spong updates caught QUIT signal, exiting');
+      close SERVER; exit;
+   };
 
 
    my $proto = getprotobyname( 'tcp' );
@@ -155,8 +173,10 @@ sub listen_for_bb_updates {
    # Set up the socket to listen to
 
    $SIG{'PIPE'} = 'IGNORE';
-   $SIG{'QUIT'} = sub {&debug('bb updates caught QUIT signal, exiting');
-                       close SERVER; exit;};
+   $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub {
+      &debug('spong updates caught QUIT signal, exiting');
+      close SERVER; exit;
+   };
    $SIG{'HUP'} = sub {&debug('bb updates caught HUP signal, exiting');
                        close SERVER; exit;};
 
@@ -210,6 +230,10 @@ sub listen_for_queries {
    # Set up the socket to listen to
 
    $SIG{'PIPE'} = 'IGNORE';
+   $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub {
+      &debug('spong updates caught QUIT signal, exiting');
+      close SERVER; exit;
+   };
 
    my $proto = getprotobyname( 'tcp' );
    my $p     = pack( "l", 1 );
@@ -864,7 +888,10 @@ sub fmt_error {
 sub exit_handler { 
    &debug( "caught QUIT signal, exiting..." );
    $shutdown = 1;
-   kill QUIT,$upd_pid,$bb_pid;
+   while ( my($name,$proc) = (each %PROCS) ) {
+      kill QUIT,$proc->{'pid'};
+   }
+#   kill QUIT,$upd_pid,$bb_pid;
    unlink "$SPONGTMP/spong-server.pid" if -f "$SPONGTMP/spong-server.pid";
    exit(0);
 }
@@ -873,8 +900,11 @@ sub hup_handler {
    &debug( "caught HUP signal, restarting..." );
    $shutdown = 1;
    $SIG{CHLD} = 'DEFAULT';
-   kill QUIT,$upd_pid; waitpid($upd_pid,0);
-   kill QUIT,$bb_pid;  waitpid($bb_pid,0);
+   while ( my($name,$proc) = (each %PROCS) ) {
+      kill QUIT,$proc->{'pid'}; waitpid($proc->{'pid'},0);
+   }
+#   kill QUIT,$upd_pid; waitpid($upd_pid,0);
+#   kill QUIT,$bb_pid;  waitpid($bb_pid,0);
    unlink "$SPONGTMP/spong-server.pid" if -f "$SPONGTMP/spong-server.pid";
    close( SERVER );
    if( $debug ) { exec $me, "--debug"; } else { exec $me; }
@@ -891,23 +921,21 @@ sub chld_handler {
    }
    &debug( "caught CHLD signal, restarting child..." );
 
-   if ($pid == $upd_pid) {
-      if( $upd_pid = fork() ) {
-          return;
-      } elsif( defined $upd_pid ) {
-         &listen_for_updates();
-      } else {
-         die "Can't fork: $!";
-      }
-   } elsif ($pid == $bb_pid ) {
-      if( $bb_pid = fork() ) {
-          return;
-      } elsif( defined $bb_pid ) {
-         &listen_for_bb_updates();
-      } else {
-         die "Can't fork: $!";
+   while( my($name,$proc) = each %PROCS ) {
+      if ( $pid == $proc->{'pid'} ) {
+         my $pid = fork();
+         if (! defined $pid ) { 
+            die "Error: Cannot fork for $name process: $!";
+         } elsif ($pid) {
+            # I'm the parent, save the new child pid
+            $proc->{'pid'} = $pid;
+         } else {
+            # I'm the parent, call the function I'm assigned
+            &{$proc->{'func'}}();
+         }
       }
    }
+
 }
 
 # ---------------------------------------------------------------------------