--- loncom/loncnew 2004/09/22 11:11:54 1.60 +++ loncom/loncnew 2004/09/29 10:37:35 1.61 @@ -2,7 +2,7 @@ # The LearningOnline Network with CAPA # lonc maintains the connections to remote computers # -# $Id: loncnew,v 1.60 2004/09/22 11:11:54 foxr Exp $ +# $Id: loncnew,v 1.61 2004/09/29 10:37:35 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1571,6 +1571,9 @@ sub ToggleDebug { =head2 ChildProcess This sub implements a child process for a single lonc daemon. +Optional parameter: + $socket - if provided, this is a socket already open for listen + on the client socket. Otherwise, a new listen is set up. =cut @@ -1579,7 +1582,7 @@ sub ChildProcess { # # Signals must be handled by the Event framework... -# + # Event->signal(signal => "QUIT", cb => \&SignalledToDeath, @@ -1597,7 +1600,11 @@ sub ChildProcess { data => "INT"); - my $socket = SetupLoncListener(); + my ($socket) = @_; + if (!$socket) { + + $socket = SetupLoncListener(); + } Event->io(cb => \&NewClient, poll => 'r', desc => 'Lonc Listener Unix Socket', @@ -1609,7 +1616,7 @@ sub ChildProcess { # Setup the initial server connection: - # &MakeLondConnection(); // let first work requirest do it. + # &MakeLondConnection(); // let first work requirest do it. Debug(9,"Entering event loop"); @@ -1641,8 +1648,89 @@ sub CreateChild { sigprocmask(SIG_UNBLOCK, $sigset); ChildProcess; # Does not return. } +} +# parent_client_connection: +# Event handler that processes client connections for the parent process. +# This sub is called when the parent is listening on a socket and +# a connection request arrives. We must: +# Start a child process to accept the connection request. +# Kill our listen on the socket. +# Setup an event to handle the child process exit. (SIGCHLD). +# Parameter: +# event - The event object that was created to monitor this socket. +# event->w->fd is the socket. +# Returns: +# NONE +# +sub parent_client_connection { + die "DieWhenIdle processing not completely operational yet"; + +} + +# parent_listen: +# Opens a socket and starts a listen for the parent process on a client UNIX +# domain socket. +# +# This involves: +# Creating a socket for listen. +# Removing any socket lock file +# Adding an event handler for this socket becoming readable +# To the parent's event dispatcher. +# Parameters: +# loncapa_host - LonCAPA cluster name of the host represented by the client +# socket. +# Returns: +# NONE +# +sub parent_listen { + my ($loncapa_host) = @_; + Debug(5, "parent_listen: $loncapa_host"); + + my $socket = &SetupLoncListener($loncapa_host); + if (!$socket) { + die "Unable to create a listen socket for $loncapa_host"; + } + + my $lock_file = &GetLoncSocketPath().".lock"; + unlink($lock_file); # No problem if it doesn't exist yet [startup e.g.] + + Event->io(cb => &parent_client_connection, + poll => 'r', + desc => 'Parent listener unix socket', + fd => $socket); + +} + + +# listen_on_all_unix_sockets: +# This sub initiates a listen on all unix domain lonc client sockets. +# This will be called in the case where we are trimming idle processes. +# When idle processes are trimmed, loncnew starts up with no children, +# and only spawns off children when a connection request occurs on the +# client unix socket. The spawned child continues to run until it has +# been idle a while at which point it eventually exits and once more +# the parent picks up the listen. +# +# Parameters: +# NONE +# Implicit Inputs: +# The configuration file that has been read in by LondConnection. +# Returns: +# NONE +# +sub listen_on_all_unix_sockets { + Debug(5, "listen_on_all_unix_sockets"); + my $host_iterator = &LondConnection::GetHostIterator(); + while (!$host_iterator->end()) { + my $host_entry_ref = $host_iterator->get(); + my $host_name = $host_entry_ref->[0]; + Debug(9, "Listen for $host_name"); + &parent_listen($host_name); + $host_iterator->next(); + } } + # # Parent process logic pass 1: # For each entry in the hosts table, we will @@ -1694,8 +1782,8 @@ LondConnection::ReadConfig; my $HostIterator = LondConnection::GetHostIterator; if ($DieWhenIdle) { - print "Die when idle socket monitoring is not yet implemented\n"; - exit(-1); + $RemoteHost = "[parent]"; + &listen_on_all_unix_sockets(); } else { while (! $HostIterator->end()) { @@ -1713,14 +1801,18 @@ $RemoteHost = "Parent Server"; ShowStatus("Parent keeping the flock"); -# -# Set up parent signals: -# if ($DieWhenIdle) { - print "Die when idle main processing not yet implemented"; - exit (-1); + $Event::DebugLevel = $DebugLevel; + Debug(9, "Parent entering event loop"); + my $ret = Event::loop(); + die "Main Event loop exited: $ret"; + + } else { + # + # Set up parent signals: + # $SIG{INT} = \&Terminate; $SIG{TERM} = \&Terminate;