Diff for /loncom/loncnew between versions 1.52 and 1.60

version 1.52, 2004/08/30 11:01:04 version 1.60, 2004/09/22 11:11:54
Line 104  my $ConnectionRetries=2; # Number of con Line 104  my $ConnectionRetries=2; # Number of con
 my $ConnectionRetriesLeft=2; # Number of connection retries remaining.  my $ConnectionRetriesLeft=2; # Number of connection retries remaining.
 my $LondVersion     = "unknown"; # Version of lond we talk with.  my $LondVersion     = "unknown"; # Version of lond we talk with.
 my $KeyMode         = "";       # e.g. ssl, local, insecure from last connect.  my $KeyMode         = "";       # e.g. ssl, local, insecure from last connect.
   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.
   
 #  #
 #   The hash below gives the HTML format for log messages  #   The hash below gives the HTML format for log messages
Line 118  $LogFormats{"WARNING"}  = "<font color=' Line 124  $LogFormats{"WARNING"}  = "<font color='
 $LogFormats{"DEFAULT"}  = " %s ";  $LogFormats{"DEFAULT"}  = " %s ";
   
   
   #  UpdateStatus;
   #    Update the idle status display to show how many connections
   #    are left, retries and other stuff.
   #
   sub UpdateStatus {
       if ($ConnectionRetriesLeft > 0) {
    ShowStatus(GetServerHost()." Connection count: ".$ConnectionCount
      ." Retries remaining: ".$ConnectionRetriesLeft
      ." ($KeyMode)");
       } else {
    ShowStatus(GetServerHost()." >> DEAD <<");
       }
   }
   
   
 =pod  =pod
   
Line 275  sub SocketTimeout { Line 295  sub SocketTimeout {
     $ConnectionRetriesLeft--;      $ConnectionRetriesLeft--;
     if($ConnectionRetriesLeft <= 0) {      if($ConnectionRetriesLeft <= 0) {
  Log("CRITICAL", "Host marked DEAD: ".GetServerHost());   Log("CRITICAL", "Host marked DEAD: ".GetServerHost());
    $LondConnecting = 0;
     }      }
   
 }  }
