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

foxr lon-capa-cvs@mail.lon-capa.org
Tue, 04 Nov 2003 11:52:07 -0000


foxr		Tue Nov  4 06:52:07 2003 EDT

  Modified files:              
    /loncom	lonManage 
  Log:
  re-factored the LondConnection state machine sequencing into a separate
  sub:   SequenceStateMachine
  
  
  
Index: loncom/lonManage
diff -u loncom/lonManage:1.24 loncom/lonManage:1.25
--- loncom/lonManage:1.24	Tue Nov  4 06:36:04 2003
+++ loncom/lonManage	Tue Nov  4 06:52:06 2003
@@ -3,9 +3,9 @@
 #
 #  lonManage supports remote management of nodes in a LonCAPA cluster.
 #
-#  $Id: lonManage,v 1.24 2003/11/04 11:36:04 foxr Exp $
+#  $Id: lonManage,v 1.25 2003/11/04 11:52:06 foxr Exp $
 #
-# $Id: lonManage,v 1.24 2003/11/04 11:36:04 foxr Exp $
+# $Id: lonManage,v 1.25 2003/11/04 11:52:06 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -133,6 +133,62 @@
     return return $Connection;
 }
 #
+#   Process the connection state machine until the connection
+#   becomes idle. This is used both to negotiate the initial
+#   connection, during which the LondConnection sequences a rather 
+#   complex state machine and during the transaction itself
+#   for a simpler set of transitions.
+#   All we really need to be concerned with is whether or not
+#   we're readable or writable and the final state:
+#
+#   Parameter:
+#       connection   - Represents the LondConnection to be sequenced.
+#       timeout      - Maximum time to wait for readable/writable sockets.
+#                      in seconds. < 0 waits forever.
+#   Return:
+#       'ok'         - We got to idle ok.
+#       'error:msg'  - An error occured. msg describes the error.
+#
+sub SequenceStateMachine {
+    my $connection   = shift;
+    my $timeout      = shift;
+
+    my $Socket       = $connection->GetSocket;
+    my $returnstatus = "ok";	              # optimist!!!
+    my $error        = 0;	              # Used to force early loop termination
+                                              # damned perl has no break!!.
+    my $state        = $connection->GetState;
+
+    while(($connection->GetState ne "Idle") && (!$error)) {
+	#
+	# Figure out what the connection wants. read/write and wait for it
+	# or for the timeout.
+	#
+	my $wantread = $connection->WantReadable;
+	my $poll     = new IO::Poll;
+	$poll->mask($Socket, => $wantread ? POLLIN : POLLOUT);
+	$poll->poll($timeout);
+	my $done     = $poll->handles();
+	if(scalar($done) == 0) {            # no handles ready... timeout!!
+	    $returnstatus  = "error:";
+	    $returnstatus .= "Timeout in state $state\n";
+	    $error         = 1;
+	} else {
+	    my $status;
+	    $status        = $wantread ? $connection->Readable :
+		                         $connection->Writable;
+	    if($status != 0) {
+		$returnstatus  =  "error:";
+		$returnstatus .=  " I/O failed in state $state\n";
+		$error = 1;
+	    }
+	}
+	$state = $connection->GetState;
+    }
+    return $returnstatus;
+}
+
+#
 #    This function runs through the section of the connection
 #   state machine that has to do with negotiating the startup 
 #   sequence with lond.  The general strategy is to loop
@@ -163,37 +219,8 @@
 	print "Error: Initial lond connection state: $state should be Connected\n";
 	return "error";
     }
-    my $Socket     = $connection->GetSocket; # This is a IO:Socket::INET object.
 
-    #  Ready now to enter the main loop:
-    #
-    my $error = 0;
-    while (($connection->GetState ne "Idle") && (!$error)) {
-	#
-	#   Wait for the socket to get into the appropriate state:
-	#
-	my $wantread = $connection->WantReadable; 
-	my $poll     = new IO::Poll;
-	$poll->mask($Socket => $wantread ? POLLIN : POLLOUT);
-	$poll->poll($TransitionTimeout);
-	my $done     = $poll->handles();
-	if(scalar($done) == 0) {                       # Timeout!!!
-	    print "Error: Timeout in state : $state negotiating connection\n";
-	    $returnstatus = "error";
-	    $error = 1;
-	} else {
-	    my $status;
-	    $status = $wantread ? $connection->Readable : $connection->Writable;
-	    if ($status != 0) {
-		print "Error: I/O failed in state : $state negotiating connection\n";
-		$returnstatus = "error";
-		$error = 1;
-	    }
-	}
-    }
-
-    
-    return $returnstatus;
+    return SequenceStateMachine($connection, $TransitionTimeout);
 }
 #
 #   Perform a transaction with the remote lond.
@@ -210,43 +237,18 @@
     my $connection  = shift;
     my $command     = shift;
     my $retval;                          # What we'll returnl.
+
    
     #  Set up the connection to do the transaction then
     #  do the I/O until idle or error.
     #
     $connection->InitiateTransaction($command);
-    my $error      = 0;
-    my $Socket    = $connection->GetSocket;
-    my $state;
 
-    while (($connection->GetState ne "Idle") && (!$error)) {
-	#
-	#   Wait for the socket to get into the appropriate state:
-	#
-	my $wantread = $connection->WantReadable; 
-	my $poll     = new IO::Poll;
-	$poll->mask($Socket => $wantread ? POLLIN : POLLOUT);
-	$poll->poll($TransitionTimeout);
-	my $done     = $poll->handles();
-	if(scalar($done) == 0) {                       # Timeout!!!
-	    print "Error: Timeout in state : $state negotiating connection\n";
-	    $retval = "error";
-	    $error = 1;
-	} else {
-	    my $status;
-	    $status = $wantread ? $connection->Readable : $connection->Writable;
-	    if ($status != 0) {
-		print "Error: I/O failed in state : $state negotiating connection\n";
-		$retval = "error";
-		$error = 1;
-	    }
-	}
-    }
-    #
-    #  Fetch the reply from the transaction
-    #
-    if(! $error) {
+    my $status = SequenceStateMachine($connection, $TransitionTimeout);
+    if($status eq "ok") {
 	$retval = $connection->GetReply;
+    } else {
+	$retval = $status;
     }
 
     return $retval;
@@ -273,7 +275,6 @@
     if($reply ne "ok") {
 	return "connection negotiation failed";
     }
-    print "Connection negotiated\n";
     my $reply =  PerformTransaction($connection, $cmd);
     return $reply;