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

foxr lon-capa-cvs@mail.lon-capa.org
Tue, 03 Jun 2003 01:59:39 -0000


This is a MIME encoded message

--foxr1054605579
Content-Type: text/plain

foxr		Mon Jun  2 21:59:39 2003 EDT

  Modified files:              
    /loncom	loncnew 
  Log:
  complete coding to support deferred transactions.
  
  
--foxr1054605579
Content-Type: text/plain
Content-Disposition: attachment; filename="foxr-20030602215939.txt"

Index: loncom/loncnew
diff -u loncom/loncnew:1.6 loncom/loncnew:1.7
--- loncom/loncnew:1.6	Mon May  5 19:40:27 2003
+++ loncom/loncnew	Mon Jun  2 21:59:39 2003
@@ -2,7 +2,7 @@
 # The LearningOnline Network with CAPA
 # lonc maintains the connections to remote computers
 #
-# $Id: loncnew,v 1.6 2003/05/05 23:40:27 foxr Exp $
+# $Id: loncnew,v 1.7 2003/06/03 01:59:39 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -34,13 +34,22 @@
 #    - Add timer dispatch.       (done)
 #    - Add ability to accept lonc UNIX domain sockets.  (done)
 #    - Add ability to create/negotiate lond connections (done).
-#    - Add general logic for dispatching requests and timeouts.
-#    - Add support for the lonc/lond requests.
+#    - 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 Configuration file I/O
+#    - Add Configuration file I/O                       (done).
 #    - Add Pending request processing on startup.
 #    - Add management/status request interface.
+#    - Add deferred request capability.
+#
+
+# Change log:
+#    $Log: loncnew,v $
+#    Revision 1.7  2003/06/03 01:59:39  foxr
+#    complete coding to support deferred transactions.
+#
+#
 
 use lib "/home/httpd/lib/perl/";
 use lib "/home/foxr/newloncapa/types";
@@ -55,6 +64,7 @@
 use LONCAPA::Queue;
 use LONCAPA::Stack;
 use LONCAPA::LondConnection;
+use LONCAPA::LondTransaction;
 use LONCAPA::Configuration;
 use LONCAPA::HashIterator;
 
@@ -96,10 +106,10 @@
 my $UnixSocketDir= "/home/httpd/sockets"; 
 my $IdleConnections = Stack->new(); # Set of idle connections
 my %ActiveConnections;		# Connections to the remote lond.
-my %ActiveTransactions;		# Transactions in flight.
+my %ActiveTransactions;		# LondTransactions in flight.
 my %ActiveClients;		# Serial numbers of active clients by socket.
 my $WorkQueue       = Queue->new(); # Queue of pending transactions.
-my $ClientQueue     = Queue->new(); # Queue of clients causing xactinos.
+#  my $ClientQueue     = Queue->new(); # Queue of clients causing xactinos.
 my $ConnectionCount = 0;
 my $IdleSeconds     = 0;	# Number of seconds idle.
 
@@ -257,24 +267,20 @@
 
 sub ServerToIdle {
     my $Socket   = shift;	# Get the socket.
+    delete($ActiveTransactions{$Socket}); # Server has no transaction
 
     &Debug(6, "Server to idle");
 
     #  If there's work to do, start the transaction:
 
-    $reqdata = $WorkQueue->dequeue();
-    Debug(9, "Queue gave request data: ".$reqdata);
+    $reqdata = $WorkQueue->dequeue(); # This is a LondTransaction
     unless($reqdata eq undef)  {
-	my $unixSocket = $ClientQueue->dequeue();
-	&Debug(6, "Starting new work request");
-	&Debug(7, "Request: ".$reqdata);
-	
-	&StartRequest($Socket, $unixSocket, $reqdata);
+	Debug(9, "Queue gave request data: ".$reqdata->getRequest());
+	&StartRequest($Socket,  $reqdata);
     } else {
 	
     #  There's no work waiting, so push the server to idle list.
 	&Debug(8, "No new work requests, server connection going idle");
-	delete($ActiveTransactions{$Socket});
 	$IdleConnections->push($Socket);
     }
 }
