--- loncom/loncnew	2003/04/24 10:56:55	1.4
+++ loncom/loncnew	2003/04/29 03:24:51	1.5
@@ -2,7 +2,7 @@
 # The LearningOnline Network with CAPA
 # lonc maintains the connections to remote computers
 #
-# $Id: loncnew,v 1.4 2003/04/24 10:56:55 foxr Exp $
+# $Id: loncnew,v 1.5 2003/04/29 03:24:51 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -155,15 +155,28 @@ sub SocketDump {
 
 =pod
 
+=head2 ShowStatus
+
+ Place some text as our pid status.
+
+=cut
+sub ShowStatus {
+    my $status = shift;
+    $0 =  "lonc: ".$status;
+}
+
+=pod
+
 =head2 Tick
 
 Invoked  each timer tick.
 
 =cut
 
+
 sub Tick {
     my $client;
-    $0 = 'lonc: '.GetServerHost()." Connection count: ".$ConnectionCount;
+    ShowStatus(GetServerHost()." Connection count: ".$ConnectionCount);
     Debug(6, "Tick");
     Debug(6, "    Current connection count: ".$ConnectionCount);
     foreach $client (keys %ActiveClients) {
@@ -182,6 +195,21 @@ sub Tick {
     } else {
 	$IdleSeconds = 0;	# Reset idle count if not idle.
     }
+
+    # Do we have work in the queue, but no connections to service them?
+    # If so, try to make some new connections to get things going again.
+    #
+    
+    my $Requests = $WorkQueue->Count();
+    if (($ConnectionCount == 0)  && ($Requests > 0)) {
+	my $Connections = ($Requests <= $MaxConnectionCount) ?
+	                           $Requests : $MaxConnectionCount;
+	Debug(1,"Work but no connections, starting ".$Connections." of them");
+	for ($i =0; $i < $Connections; $i++) {
+	    MakeLondConnection();
+	}
+       
+    }
 }
 
 =pod
@@ -654,10 +682,7 @@ sub LondWritable {
 	if ($Socket->Writable() != 0) {
 	    #  The write resulted in an error.
 	    # We'll treat this as if the socket got disconnected:
-	    if(exists($ActiveTransactions{$Socket})) {
-		Debug(3, "Lond connection lost, failing transactions");
-		FailTransaction($ActiveTransactions{$Socket});
-	    }
+
 	    $Watcher->cancel();
 	    KillSocket($Socket, 1);
 	    return;
@@ -679,7 +704,10 @@ sub LondWritable {
 	# we're waiting for the state to change
 	
 	if($Socket->Writable() != 0) {
-	    # Write of the next chunk resulted in an error.
+
+	    $Watcher->cancel();
+	    KillSocket($Socket, 1);
+	    return;
 	}
 	
     } elsif ($State eq "ChallengeReplied")  {
@@ -697,8 +725,12 @@ sub LondWritable {
 
 	if($Socket->Writable() != 0) {
 	    # Write resulted in an error.
-	}
 
+	    $Watcher->cancel();
+	    KillSocket($Socket, 1);
+	    return;
+
+	}
     } elsif ($State eq "ReceivingKey")      {
 	# Now we need to wait for the key
 	# to come back from the peer:
@@ -711,8 +743,15 @@ sub LondWritable {
 	# peer... write the next chunk:
 
 	if($Socket->Writable() != 0) {
-	    # Write resulted in an error.
 
+	    if(exists($ActiveTransactions{$Socket})) {
+		Debug(3, "Lond connection lost, failing transactions");
+		FailTransaction($ActiveTransactions{$Socket});
+	    }
+	    $Watcher->cancel();
+	    KillSocket($Socket, 1);
+	    return;
+	    
 	}
 
     } elsif ($State eq "ReceivingReply")    {
@@ -753,31 +792,30 @@ sub MakeLondConnection {
 					 &GetServerPort());
 
     if($Connection == undef) {	# Needs to be more robust later.
-	die "Failed to make a connection!!".$!."\n";
+	Debug(0,"Failed to make a connection with lond.");
+    }  else {
+	# The connection needs to have writability 
+	# monitored in order to send the init sequence
+	# that starts the whole authentication/key
+	# exchange underway.
+	#
+	my $Socket = $Connection->GetSocket();
+	if($Socket == undef) {
+	    die "did not get a socket from the connection";
+	} else {
+	    &Debug(9,"MakeLondConnection got socket: ".$Socket);
+	}
 	
-    } 
-    # The connection needs to have writability 
-    # monitored in order to send the init sequence
-    # that starts the whole authentication/key
-    # exchange underway.
-    #
-    my $Socket = $Connection->GetSocket();
-    if($Socket == undef) {
-	die "did not get a socket from the connection";
-    } else {
-	&Debug(9,"MakeLondConnection got socket: ".$Socket);
+	
+	$event = Event->io(fd       => $Socket,
+			   poll     => 'w',
+			   cb       => \&LondWritable,
+			   data     => ($Connection, undef),
+			   desc => 'Connection to lond server');
+	$ActiveConnections{$Connection} = $event;
+	
+	$ConnectionCount++;
     }
-
-    
-    $event = Event->io(fd       => $Socket,
-		       poll     => 'w',
-		       cb       => \&LondWritable,
-		       data     => ($Connection, undef),
-		       desc => 'Connection to lond server');
-    $ActiveConnections{$Connection} = $event;
-
-    $ConnectionCount++;
-   
     
 }
 
@@ -1043,7 +1081,11 @@ sub ChildProcess {
 # Setup the initial server connection:
     
     &MakeLondConnection();
-    
+
+    if($ConnectionCount == 0) {
+	Debug(1,"Could not make initial connection..\n");
+	Debug(1,"Will retry when there's work to do\n");
+    }
     Debug(9,"Entering event loop");
     my $ret = Event::loop();		#  Start the main event loop.
     
@@ -1062,6 +1104,7 @@ sub CreateChild {
     if($pid) {			# Parent
 	$ChildHash{$pid} = $RemoteHost;
     } else {			# child.
+	ShowStatus("Connected to ".$RemoteHost);
 	ChildProcess;
     }
 
@@ -1076,6 +1119,20 @@ sub CreateChild {
 #  Each exit gets logged and the child gets restarted.
 #
 
+#
+#   Fork and start in new session so hang-up isn't going to 
+#   happen without intent.
+#
+
+
+ShowStatus("Parent writing pid file:");
+$execdir = $perlvar{'lonDaemons'};
+open (PIDSAVE, ">$execdir/logs/lonc.pid");
+print PIDSAVE "$$\n";
+close(PIDSAVE);
+
+ShowStatus("Forking node servers");
+
 my $HostIterator = LondConnection::GetHostIterator;
 while (! $HostIterator->end()) {
 
@@ -1086,6 +1143,8 @@ while (! $HostIterator->end()) {
 
 # Maintain the population:
 
+ShowStatus("Parent keeping the flock");
+
 while(1) {
     $deadchild = wait();
     if(exists $ChildHash{$deadchild}) {	# need to restart.