[LON-CAPA-cvs] cvs: loncom / loncnew

foxr lon-capa-cvs@mail.lon-capa.org
Tue, 05 Oct 2004 11:16:57 -0000


foxr		Tue Oct  5 07:16:57 2004 EDT

  Modified files:              
    /loncom	loncnew 
  Log:
  Full signal handling in loncnew.  I believe this now works so I have set
  DieWhenIdle to true.   If there are problems in an emergency, set DieWhenIdle
  to 0 and old style behavior (no process trimming) will occur.
  
  
Index: loncom/loncnew
diff -u loncom/loncnew:1.64 loncom/loncnew:1.65
--- loncom/loncnew:1.64	Tue Oct  5 06:10:31 2004
+++ loncom/loncnew	Tue Oct  5 07:16:57 2004
@@ -2,7 +2,7 @@
 # The LearningOnline Network with CAPA
 # lonc maintains the connections to remote computers
 #
-# $Id: loncnew,v 1.64 2004/10/05 10:10:31 foxr Exp $
+# $Id: loncnew,v 1.65 2004/10/05 11:16:57 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -79,6 +79,8 @@
                                 # is listening to.
 my %parent_dispatchers;         # host-> listener watcher events. 
 
+my %parent_handlers;		# Parent signal handlers...
+
 my $MaxConnectionCount = 10;	# Will get from config later.
 my $ClientConnection = 0;	# Uniquifier for client events.
 
@@ -87,6 +89,7 @@
 my $IdleTimeout= 600;		# Wait 10 minutes before pruning connections.
 
 my $LogTransactions = 0;	# When True, all transactions/replies get logged.
+my $executable      = $0;	# Get the full path to me.
 
 #
 #  The variables below are only used by the child processes.
@@ -109,9 +112,8 @@
 my $LondConnecting  = 0;       # True when a connection is being built.
 
 
-# DO NOT SET THE NEXT VARIABLE TO NON ZERO!!!!!!!!!!!!!!!
 
-my $DieWhenIdle     = 0;	# When true children die when trimmed -> 0.
+my $DieWhenIdle     = 1;	# When true children die when trimmed -> 0.
 my $I_am_child      = 0;	# True if this is the child process.
 
 #
@@ -1650,9 +1652,19 @@
 	Debug(5, "Killing watcher for $listener");
 
 	$watcher->cancel();
-	undef         $parent_dispatchers{$listener};
+	delete($parent_dispatchers{$listener});
 
     }
+
+    #  kill off the parent's signal handlers too!  
+    #
+
+    for my $handler (keys %parent_handlers) {
+	my $watcher = $parent_handlers{$handler};
+	$watcher->cancel();
+	delete($parent_handlers{$handler});
+    }
+
     $I_am_child    = 1;		# Seems like in spite of it all I may still getting
                                 # parent event dispatches.. flag I'm a child.
 
@@ -1965,6 +1977,28 @@
 		   signal   => "CHLD");
 
 
+    # Set up all the other signals we set up.  We'll vector them off to the
+    # same subs as we would for DieWhenIdle false and, if necessary, conditionalize
+    # the code there.
+
+    $parent_handlers{INT} = Event->signal(cb       => \&Terminate,
+					  desc     => "Parent INT handler",
+					  signal   => "INT");
+    $parent_handlers{TERM} = Event->signal(cb       => \&Terminate,
+					   desc     => "Parent TERM handler",
+					   signal   => "TERM");
+    $parent_handlers{HUP}  = Event->signal(cb       => \&Restart,
+					   desc     => "Parent HUP handler.",
+					   signal   => "HUP");
+    $parent_handlers{USR1} = Event->signal(cb       => \&CheckKids,
+					   desc     => "Parent USR1 handler",
+					   signal   => "USR1");
+    $parent_handlers{USR2} = Event->signal(cb       => \&UpdateKids,
+					   desc     => "Parent USR2 handler.",
+					   signal   => "USR2");
+    
+    #  Start procdesing events.
+
     $Event::DebugLevel = $DebugLevel;
     Debug(9, "Parent entering event loop");
     my $ret = Event::loop();