@@ -378,30 +384,46 @@
 Socket on which the lond transaction occured.  This is a
 LondConnection. The data received is in the TransactionReply member.
 
-=item Client
+=item Transaction
 
-Unix domain socket open on the ultimate client.
+The transaction that is being completed.
 
 =cut
 
 sub CompleteTransaction {
     &Debug(6,"Complete transaction");
     my $Socket = shift;
-    my $Client = shift;
+    my $Transaction = shift;
 
-    my $data   = $Socket->GetReply(); # Data to send.
-    StartClientReply($Client, $data);
+    if (!$Transaction->isDeferred()) { # Normal transaction
+	my $data   = $Socket->GetReply(); # Data to send.
+	StartClientReply($Transaction, $data);
+    } else {			# Delete deferred transaction file.
+	unlink $Transaction->getFile();
+    }
 }
 =pod
 =head1 StartClientReply
 
    Initiates a reply to a client where the reply data is a parameter.
 
+=head2  parameters:
+
+=item Transaction
+
+    The transaction for which we are responding to the client.
+
+=item data
+
+    The data to send to apached client.
+
 =cut
 sub StartClientReply {
-    my $Client   = shift;
+    my $Transaction   = shift;
     my $data     = shift;
 
+    my $Client   = $Transaction->getClient();
+
     &Debug(8," Reply was: ".$data);
     my $Serial         = $ActiveClients{$Client};
     my $desc           = sprintf("Connection to lonc client %d",
@@ -417,32 +439,46 @@
 =head2 FailTransaction
 
   Finishes a transaction with failure because the associated lond socket
-  disconnected.  It is up to our client to retry if desired.  
+  disconnected.  There are two possibilities:
+  - The transaction is deferred: in which case we just quietly
+    delete the transaction since there is no client connection.
+  - The transaction is 'live' in which case we initiate the sending
+    of "con_lost" to the client.
+
+Deleting the transaction means killing it from the 
+%ActiveTransactions hash.
 
 Parameters:
 
 =item client  
  
-   The UNIX domain socket open on our client.
-
+   The LondTransaction we are failing.
+ 
 =cut
 
 sub FailTransaction {
-    my $client = shift;
-
-    StartClientReply($client, "con_lost");
+    my $transaction = shift;
+    my $Lond        = $transaction->getServer();
+    if (!$client->isDeferred()) { # If the transaction is deferred we'll get to it.
+	my $client  = $transcation->getClient();
+	StartClientReply($client, "con_lost");
+    }
+# not needed, done elsewhere if active.
+#    delete $ActiveTransactions{$Lond};
 
 }
 
 =pod
 =head1  EmptyQueue
+
   Fails all items in the work queue with con_lost.
+  Note that each item in the work queue is a transaction.
+
 =cut
 sub EmptyQueue {
     while($WorkQueue->Count()) {
-	my $request = $WorkQUeue->dequeue(); # Just to help it become empty.
-	my $client  = $ClientQueue->dequeue(); #  Need to con_lost this guy.
-	FailTransaction($client);
+	my $request = $Workqueue->dequeue(); # This is a transaction
+	FailTransaction($request);
     }
 }
 
@@ -471,8 +507,11 @@
 sub KillSocket {
     my $Socket = 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 the socket came from the active connection set,
+    #  delete its transaction... note that FailTransaction should
+    #  already have been called!!!
+    #  otherwise it came from the idle set.
+    #  
     
     if(exists($ActiveTransactions{$Socket})) {
 	delete ($ActiveTransactions{$Socket});
@@ -695,7 +734,7 @@
     my @data    = $Watcher->data;
     Debug(6,"LondWritable State = ".$State." data has ".@data." elts.\n");
 
-    my $Socket  = $data[0];	# I know there's at least a socket.
+    my $Socket  = $data;	# I know there's at least a socket.
 
     #  Figure out what to do depending on the state of the socket:
     
@@ -814,7 +853,9 @@
 	my $Handle = IO::File->new($reqfile);
 	my $cmd    = <$Handle>;
 	chomp($cmd);
-	QueueTransaction($NullSocket, $cmd);
+	my $Transaction = LondTransaction->new($cmd);
+	$Transaction->SetDeferred($reqfile);
+	QueueTransaction($Transaction);
     }
     
 }
@@ -857,7 +898,7 @@
 	$event = Event->io(fd       => $Socket,
 			   poll     => 'w',
 			   cb       => \&LondWritable,
-			   data     => ($Connection, undef),
+			   data     => \$Connection,
 			   desc => 'Connection to lond server');
 	$ActiveConnections{$Connection} = $event;
 	
@@ -896,16 +937,16 @@
 
 sub StartRequest {
     my $Lond     = shift;
-    my $Client   = shift;
-    my $Request  = shift;
+    my $Request  = shift;	# This is a LondTransaction.
     
-    Debug(6, "StartRequest: ".$Request);
+    Debug(6, "StartRequest: ".$Request->getRequest());
 
     my $Socket = $Lond->GetSocket();
     
-    $ActiveTransactions{$Lond} = $Client; # Socket to relay to client.
+    $Request->Activate($Lond);
+    $ActiveTransactions{$Lond} = $Request;
 
-    $Lond->InitiateTransaction($Request);
+    $Lond->InitiateTransaction($Request->getRequest());
     $event = Event->io(fd      => $Lond->GetSocket(),
 		       poll    => "w",
 		       cb      => \&LondWritable,
@@ -937,15 +978,15 @@
 =cut
 
 sub QueueTransaction {
-    my $requestSocket = shift;
-    my $requestData   = shift;
 
-    Debug(6,"QueueTransaction: ".$requestData);
+    my $requestData   = shift;	# This is a LondTransaction.
+    my $cmd           = $requestData->getRequest();
+
+    Debug(6,"QueueTransaction: ".$cmd);
 
     my $LondSocket    = $IdleConnections->pop();
     if(!defined $LondSocket) {	# Need to queue request.
 	Debug(8,"Must queue...");
-	$ClientQueue->enqueue($requestSocket);
 	$WorkQueue->enqueue($requestData);
 	if($ConnectionCount < $MaxConnectionCount) {
 	    Debug(4,"Starting additional lond connection");
@@ -953,7 +994,7 @@
 	}
     } else {			# Can start the request:
 	Debug(8,"Can start...");
-	StartRequest($LondSocket, $requestSocket, $requestData);
+	StartRequest($LondSocket,  $requestData);
     }
 }
 
@@ -993,7 +1034,9 @@
     $watcher->data($data);
     if($data =~ /(.*\n)/) {	# Request entirely read.
 	Debug(8, "Complete transaction received: ".$data);
-	QueueTransaction($socket, $data);
+	my $Transaction = new LondTransaction->new($data);
+	$Transaction->SetClient($socket);
+	QueueTransaction($Transaction);
 	$watcher->cancel();	# Done looking for input data.
     }
 
@@ -1055,7 +1098,7 @@
 
 =cut
 
-sub GetServerHost {		# Stub - get this from config.
+sub GetServerHost {
     return $RemoteHost;		# Setup by the fork.
 }
 
@@ -1067,7 +1110,7 @@
 
 =cut
 
-sub GetServerPort {		# Stub - get this from config.
+sub GetServerPort {
     return $perlvar{londPort};
 }
 
@@ -1088,7 +1131,7 @@
     my $socket;
     my $SocketName = GetLoncSocketPath();
     unlink($SocketName);
-    unless ($socket = IO::Socket::UNIX->new(Local  => $SocketName,
+    unless ($socket =IO::Socket::UNIX->new(Local  => $SocketName,
 					    Listen => 10, 
 					    Type   => SOCK_STREAM)) {
 	die "Failed to create a lonc listner socket";

--foxr1054605579--