--- loncom/loncnew	2003/11/25 10:14:40	1.33
+++ loncom/loncnew	2004/01/13 09:57:18	1.39
@@ -2,7 +2,7 @@
 # The LearningOnline Network with CAPA
 # lonc maintains the connections to remote computers
 #
-# $Id: loncnew,v 1.33 2003/11/25 10:14:40 foxr Exp $
+# $Id: loncnew,v 1.39 2004/01/13 09:57:18 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -35,12 +35,12 @@
 #    - Add ability to create/negotiate lond connections (done).
 #    - Add general logic for dispatching requests and timeouts. (done).
 #    - Add support for the lonc/lond requests.          (done).
-#    - Add logging/status monitoring.
-#    - Add Signal handling - HUP restarts. USR1 status report.
+#    - Add logging/status monitoring.                    (done)
+#    - Add Signal handling - HUP restarts. USR1 status report. (done)
 #    - Add Configuration file I/O                       (done).
-#    - Add management/status request interface.
+#    - Add management/status request interface.         (done)
 #    - Add deferred request capability.                  (done)
-#    - Detect transmission timeouts.
+#    - Detect transmission timeouts.                     (done)
 #
 
 use strict;
@@ -89,6 +89,8 @@ my $DebugLevel = 0;
 my $NextDebugLevel= 2;		# So Sigint can toggle this.
 my $IdleTimeout= 3600;		# Wait an hour before pruning connections.
 
+my $LogTransactions = 0;	# When True, all transactions/replies get logged.
+
 #
 #  The variables below are only used by the child processes.
 #
@@ -210,7 +212,6 @@ sub GetPeername {
 	return $peerfile;
     }
 }
-#----------------------------- Timer management ------------------------
 =pod
 
 =head2 Debug
@@ -262,11 +263,14 @@ sub ShowStatus {
 =cut
 sub SocketTimeout {
     my $Socket = shift;
-    
+    Log("WARNING", "A socket timeout was detected");
+    Debug(0, " SocketTimeout called: ");
+    $Socket->Dump();
     KillSocket($Socket);	# A transaction timeout also counts as
                                 # a connection failure:
     $ConnectionRetriesLeft--;
 }
+#----------------------------- Timer management ------------------------
 
 =pod
 
@@ -301,9 +305,13 @@ sub Tick {
     #
     #  For each inflight transaction, tick down its timeout counter.
     #
-    foreach my $item (keys %ActiveTransactions) {
-	my $Socket = $ActiveTransactions{$item}->getServer();
-	$Socket->Tick();
+
+    foreach my $item (keys %ActiveConnections) {
+	my $State = $ActiveConnections{$item}->data->GetState();
+	if ($State ne 'Idle') {
+	    Debug(5,"Ticking Socket $State $item");
+	    $ActiveConnections{$item}->data->Tick();
+	}
     }
     # 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.
@@ -507,6 +515,9 @@ sub CompleteTransaction {
 
     if (!$Transaction->isDeferred()) { # Normal transaction
 	my $data   = $Socket->GetReply(); # Data to send.
+	if($LogTransactions) {
+	    Log("SUCCESS", "Reply from lond: '$data'");
+	}
 	StartClientReply($Transaction, $data);
     } else {			# Delete deferred transaction file.
 	Log("SUCCESS", "A delayed transaction was completed");
@@ -651,9 +662,9 @@ sub KillSocket {
     }
     if(exists($ActiveConnections{$Socket})) {
 	delete($ActiveConnections{$Socket});
+	$ConnectionCount--;
+	if ($ConnectionCount < 0) { $ConnectionCount = 0; }
     }
-    $ConnectionCount--;
-
     #  If the connection count has gone to zero and there is work in the
     #  work queue, the work all gets failed with con_lost.
     #
@@ -1211,6 +1222,9 @@ sub ClientRequest {
 	    exit;
 	}
 	Debug(8, "Complete transaction received: ".$data);
+	if($LogTransactions) {
+	    Log("SUCCESS", "Transaction: '$data'"); # Transaction has \n.
+	}
 	my $Transaction = LondTransaction->new($data);
 	$Transaction->SetClient($socket);
 	QueueTransaction($Transaction);
@@ -1319,6 +1333,24 @@ sub SetupLoncListener {
 	      fd     => $socket);
 }
 
+#
+#   Toggle transaction logging.
+#  Implicit inputs:  
+#     LogTransactions
+#  Implicit Outputs:
+#     LogTransactions
+sub ToggleTransactionLogging {
+    print STDERR "Toggle transaction logging...\n";
+    if(!$LogTransactions) {
+	$LogTransactions = 1;
+    } else {
+	$LogTransactions = 0;
+    }
+
+
+    Log("SUCCESS", "Toggled transaction logging: $LogTransactions \n");
+}
+
 =pod 
 
 =head2 ChildStatus
@@ -1338,6 +1370,20 @@ sub ChildStatus {
     my $fh = IO::File->new(">>$docdir/lon-status/loncstatus.txt");
     print $fh $$."\t".$RemoteHost."\t".$Status."\t".
 	$RecentLogEntry."\n";
+    #
+    #  Write out information about each of the connections:
+    #
+    print $fh "Active connection statuses: \n";
+    my $i = 1;
+    print STDERR  "================================= Socket Status Dump:\n";
+    foreach my $item (keys %ActiveConnections) {
+	my $Socket = $ActiveConnections{$item}->data;
+	my $state  = $Socket->GetState();
+	print $fh "Connection $i State: $state\n";
+	print STDERR "---------------------- Connection $i \n";
+	$Socket->Dump();
+	$i++;	
+    }
     $ConnectionRetriesLeft = $ConnectionRetries;
 }
 
@@ -1402,6 +1448,8 @@ sub ChildProcess {
     Event->signal(signal   => "USR1",
 		  cb       => \&ChildStatus,
 		  data     => "USR1");
+    Event->signal(signal   => "USR2",
+		  cb       => \&ToggleTransactionLogging);
     Event->signal(signal   => "INT",
 		  cb       => \&ToggleDebug,
 		  data     => "INT");