@@ -2016,11 +2050,15 @@
     my $now=time;
     my $local=localtime($now);
     print $fh "LONC status $local - parent $$ \n\n";
+    foreach my $host (keys %parent_dispatchers) {
+	print $fh "LONC Parent process listening for $host\n";
+    }
     foreach my $pid (keys %ChildHash) {
 	Debug(2, "Sending USR1 -> $pid");
 	kill 'USR1' => $pid;	# Tell Child to report status.
 	sleep 1;		# Wait so file doesn't intermix.
     }
+
 }
 
 =pod
@@ -2053,81 +2091,15 @@
 
     Log("INFO", "Updating connections via SIGUSR2");
 
-    #  Just in case we need to kill our own lonc, we wait a few seconds to
-    #  give it a chance to receive and relay lond's response to the 
-    #  re-init command.
-    #
-
-    sleep(2);			# Wait a couple of seconds.
+    #  I'm not sure what I was thinking in the first implementation.
+    # someone will have to work hard to convince me the effect is any
+    # different than Restart, especially now that we don't start up 
+    # per host servers automatically, may as well just restart.
+    # The down side is transactions that are in flight will get timed out
+    # (lost unless they are critical).
 
-    my %hosts;                   # Indexed by loncapa hostname, value=ip.
-    
-    # Need to re-read  the host table:
-    
-    
-    LondConnection::ReadConfig();
-    my $I = LondConnection::GetHostIterator;
-    while (! $I->end()) {
-	my $item = $I->get();
-	$hosts{$item->[0]} = $item->[4];
-	$I->next();
-    }
+    &Restart();
 
-    #  The logic below is written for clarity not for efficiency.
-    #  Since I anticipate that this function is only rarely called, that's
-    #  appropriate.  There are certainly ways to combine the loops below,
-    #  and anyone wishing to obscure the logic is welcome to go for it.
-    #  Note that we don't re-direct sigchild.  Instead we do what's needed
-    #  to the data structures that keep track of children to ensure that
-    #  when sigchild is honored, no new child is born.
-    #
-
-    #  For each existing child; if it's host doesn't exist, kill the child.
-
-    foreach my $child (keys %ChildHash) {
-	my $oldhost = $ChildHash{$child};
-	if (!(exists $hosts{$oldhost})) {
-	    Log("CRITICAL", "Killing child for $oldhost  host no longer exists");
-	    delete $ChildHash{$child};
-	    delete $HostToPid{$oldhost};
-	    kill 'QUIT' => $child;
-	}
-    }
-    # For each remaining existing child; if it's host's ip has changed,
-    # Restart the child on the new IP.
-
-    foreach my $child (keys %ChildHash) {
-	my $oldhost = $ChildHash{$child};
-	my $oldip   = $HostHash{$oldhost};
-	if ($hosts{$oldhost} ne $oldip) {
-
-	    # kill the old child.
-
-	    Log("CRITICAL", "Killing child for $oldhost host ip has changed...");
-	    delete $ChildHash{$child};
-	    delete $HostToPid{$oldhost};
-	    kill 'QUIT' => $child;
-
-	    # Do the book-keeping needed to start a new child on the
-	    # new ip.
-
-	    $HostHash{$oldhost} = $hosts{$oldhost};
-	    CreateChild($oldhost);
-	}
-    }
-    # Finally, for each new host, not in the host hash, create a
-    # enter the host and create a new child.
-    # Force a status display of any existing process.
-
-    foreach my $host (keys %hosts) {
-	if(!(exists $HostHash{$host})) {
-	    Log("INFO", "New host $host discovered in hosts.tab...");
-	    $HostHash{$host} = $hosts{$host};
-	    CreateChild($host);
-	} else {
-	    kill 'HUP' => $HostToPid{$host};    # status display.
-	}
-    }
 }
 
 
@@ -2146,7 +2118,7 @@
     Log("CRITICAL", "Restarting");
     my $execdir = $perlvar{'lonDaemons'};
     unlink("$execdir/logs/lonc.pid");
-    exec("$execdir/loncnew");
+    exec("$executable");
 }
 
 =pod