Line 294  sub Tick { Line 315  sub Tick {
     my $clock_watcher = $Event->w;      my $clock_watcher = $Event->w;
   
     my $client;      my $client;
     if($ConnectionRetriesLeft > 0) {      UpdateStatus();
  ShowStatus(GetServerHost()." Connection count: ".$ConnectionCount  
    ." Retries remaining: ".$ConnectionRetriesLeft  
    ." ($KeyMode)");  
     } else {  
  ShowStatus(GetServerHost()." >> DEAD <<");  
     }  
     # Is it time to prune connection count:      # Is it time to prune connection count:
   
   
Line 310  sub Tick { Line 326  sub Tick {
  if($IdleSeconds > $IdleTimeout) { # Prune a connection...   if($IdleSeconds > $IdleTimeout) { # Prune a connection...
     my $Socket = $IdleConnections->pop();      my $Socket = $IdleConnections->pop();
     KillSocket($Socket);      KillSocket($Socket);
       $IdleSeconds = 0; # Otherwise all connections get trimmed to fast.
       UpdateStatus();
       if(($ConnectionCount == 0) && $DieWhenIdle) {
    #
    #  Create a lock file since there will be a time window
    #  between our exit and the parent's picking up the listen
    #  during which no listens will be done on the
    #  lonnet client socket.
    #
    my $lock_file = GetLoncSocketPath().".lock";
    open(LOCK,">$lock_file");
    print LOCK "Contents not important";
    close(LOCK);
   
    exit(0);
       }
  }   }
     } else {      } else {
  $IdleSeconds = 0; # Reset idle count if not idle.   $IdleSeconds = 0; # Reset idle count if not idle.
Line 328  sub Tick { Line 360  sub 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.
     #      #
           #   Note this code is dead now...
       #
     my $Requests = $WorkQueue->Count();      my $Requests = $WorkQueue->Count();
     if (($ConnectionCount == 0)  && ($Requests > 0)) {       if (($ConnectionCount == 0)  && ($Requests > 0) && (!$LondConnecting)) { 
  if ($ConnectionRetriesLeft > 0) {   if ($ConnectionRetriesLeft > 0) {
     my $Connections = ($Requests <= $MaxConnectionCount) ?      Debug(5,"Work but no connections, Make a new one");
  $Requests : $MaxConnectionCount;      my $success;
     Debug(5,"Work but no connections, start ".$Connections." of them");      $success    = &MakeLondConnection;
     my $successCount = 0;      if($success == 0) { # All connections failed:
     for (my $i =0; $i < $Connections; $i++) {  
  $successCount += MakeLondConnection();  
     }  
     if($successCount == 0) { # All connections failed:  
  Debug(5,"Work in queue failed to make any connectiouns\n");   Debug(5,"Work in queue failed to make any connectiouns\n");
  EmptyQueue(); # Fail pending transactions with con_lost.   EmptyQueue(); # Fail pending transactions with con_lost.
  CloseAllLondConnections(); # Should all be closed but....   CloseAllLondConnections(); # Should all be closed but....
     }      }
  } else {   } else {
       $LondConnecting = 0;
     ShowStatus(GetServerHost()." >>> DEAD!!! <<<");      ShowStatus(GetServerHost()." >>> DEAD!!! <<<");
     Debug(5,"Work in queue, but gave up on connections..flushing\n");      Debug(5,"Work in queue, but gave up on connections..flushing\n");
     EmptyQueue(); # Connections can't be established.      EmptyQueue(); # Connections can't be established.
Line 797  sub LondReadable { Line 827  sub LondReadable {
     "Lond connection lost.");      "Lond connection lost.");
  if(exists($ActiveTransactions{$Socket})) {   if(exists($ActiveTransactions{$Socket})) {
     FailTransaction($ActiveTransactions{$Socket});      FailTransaction($ActiveTransactions{$Socket});
    } else {
       #  Socket is connecting and failed... need to mark
       #  no longer connecting.
      
       $LondConnecting = 0;
  }   }
  $Watcher->cancel();   $Watcher->cancel();
  KillSocket($Socket);   KillSocket($Socket);
Line 871  sub LondReadable { Line 906  sub LondReadable {
  .$RemoteHost." now ready for action");   .$RemoteHost." now ready for action");
  }   }
  ServerToIdle($Socket); # Next work unit or idle.   ServerToIdle($Socket); # Next work unit or idle.
   
    #
    $LondConnecting = 0; # Best spot I can think of for this.
    # 
   
     } elsif ($State eq "SendingRequest") {      } elsif ($State eq "SendingRequest") {
  #  We need to be writable for this and probably don't belong   #  We need to be writable for this and probably don't belong
Line 984  sub LondWritable { Line 1023  sub LondWritable {
     " has been disconnected");      " has been disconnected");
  if(exists($ActiveTransactions{$Socket})) {   if(exists($ActiveTransactions{$Socket})) {
     FailTransaction($ActiveTransactions{$Socket});      FailTransaction($ActiveTransactions{$Socket});
    } else {
       #  In the process of conneting, so need to turn that off.
       
       $LondConnecting = 0;
  }   }
  $Watcher->cancel();   $Watcher->cancel();
  KillSocket($Socket);   KillSocket($Socket);
Line 1154  sub MakeLondConnection { Line 1197  sub MakeLondConnection {
  }   }
  Log("SUCESS", "Created connection ".$ConnectionCount   Log("SUCESS", "Created connection ".$ConnectionCount
     ." to host ".GetServerHost());      ." to host ".GetServerHost());
    $LondConnecting = 1; # Connection in progress.
  return 1; # Return success.   return 1; # Return success.
     }      }
           
Line 1237  sub QueueTransaction { Line 1281  sub QueueTransaction {
     if(!defined $LondSocket) { # Need to queue request.      if(!defined $LondSocket) { # Need to queue request.
  Debug(5,"Must queue...");   Debug(5,"Must queue...");
  $WorkQueue->enqueue($requestData);   $WorkQueue->enqueue($requestData);
  if($ConnectionCount < $MaxConnectionCount) {   Debug(5, "Queue Transaction startnew $ConnectionCount $LondConnecting");
    if(($ConnectionCount < $MaxConnectionCount)   && (! $LondConnecting)) {
   
     if($ConnectionRetriesLeft > 0) {      if($ConnectionRetriesLeft > 0) {
  Debug(5,"Starting additional lond connection");   Debug(5,"Starting additional lond connection");
  if(MakeLondConnection() == 0) {   if(&MakeLondConnection() == 0) {
     EmptyQueue(); # Fail transactions, can't make connection.      EmptyQueue(); # Fail transactions, can't make connection.
     CloseAllLondConnections; # Should all be closed but...      CloseAllLondConnections; # Should all be closed but...
  }   }
     } else {      } else {
  ShowStatus(GetServerHost()." >>> DEAD !!!! <<<");   ShowStatus(GetServerHost()." >>> DEAD !!!! <<<");
    $LondConnecting = 0;
  EmptyQueue(); # It's worse than that ... he's dead Jim.   EmptyQueue(); # It's worse than that ... he's dead Jim.
  CloseAllLondConnections; # Should all be closed but..   CloseAllLondConnections; # Should all be closed but..
     }      }
Line 1351  sub NewClient { Line 1398  sub NewClient {
 Returns the name of the UNIX socket on which to listen for client  Returns the name of the UNIX socket on which to listen for client
 connections.  connections.
   
   =head2 Parameters:
   
       host (optional)  - Name of the host socket to return.. defaults to
                          the return from GetServerHost().
   
 =cut  =cut
   
 sub GetLoncSocketPath {  sub GetLoncSocketPath {
     return $UnixSocketDir."/".GetServerHost();  
       my $host = GetServerHost(); # Default host.
       if (@_) {
    ($host)  = @_; # Override if supplied.
       }
       return $UnixSocketDir."/".$host;
 }  }
   
 =pod  =pod
Line 1391  connection.  The event handler establish Line 1448  connection.  The event handler establish
 (creating a communcations channel), that int turn will establish  (creating a communcations channel), that int turn will establish
 another event handler to subess requests.  another event handler to subess requests.
   
   =head2  Parameters:
   
      host (optional)   Name of the host to set up a unix socket to.
   
 =cut  =cut
   
 sub SetupLoncListener {  sub SetupLoncListener {
   
       my $host       = GetServerHost(); # Default host.
       if (@_) {
    ($host)    = @_ # Override host with parameter.
       }
   
     my $socket;      my $socket;
     my $SocketName = GetLoncSocketPath();      my $SocketName = GetLoncSocketPath($host);
     unlink($SocketName);      unlink($SocketName);
     unless ($socket =IO::Socket::UNIX->new(Local  => $SocketName,      unless ($socket =IO::Socket::UNIX->new(Local  => $SocketName,
     Listen => 10,       Listen => 250, 
     Type   => SOCK_STREAM)) {      Type   => SOCK_STREAM)) {
  die "Failed to create a lonc listner socket";   die "Failed to create a lonc listner socket";
     }      }
     Event->io(cb     => \&NewClient,      return $socket;
       poll   => 'r',  
       desc   => 'Lonc listener Unix Socket',  
       fd     => $socket);  
 }  }
   
 #  #
Line 1534  sub ChildProcess { Line 1597  sub ChildProcess {
   data     => "INT");    data     => "INT");
   
           
     SetupLoncListener();      my $socket =  SetupLoncListener();
       Event->io(cb   => \&NewClient,
         poll => 'r',
         desc => 'Lonc Listener Unix Socket',
         fd   => $socket);
           
     $Event::Debuglevel = $DebugLevel;      $Event::Debuglevel = $DebugLevel;
           
Line 1625  Log("CRITICAL", "--------------- Startin Line 1692  Log("CRITICAL", "--------------- Startin
   
 LondConnection::ReadConfig;               # Read standard config files.  LondConnection::ReadConfig;               # Read standard config files.
 my $HostIterator = LondConnection::GetHostIterator;  my $HostIterator = LondConnection::GetHostIterator;
 while (! $HostIterator->end()) {  
   
     my $hostentryref = $HostIterator->get();  if ($DieWhenIdle) {
     CreateChild($hostentryref->[0]);      print "Die when idle socket monitoring is not yet implemented\n";
     $HostHash{$hostentryref->[0]} = $hostentryref->[4];      exit(-1);
     $HostIterator->next();  } else {
       
       while (! $HostIterator->end()) {
   
    my $hostentryref = $HostIterator->get();
    CreateChild($hostentryref->[0]);
    $HostHash{$hostentryref->[0]} = $hostentryref->[4];
    $HostIterator->next();
       }
 }  }
   
 $RemoteHost = "Parent Server";  $RemoteHost = "Parent Server";
   
 # Maintain the population:  # Maintain the population:
Line 1642  ShowStatus("Parent keeping the flock"); Line 1717  ShowStatus("Parent keeping the flock");
 #   Set up parent signals:  #   Set up parent signals:
 #  #
   
 $SIG{INT}  = \&Terminate;  if ($DieWhenIdle) {
 $SIG{TERM} = \&Terminate;       print "Die when idle main processing not yet implemented";
 $SIG{HUP}  = \&Restart;      exit (-1);
 $SIG{USR1} = \&CheckKids;   } else {
 $SIG{USR2} = \&UpdateKids; # LonManage update request.      
       $SIG{INT}  = \&Terminate;
 while(1) {      $SIG{TERM} = \&Terminate; 
     my $deadchild = wait();      $SIG{HUP}  = \&Restart;
     if(exists $ChildHash{$deadchild}) { # need to restart.      $SIG{USR1} = \&CheckKids; 
  my $deadhost = $ChildHash{$deadchild};      $SIG{USR2} = \&UpdateKids; # LonManage update request.
  delete($HostToPid{$deadhost});      
  delete($ChildHash{$deadchild});      while(1) {
  Log("WARNING","Lost child pid= ".$deadchild.   my $deadchild = wait();
       "Connected to host ".$deadhost);   if(exists $ChildHash{$deadchild}) { # need to restart.
  Log("INFO", "Restarting child procesing ".$deadhost);      my $deadhost = $ChildHash{$deadchild};
  CreateChild($deadhost);      delete($HostToPid{$deadhost});
       delete($ChildHash{$deadchild});
       Log("WARNING","Lost child pid= ".$deadchild.
    "Connected to host ".$deadhost);
       Log("INFO", "Restarting child procesing ".$deadhost);
       CreateChild($deadhost);
    }
     }      }
 }  }
   
   
   
 =pod  =pod
   
 =head1 CheckKids  =head1 CheckKids

Removed from v.1.52  
changed lines
  Added in v.1.60


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