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