Diff for /loncom/loncnew between versions 1.12 and 1.15

version 1.12, 2003/07/02 01:12:35 version 1.15, 2003/07/15 02:07:05
Line 27 Line 27
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
 #  #
 # new lonc handles n requestors spread out bver m connections to londs.  # new lonc handles n request out bver m connections to londs.
 # This module is based on the Event class.  # This module is based on the Event class.
 #   Development iterations:  #   Development iterations:
 #    - Setup basic event loop.   (done)  #    - Setup basic event loop.   (done)
Line 46 Line 46
   
 # Change log:  # Change log:
 #    $Log$  #    $Log$
 #    Revision 1.12  2003/07/02 01:12:35  foxr  #    Revision 1.15  2003/07/15 02:07:05  foxr
 #    - Add some debugging to killthemall  #    Added code for lonc/lond transaction timeouts.  Who knows if it works right.
 #    - Add better error handling to LondReadable  #    The intent is for a timeout to fail any transaction in progress and kill
 #    - Remove tick logging in the timer handler.  #    off the sockt that timed out.
   #
   #    Revision 1.14  2003/07/03 02:10:18  foxr
   #    Get all of the signals to work correctly.
   #
   #    Revision 1.13  2003/07/02 01:31:55  foxr
   #    Added kill -HUP logic (restart).
 #  #
 #    Revision 1.11  2003/06/25 01:54:44  foxr  #    Revision 1.11  2003/06/25 01:54:44  foxr
 #    Fix more problems with transaction failure.  #    Fix more problems with transaction failure.
Line 95  use LONCAPA::HashIterator; Line 101  use LONCAPA::HashIterator;
 #  #
 #   Disable all signals we might receive from outside for now.  #   Disable all signals we might receive from outside for now.
 #  #
 $SIG{QUIT}  = IGNORE;  #$SIG{QUIT}  = IGNORE;
 $SIG{HUP}   = IGNORE;  #$SIG{HUP}   = IGNORE;
 $SIG{USR1}  = IGNORE;  #$SIG{USR1}  = IGNORE;
 $SIG{INT}   = IGNORE;  #$SIG{INT}   = IGNORE;
 $SIG{CHLD}  = IGNORE;  #$SIG{CHLD}  = IGNORE;
 $SIG{__DIE__}  = IGNORE;  #$SIG{__DIE__}  = IGNORE;
   
   
 # Read the httpd configuration file to get perl variables  # Read the httpd configuration file to get perl variables
Line 134  my $WorkQueue       = Queue->new(); # Qu Line 140  my $WorkQueue       = Queue->new(); # Qu
 my $ConnectionCount = 0;  my $ConnectionCount = 0;
 my $IdleSeconds     = 0; # Number of seconds idle.  my $IdleSeconds     = 0; # Number of seconds idle.
 my $Status          = ""; # Current status string.  my $Status          = ""; # Current status string.
   my $RecentLogEntry  = "";
 my $ConnectionRetries=5; # Number of connection retries allowed.  my $ConnectionRetries=5; # Number of connection retries allowed.
 my $ConnectionRetriesLeft=5; # Number of connection retries remaining.  my $ConnectionRetriesLeft=5; # Number of connection retries remaining.
   
