[LON-CAPA-cvs] cvs: loncom / loncnew
foxr
lon-capa-cvs@mail.lon-capa.org
Mon, 05 May 2003 23:40:27 -0000
This is a MIME encoded message
--foxr1052178027
Content-Type: text/plain
foxr Mon May 5 19:40:27 2003 EDT
Modified files:
/loncom loncnew
Log:
>>>>UNTESTED<<<<<
Add beginnings of code for delayed transactions...
Add code to fork off into separate session...
>>>>UNTESTED<<<<
Comitting prior to ripping guts out to re-cast the transaction as an object
so that state/history/etc. can be more easily carried with it (need to do that
to know when to retire a delayed transaction).
--foxr1052178027
Content-Type: text/plain
Content-Disposition: attachment; filename="foxr-20030505194027.txt"
Index: loncom/loncnew
diff -u loncom/loncnew:1.5 loncom/loncnew:1.6
--- loncom/loncnew:1.5 Mon Apr 28 23:24:51 2003
+++ loncom/loncnew Mon May 5 19:40:27 2003
@@ -2,7 +2,7 @@
# The LearningOnline Network with CAPA
# lonc maintains the connections to remote computers
#
-# $Id: loncnew,v 1.5 2003/04/29 03:24:51 foxr Exp $
+# $Id: loncnew,v 1.6 2003/05/05 23:40:27 foxr Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -49,6 +49,7 @@
use IO::Socket;
use IO::Socket::INET;
use IO::Socket::UNIX;
+use IO::Handle;
use Socket;
use Crypt::IDEA;
use LONCAPA::Queue;
@@ -103,6 +104,12 @@
my $IdleSeconds = 0; # Number of seconds idle.
#
+# This disconnected socket makes posible a bit more regular
+# code when processing delayed requests:
+#
+my $NullSocket = IO::Socket->new();
+
+#
=pod
@@ -190,7 +197,7 @@
$IdleSeconds++;
if($IdleSeconds > $IdleTimeout) { # Prune a connection...
$Socket = $IdleConnections->pop();
- KillSocket($Socket, 0);
+ KillSocket($Socket);
}
} else {
$IdleSeconds = 0; # Reset idle count if not idle.
@@ -302,51 +309,55 @@
&Debug(6, "ClientWritable writing".$Data);
&Debug(9, "Socket is: ".$Socket);
- my $result = $Socket->send($Data, 0);
-
- # $result undefined: the write failed.
- # otherwise $result is the number of bytes written.
- # Remove that preceding string from the data.
- # If the resulting data is empty, destroy the watcher
- # and set up a read event handler to accept the next
- # request.
-
- &Debug(9,"Send result is ".$result." Defined: ".defined($result));
- if(defined($result)) {
- &Debug(9, "send result was defined");
- if($result == length($Data)) { # Entire string sent.
- &Debug(9, "ClientWritable data all written");
- $Watcher->cancel();
- #
- # Set up to read next request from socket:
-
- my $descr = sprintf("Connection to lonc client %d",
- $ActiveClients{$Socket});
- Event->io(cb => \&ClientRequest,
- poll => 'r',
- desc => $descr,
- data => "",
- fd => $Socket);
-
- } else { # Partial string sent.
- $Watcher->data(substr($Data, $result));
- }
+ if($Socket->connected) {
+ my $result = $Socket->send($Data, 0);
- } else { # Error of some sort...
-
- # Some errnos are possible:
- my $errno = $!;
- if($errno == POSIX::EWOULDBLOCK ||
- $errno == POSIX::EAGAIN ||
- $errno == POSIX::EINTR) {
- # No action taken?
- } else { # Unanticipated errno.
- &Debug(5,"ClientWritable error or peer shutdown".$RemoteHost);
- $Watcher->cancel; # Stop the watcher.
- $Socket->shutdown(2); # Kill connection
- $Socket->close(); # Close the socket.
- }
+ # $result undefined: the write failed.
+ # otherwise $result is the number of bytes written.
+ # Remove that preceding string from the data.
+ # If the resulting data is empty, destroy the watcher
+ # and set up a read event handler to accept the next
+ # request.
+ &Debug(9,"Send result is ".$result." Defined: ".defined($result));
+ if(defined($result)) {
+ &Debug(9, "send result was defined");
+ if($result == length($Data)) { # Entire string sent.
+ &Debug(9, "ClientWritable data all written");
+ $Watcher->cancel();
+ #
+ # Set up to read next request from socket:
+
+ my $descr = sprintf("Connection to lonc client %d",
+ $ActiveClients{$Socket});
+ Event->io(cb => \&ClientRequest,
+ poll => 'r',
+ desc => $descr,
+ data => "",
+ fd => $Socket);
+
+ } else { # Partial string sent.
+ $Watcher->data(substr($Data, $result));
+ }
+
+ } else { # Error of some sort...
+
+ # Some errnos are possible:
+ my $errno = $!;
+ if($errno == POSIX::EWOULDBLOCK ||
+ $errno == POSIX::EAGAIN ||
+ $errno == POSIX::EINTR) {
+ # No action taken?
+ } else { # Unanticipated errno.
+ &Debug(5,"ClientWritable error or peer shutdown".$RemoteHost);
+ $Watcher->cancel; # Stop the watcher.
+ $Socket->shutdown(2); # Kill connection
+ $Socket->close(); # Close the socket.
+ }
+
+ }
+ } else {
+ $Watcher->cancel(); # A delayed request...just cancel.
}
}
@@ -379,10 +390,22 @@
my $Client = shift;
my $data = $Socket->GetReply(); # Data to send.
+ StartClientReply($Client, $data);
+}
+=pod
+=head1 StartClientReply
+
+ Initiates a reply to a client where the reply data is a parameter.
+
+=cut
+sub StartClientReply {
+ my $Client = shift;
+ my $data = shift;
&Debug(8," Reply was: ".$data);
my $Serial = $ActiveClients{$Client};
my $desc = sprintf("Connection to lonc client %d",
+
$Serial);
Event->io(fd => $Client,
poll => "w",
@@ -407,20 +430,23 @@
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);
+ StartClientReply($client, "con_lost");
}
=pod
+=head1 EmptyQueue
+ Fails all items in the work queue with con_lost.
+=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);
+ }
+}
+
+=pod
=head2 KillSocket
@@ -444,7 +470,6 @@
=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:
@@ -456,10 +481,13 @@
delete($ActiveConnections{$Socket});
}
$ConnectionCount--;
- if( ($ConnectionCount = 0) && ($Restart)) {
- MakeLondConnection();
- }
+ # If the connection count has gone to zero and there is work in the
+ # work queue, the work all gets failed with con_lost.
+ #
+ if($ConnectionCount == 0) {
+ EmptyQueue;
+ }
}
=pod
@@ -541,7 +569,7 @@
FailTransaction($ActiveTransactions{$Socket});
}
$Watcher->cancel();
- KillSocket($Socket, 1);
+ KillSocket($Socket);
return;
}
SocketDump(6,$Socket);
@@ -582,7 +610,7 @@
}
$Watcher->cancel();
ServerToIdle($Socket); # Next work unit or idle.
-
+
} elsif ($State eq "SendingRequest") {
# We need to be writable for this and probably don't belong
# here inthe first place.
@@ -684,7 +712,7 @@
# We'll treat this as if the socket got disconnected:
$Watcher->cancel();
- KillSocket($Socket, 1);
+ KillSocket($Socket);
return;
}
# "init" is being sent...
@@ -706,7 +734,7 @@
if($Socket->Writable() != 0) {
$Watcher->cancel();
- KillSocket($Socket, 1);
+ KillSocket($Socket);
return;
}
@@ -727,7 +755,7 @@
# Write resulted in an error.
$Watcher->cancel();
- KillSocket($Socket, 1);
+ KillSocket($Socket);
return;
}
@@ -749,7 +777,7 @@
FailTransaction($ActiveTransactions{$Socket});
}
$Watcher->cancel();
- KillSocket($Socket, 1);
+ KillSocket($Socket);
return;
}
@@ -771,6 +799,25 @@
}
}
+=pod
+
+=cut
+sub QueueDelayed {
+ my $path = "$perlvar{'lonSockDir'}/delayed";
+ opendir(DIRHANDLE, $path);
+ @alldelayed = grep /\.$RemoteHost$/, readdir DIRHANDLE;
+ closedir(DIRHANDLE);
+ my $dfname;
+ my $reqfile
+ foreach $reqfile (sort @alldelayed) {
+ $reqfile = $path/$reqfile;
+ my $Handle = IO::File->new($reqfile);
+ my $cmd = <$Handle>;
+ chomp($cmd);
+ QueueTransaction($NullSocket, $cmd);
+ }
+
+}
=pod
@@ -815,6 +862,9 @@
$ActiveConnections{$Connection} = $event;
$ConnectionCount++;
+ if($ConnectionCount == 1) { # First Connection:
+ QueueDelayed;
+ }
}
}
@@ -1125,11 +1175,25 @@
#
+
+
ShowStatus("Parent writing pid file:");
$execdir = $perlvar{'lonDaemons'};
open (PIDSAVE, ">$execdir/logs/lonc.pid");
print PIDSAVE "$$\n";
close(PIDSAVE);
+
+ShowStatus("Forming new session");
+my $childpid = fork;
+if ($childpid != 0) {
+ sleep 4; # Give child a chacne to break to
+ exit 0; # a new sesion.
+}
+
+if (POSIX::setsid() < 0) {
+ print "Could not create new session\n";
+ exit -1;
+}
ShowStatus("Forking node servers");
--foxr1052178027--