[LON-CAPA-cvs] cvs: loncom / loncnew
foxr
lon-capa-cvs@mail.lon-capa.org
Tue, 17 Feb 2004 09:43:21 -0000
foxr Tue Feb 17 04:43:21 2004 EDT
Modified files:
/loncom loncnew
Log:
- Clean up write logic and factor out common code.
- Fix up some error logic to ensure that:
o All failed transactions fromthe lonc point of view close the
associated connection
o All closures of a lond connection will fail any associated transaction
o A bit of defensive programming when closing a connection that should be
idle to ensure that any bad book-keeping gets cleaned up by failing
the associaed transaction.
Index: loncom/loncnew
diff -u loncom/loncnew:1.41 loncom/loncnew:1.42
--- loncom/loncnew:1.41 Mon Feb 9 08:39:28 2004
+++ loncom/loncnew Tue Feb 17 04:43:21 2004
@@ -2,7 +2,7 @@
# The LearningOnline Network with CAPA
# lonc maintains the connections to remote computers
#
-# $Id: loncnew,v 1.41 2004/02/09 13:39:28 albertel Exp $
+# $Id: loncnew,v 1.42 2004/02/17 09:43:21 foxr Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -262,9 +262,16 @@
Log("WARNING", "A socket timeout was detected");
Debug(0, " SocketTimeout called: ");
$Socket->Dump();
+ if(exists($ActiveTransactions{$Socket})) {
+ FailTransaction($ActiveTransactions{$Socket});
+ }
KillSocket($Socket); # A transaction timeout also counts as
# a connection failure:
$ConnectionRetriesLeft--;
+ if($ConnectionRetriesLeft <= 0) {
+ Log("CRITICAL", "Host marked dead: ".GetServerHost());
+ }
+
}
#----------------------------- Timer management ------------------------
@@ -326,11 +333,13 @@
if($successCount == 0) { # All connections failed:
Debug(5,"Work in queue failed to make any connectiouns\n");
EmptyQueue(); # Fail pending transactions with con_lost.
+ CloseAllLondConnections(); # Should all be closed but....
}
} else {
ShowStatus(GetServerHost()." >>> DEAD!!! <<<");
Debug(5,"Work in queue, but gave up on connections..flushing\n");
EmptyQueue(); # Connections can't be established.
+ CloseAllLondConnections(); # Should all already be closed but...
}
}
@@ -521,7 +530,9 @@
unlink $Transaction->getFile();
}
}
+
=pod
+
=head1 StartClientReply
Initiates a reply to a client where the reply data is a parameter.
@@ -537,6 +548,7 @@
The data to send to apached client.
=cut
+
sub StartClientReply {
my $Transaction = shift;
my $data = shift;
@@ -554,7 +566,9 @@
cb => \&ClientWritable,
data => $data);
}
+
=pod
+
=head2 FailTransaction
Finishes a transaction with failure because the associated lond socket
@@ -564,8 +578,7 @@
- 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.
+Deleting the transaction means killing it from the %ActiveTransactions hash.
Parameters:
@@ -573,6 +586,7 @@
The LondTransaction we are failing.
+
=cut
sub FailTransaction {
@@ -584,9 +598,6 @@
Debug(1," Replying con_lost to ".$transaction->getRequest());
StartClientReply($transaction, "con_lost\n");
}
- if($ConnectionRetriesLeft <= 0) {
- Log("CRITICAL", "Host marked dead: ".GetServerHost());
- }
}
@@ -614,7 +625,10 @@
=cut
sub CloseAllLondConnections {
foreach my $Socket (keys %ActiveConnections) {
- KillSocket($Socket);
+ if(exists($ActiveTransactions{$Socket})) {
+ FailTransaction($ActiveTransactions{$Socket});
+ }
+ KillSocket($Socket);
}
}
=cut
@@ -666,6 +680,7 @@
#
if($ConnectionCount == 0) {
EmptyQueue();
+ CloseAllLondConnections; # Should all already be closed but...
}
}
@@ -932,21 +947,36 @@
SocketDump(6,$Socket);
+ # If the socket is writable, we must always write.
+ # Only by writing will we undergo state transitions.
+ # Old logic wrote in state specific code below, however
+ # That forces us at least through another invocation of
+ # this function after writability is possible again.
+ # This logic also factors out common code for handling
+ # write failures... in all cases, write failures
+ # Kill the socket.
+ # This logic makes the branches of the >big< if below
+ # so that the writing states are actually NO-OPs.
+
+ if ($Socket->Writable() != 0) {
+ # The write resulted in an error.
+ # We'll treat this as if the socket got disconnected:
+ Log("WARNING", "Connection to ".$RemoteHost.
+ " has been disconnected");
+ if(exists($ActiveTransactions{$Socket})) {
+ FailTransaction($ActiveTransactions{$Socket});
+ }
+ $Watcher->cancel();
+ KillSocket($Socket);
+ return;
+ }
+
+
+
if ($State eq "Connected") {
- if ($Socket->Writable() != 0) {
- # The write resulted in an error.
- # We'll treat this as if the socket got disconnected:
- Log("WARNING", "Connection to ".$RemoteHost.
- " has been disconnected");
- FailTransaction($ActiveTransactions{$Socket});
- $Watcher->cancel();
- KillSocket($Socket);
- return;
- }
-
# "init" is being sent...
-
+
} elsif ($State eq "Initialized") {
# Now that init was sent, we switch
@@ -960,13 +990,6 @@
# are echoing it back. This is a no-op,
# we're waiting for the state to change
- if($Socket->Writable() != 0) {
-
- $Watcher->cancel();
- KillSocket($Socket);
- return;
- }
-
} elsif ($State eq "ChallengeReplied") {
# The echo was sent back, so we switch
# to watching readability.
@@ -975,12 +998,7 @@
$Watcher->poll("r");
} elsif ($State eq "RequestingVersion") {
# Sending the peer a version request...
-
- if($Socket->Writable() != 0) {
- $Watcher->cancel();
- KillSocket($Socket);
- return;
- }
+
} elsif ($State eq "ReadingVersionString") {
# Transition to read since we have sent the
# version command and now just need to read the
@@ -991,12 +1009,7 @@
} elsif ($State eq "SetHost") {
# Setting the remote domain...
-
- if($Socket->Writable() != 0) {
- $Watcher->cancel();
- KillSocket($Socket);
- return;
- }
+
} elsif ($State eq "HostSet") {
# Back to readable to get the ok.
@@ -1007,17 +1020,7 @@
} elsif ($State eq "RequestingKey") {
# At this time we're requesting the key.
# again, this is essentially a no-op.
- # we'll write the next chunk until the
- # state changes.
-
- if($Socket->Writable() != 0) {
- # Write resulted in an error.
- $Watcher->cancel();
- KillSocket($Socket);
- return;
-
- }
} elsif ($State eq "ReceivingKey") {
# Now we need to wait for the key
# to come back from the peer:
@@ -1030,17 +1033,6 @@
# At this time we are sending a request to the
# peer... write the next chunk:
- if($Socket->Writable() != 0) {
-
- if(exists($ActiveTransactions{$Socket})) {
- Debug(3, "Lond connection lost, failing transactions");
- FailTransaction($ActiveTransactions{$Socket});
- }
- $Watcher->cancel();
- KillSocket($Socket);
- return;
-
- }
} elsif ($State eq "ReceivingReply") {
# The send has completed. Wait for the
@@ -1229,10 +1221,12 @@
Debug(5,"Starting additional lond connection");
if(MakeLondConnection() == 0) {
EmptyQueue(); # Fail transactions, can't make connection.
+ CloseAllLondConnections; # Should all be closed but...
}
} else {
ShowStatus(GetServerHost()." >>> DEAD !!!! <<<");
EmptyQueue(); # It's worse than that ... he's dead Jim.
+ CloseAllLondConnections; # Should all be closed but..
}
}
} else { # Can start the request: