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

foxr lon-capa-cvs@mail.lon-capa.org
Thu, 24 Apr 2003 10:56:55 -0000


foxr		Thu Apr 24 06:56:55 2003 EDT

  Modified files:              
    /loncom	loncnew 
  Log:
  Added code to roll back connection counts.  Also added code to show
  status of daemon on ps -axuww: show who 'I'm connected to and current connection
  count
  
  
Index: loncom/loncnew
diff -u loncom/loncnew:1.3 loncom/loncnew:1.4
--- loncom/loncnew:1.3	Thu Apr 17 23:10:36 2003
+++ loncom/loncnew	Thu Apr 24 06:56:55 2003
@@ -2,7 +2,7 @@
 # The LearningOnline Network with CAPA
 # lonc maintains the connections to remote computers
 #
-# $Id: loncnew,v 1.3 2003/04/18 03:10:36 albertel Exp $
+# $Id: loncnew,v 1.4 2003/04/24 10:56:55 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -100,7 +100,7 @@
 my $WorkQueue       = Queue->new(); # Queue of pending transactions.
 my $ClientQueue     = Queue->new(); # Queue of clients causing xactinos.
 my $ConnectionCount = 0;
-
+my $IdleSeconds     = 0;	# Number of seconds idle.
 
 #
 
@@ -163,11 +163,25 @@
 
 sub Tick {
     my $client;
+    $0 = 'lonc: '.GetServerHost()." Connection count: ".$ConnectionCount;
     Debug(6, "Tick");
     Debug(6, "    Current connection count: ".$ConnectionCount);
     foreach $client (keys %ActiveClients) {
 	Debug(7, "    Have client:  with id: ".$ActiveClients{$client});
     }
+    # Is it time to prune connection count:
+
+
+    if($IdleConnections->Count()  && 
+       ($WorkQueue->Count() == 0)) { # Idle connections and nothing to do?
+	$IdleSeconds++;
+	if($IdleSeconds > $IdleTimeout) { # Prune a connection...
+	    $Socket = $IdleConnections->pop();
+	    KillSocket($Socket, 0);
+	}
+    } else {
+	$IdleSeconds = 0;	# Reset idle count if not idle.
+    }
 }
 
 =pod
@@ -348,7 +362,77 @@
 	      cb       => \&ClientWritable,
 	      data     => $data);
 }
+=pod
+=head2 FailTransaction
+
+  Finishes a transaction with failure because the associated lond socket
+  disconnected.  It is up to our client to retry if desired.  
+
+Parameters:
+
+=item client  
+ 
+   The UNIX domain socket open on our client.
+
+=cut
+
+sub FailTransaction {
+    my $client = shift;
+
+    &Debug(8, "Failing transaction due to disconnect");
+    my $Serial = $ActiveClients{$client};
+    my $desc   = sprintf("Connection to lonc client %d", $Serial);
+    my $data   = "error: Connection to lond lost\n";
+
+    Event->io(fd     => $client,
+	      poll   => "w",
+	      desc   => $desc,
+	      cb     => \&ClientWritable,
+	      data   => $data);
+
+}
+
+=pod
+
+=head2 KillSocket
+ 
+Destroys a socket.  This function can be called either when a socket
+has died of 'natural' causes or because a socket needs to be pruned due to
+idleness.  If the socket has died naturally, if there are no longer any 
+live connections a new connection is created (in case there are transactions
+in the queue).  If the socket has been pruned, it is never re-created.
+
+Parameters:
 
+=item Socket
+ 
+  The socket to kill off.
+
+=item Restart
+
+nonzero if we are allowed to create a new connection.
+
+
+=cut
+sub KillSocket {
+    my $Socket = shift;
+    my $Restart= shift;
+
+    #  If the socket came from the active connection set, delete it.
+    # otherwise it came from the idle set and has already been destroyed:
+    
+    if(exists($ActiveTransactions{$Socket})) {
+	delete ($ActiveTransactions{$Socket});
+    }
+    if(exists($ActiveConnections{$Socket})) {
+	delete($ActiveConnections{$Socket});
+    }
+    $ConnectionCount--;
+    if( ($ConnectionCount = 0) && ($Restart)) {
+	MakeLondConnection();
+    }
+
+}
 
 =pod
 
@@ -421,7 +505,16 @@
     SocketDump(6, $Socket);
 
     if($Socket->Readable() != 0) {
-	 # bad return from socket read.
+	 # bad return from socket read. Currently this means that
+	# The socket has become disconnected. We fail the transaction.
+
+	if(exists($ActiveTransactions{$Socket})) {
+	    Debug(3,"Lond connection lost failing transaction");
+	    FailTransaction($ActiveTransactions{$Socket});
+	}
+	$Watcher->cancel();
+	KillSocket($Socket, 1);
+	return;
     }
     SocketDump(6,$Socket);
 
@@ -557,11 +650,20 @@
     SocketDump(6,$Socket);
 
     if      ($State eq "Connected")         {
-	#  "init" is being sent...
 
 	if ($Socket->Writable() != 0) {
 	    #  The write resulted in an error.
+	    # We'll treat this as if the socket got disconnected:
+	    if(exists($ActiveTransactions{$Socket})) {
+		Debug(3, "Lond connection lost, failing transactions");
+		FailTransaction($ActiveTransactions{$Socket});
+	    }
+	    $Watcher->cancel();
+	    KillSocket($Socket, 1);
+	    return;
 	}
+	#  "init" is being sent...
+
 	
     } elsif ($State eq "Initialized")       {
 
@@ -672,7 +774,7 @@
 		       cb       => \&LondWritable,
 		       data     => ($Connection, undef),
 		       desc => 'Connection to lond server');
-    $ActiveConnections{$Lond} = $event;
+    $ActiveConnections{$Connection} = $event;
 
     $ConnectionCount++;