Line 210  sub Log { Line 217  sub Log {
     my $execdir = $perlvar{'lonDaemons'};      my $execdir = $perlvar{'lonDaemons'};
     my $fh      = IO::File->new(">>$execdir/logs/lonc.log");      my $fh      = IO::File->new(">>$execdir/logs/lonc.log");
     my $msg = sprintf($finalformat, $message);      my $msg = sprintf($finalformat, $message);
       $RecentLogEntry = $msg;
     print $fh $msg;      print $fh $msg;
           
           
Line 283  sub ShowStatus { Line 291  sub ShowStatus {
   
 =pod  =pod
   
   =head 2 SocketTimeout
   
       Called when an action on the socket times out.  The socket is 
      destroyed and any active transaction is failed.
   
   
   =cut
   sub SocketTimeout {
       my $Socket = shift;
       
       KillSocket($Socket);
   }
   
   =pod
   
 =head2 Tick  =head2 Tick
   
 Invoked  each timer tick.  Invoked  each timer tick.
Line 307  sub Tick { Line 330  sub Tick {
     } else {      } else {
  $IdleSeconds = 0; # Reset idle count if not idle.   $IdleSeconds = 0; # Reset idle count if not idle.
     }      }
       #
       #  For each inflight transaction, tick down its timeout counter.
       #
       foreach $item (keys %ActiveTransactions) {
    my $Socket = $ActiveTransactions{$item}->getServer();
    $Socket->Tick();
       }
     # Do we have work in the queue, but no connections to service them?      # Do we have work in the queue, but no connections to service them?
     # If so, try to make some new connections to get things going again.      # If so, try to make some new connections to get things going again.
     #      #
Line 445  sub ClientWritable { Line 474  sub ClientWritable {
   
     } else { # Partial string sent.      } else { # Partial string sent.
  $Watcher->data(substr($Data, $result));   $Watcher->data(substr($Data, $result));
    if($result == 0) {    # client hung up on us!!
       Log("INFO", "lonc pipe client hung up on us!");
       $Watcher->cancel;
       $Socket->shutdown(2);
       $Socket->close();
    }
     }      }
           
  } else { # Error of some sort...   } else { # Error of some sort...
Line 1290  sub SetupLoncListener { Line 1325  sub SetupLoncListener {
       fd     => $socket);        fd     => $socket);
 }  }
   
   =pod 
   
   =head2 ChildStatus
    
   Child USR1 signal handler to report the most recent status
   into the status file.
   
   =cut
   sub ChildStatus {
       my $event = shift;
       my $watcher = $event->w;
   
       Debug(2, "Reporting child status because : ".$watcher->data);
       my $docdir = $perlvar{'lonDocRoot'};
       my $fh = IO::File->new(">>$docdir/lon-status/loncstatus.txt");
       print $fh $$."\t".$RemoteHost."\t".$Status."\t".
    $RecentLogEntry."\n";
   }
   
 =pod  =pod
   
 =head2 SignalledToDeath  =head2 SignalledToDeath
Line 1300  Called in response to a signal that caus Line 1354  Called in response to a signal that caus
   
   
 sub SignalledToDeath {  sub SignalledToDeath {
     Debug(2,"Signalled to death!");      my $event  = shift;
       my $watcher= $event->w;
   
       Debug(2,"Signalled to death! via ".$watcher->data);
     my ($signal) = @_;      my ($signal) = @_;
     chomp($signal);      chomp($signal);
     Log("CRITICAL", "Abnormal exit.  Child $$ for $RemoteHost "      Log("CRITICAL", "Abnormal exit.  Child $$ for $RemoteHost "
Line 1320  This sub implements a child process for Line 1377  This sub implements a child process for
 sub ChildProcess {  sub ChildProcess {
   
   
     # For now turn off signals.      #
           #  Signals must be handled by the Event framework...
     $SIG{QUIT}  = \&SignalledToDeath;  #
     $SIG{HUP}   = IGNORE;  #    $SIG{QUIT}  = \&SignalledToDeath;
     $SIG{USR1}  = IGNORE;  #    $SIG{HUP}   = \&ChildStatus;
     $SIG{INT}   = DEFAULT;  #    $SIG{USR1}  = IGNORE;
     $SIG{CHLD}  = IGNORE;  #    $SIG{INT}   = DEFAULT;
     $SIG{__DIE__}  = \&SignalledToDeath;  #    $SIG{CHLD}  = IGNORE;
   #    $SIG{__DIE__}  = \&SignalledToDeath;
   
       Event->signal(signal   => "QUIT",
     cb       => \&SignalledToDeath,
     data     => "QUIT");
       Event->signal(signal   => "HUP",
     cb       => \&ChildStatus,
     data     => "HUP");
       Event->signal(signal   => "USR1",
     cb       => \&ChildStatus,
     data     => "USR1");
   
     SetupTimer();      SetupTimer();
           
Line 1339  sub ChildProcess { Line 1407  sub ChildProcess {
   
 # Setup the initial server connection:  # Setup the initial server connection:
           
      # &MakeLondConnection(); // let first work requirest do it.       # &MakeLondConnection(); // let first work requirest do it.
   
   
     Debug(9,"Entering event loop");      Debug(9,"Entering event loop");
Line 1432  ShowStatus("Parent keeping the flock"); Line 1500  ShowStatus("Parent keeping the flock");
 #   Set up parent signals:  #   Set up parent signals:
 #  #
   
 $SIG{INT}  = \&KillThemAll;  $SIG{INT}  = \&Terminate;
 $SIG{TERM} = \&KillThemAll;   $SIG{TERM} = \&Terminate; 
   $SIG{HUP}  = \&Restart;
   $SIG{USR1} = \&CheckKids; 
   
 while(1) {  while(1) {
     $deadchild = wait();      $deadchild = wait();
Line 1448  while(1) { Line 1517  while(1) {
     }      }
 }  }
   
   
   
   =pod
   
   =head1 CheckKids
   
     Since kids do not die as easily in this implementation
   as the previous one, there  is no need to restart the
   dead ones (all dead kids get restarted when they die!!)
   The only thing this function does is to pass USR1 to the
   kids so that they report their status.
   
   =cut
   
   sub CheckKids {
       Debug(2, "Checking status of children");
       my $docdir = $perlvar{'lonDocRoot'};
       my $fh = IO::File->new(">$docdir/lon-status/loncstatus.txt");
       my $now=time;
       my $local=localtime($now);
       print $fh "LONC status $local - parent $$ \n\n";
       foreach $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
   
   =head1 Restart
   
   Signal handler for HUP... all children are killed and
   we self restart.  This is an el-cheapo way to re read
   the config file.
   
   =cut
   
   sub Restart {
       KillThemAll; # First kill all the children.
       Log("CRITICAL", "Restarting");
       my $execdir = $perlvar{'lonDaemons'};
       unlink("$execdir/logs/lonc.pid");
       exec("$execdir/lonc");
   }
   
 =pod  =pod
   
 =head1 KillThemAll  =head1 KillThemAll
Line 1466  sub KillThemAll { Line 1581  sub KillThemAll {
  ShowStatus("Killing lonc for $serving pid = $pid");   ShowStatus("Killing lonc for $serving pid = $pid");
  Log("CRITICAL", "Killing lonc for $serving pid = $pid");   Log("CRITICAL", "Killing lonc for $serving pid = $pid");
  kill('INT', $pid);   kill('INT', $pid);
    delete($ChildeHash{$pid});
     }      }
       my $execdir = $perlvar{'lonDaemons'};
       unlink("$execdir/logs/lonc.pid");
       ShowStatus("Killing the master process");
     Log("CRITICAL", "Killing the master process.");      Log("CRITICAL", "Killing the master process.");
     exit  
 }  }
   
 =pod  =pod
   
   =head1 Terminate
    
   Terminate the system.
   
   =cut
   
   sub Terminate {
       KillThemAll;
       exit;
   
   }
   =pod
   
 =head1 Theory  =head1 Theory
   
 The event class is used to build this as a single process with an  The event class is used to build this as a single process with an

Removed from v.1.12  
changed lines
  Added in v.1.15


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>