[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--