--- loncom/lonnet/perl/lonnet.pm	2011/07/18 10:32:48	1.1119
+++ loncom/lonnet/perl/lonnet.pm	2011/08/01 22:13:49	1.1123
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1119 2011/07/18 10:32:48 foxr Exp $
+# $Id: lonnet.pm,v 1.1123 2011/08/01 22:13:49 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -306,6 +306,44 @@ sub get_server_homeID {
     return &do_cache_new('serverhomeID',$hostname,$serverhomeID,$cachetime);
 }
 
+sub get_remote_globals {
+    my ($lonhost,$whathash,$ignore_cache) = @_;
+    my (%returnhash,%whatneeded);
+    if (ref($whathash) eq 'ARRAY') {
+        foreach my $what (sort(keys(%{$whathash}))) {
+            my $type = $whathash->{$what};
+            my $hashid = $lonhost.'-'.$what;
+            my ($result,$cached); 
+            unless ($ignore_cache) {
+                ($result,$cached)=&is_cached_new('lonnetglobal',$hashid);
+                $returnhash{$what} = $result;
+            }
+            if (defined($cached)) {
+                $returnhash{$what} = $result;
+            } else {
+                $whatneeded{$what} = $type;
+            }
+        }
+        if (keys(%whatneeded) > 0) {
+            my $requested = &freeze_escape(\%whatneeded);
+            my $rep=&reply('readlonnetglobal:'.$requested,$lonhost);
+            unless (($rep=~/^refused/) || ($rep=~/^rejected/) || ($rep eq 'con_lost')) {
+                my @pairs=split(/\&/,$rep);
+                if ($rep !~ /^error/) {
+                    foreach my $item (@pairs) {
+                        my ($key,$value)=split(/=/,$item,2);
+                        my $what = &unescape($key);
+                        my $hashid = $lonhost.'-'.$what;
+                        $returnhash{$what}=&thaw_unescape($value);
+                        &do_cache_new('lonnetglobal',$hashid,$returnhash{$what},600);
+                    }
+                }
+            }
+        }
+    }
+    return %returnhash;
+}
+
 # -------------------------------------------------- Non-critical communication
 sub subreply {
     my ($cmd,$server)=@_;
@@ -773,26 +811,33 @@ sub spareserver {
         my %udomdefaults = &Apache::lonnet::get_domain_defaults($udom);
         $remotesessions = $udomdefaults{'remotesessions'};
     }
-    foreach my $try_server (@{ $spareid{'primary'} }) {
-        if ($uint_dom) {
-             next unless (&spare_can_host($udom,$uint_dom,$remotesessions,
-                                          $try_server));
+    my $spareshash = &this_host_spares($udom);
+    if (ref($spareshash) eq 'HASH') {
+        if (ref($spareshash->{'primary'}) eq 'ARRAY') {
+            foreach my $try_server (@{ $spareshash->{'primary'} }) {
+                if ($uint_dom) {
+                    next unless (&spare_can_host($udom,$uint_dom,$remotesessions,
+                                                 $try_server));
+                }
+	        ($spare_server, $lowest_load) =
+	            &compare_server_load($try_server, $spare_server, $lowest_load);
+            }
         }
-	($spare_server, $lowest_load) =
-	    &compare_server_load($try_server, $spare_server, $lowest_load);
-    }
 
-    my $found_server = ($spare_server ne '' && $lowest_load < 100);
+        my $found_server = ($spare_server ne '' && $lowest_load < 100);
 
-    if (!$found_server) {
-	foreach my $try_server (@{ $spareid{'default'} }) {
-            if ($uint_dom) {
-                next unless (&spare_can_host($udom,$uint_dom,$remotesessions,
-                                             $try_server));
-            }
-	    ($spare_server, $lowest_load) =
-		&compare_server_load($try_server, $spare_server, $lowest_load);
-	}
+        if (!$found_server) {
+            if (ref($spareshash->{'default'}) eq 'ARRAY') { 
+	        foreach my $try_server (@{ $spareshash->{'default'} }) {
+                    if ($uint_dom) {
+                        next unless (&spare_can_host($udom,$uint_dom,
+                                                     $remotesessions,$try_server));
+                    }
+	            ($spare_server, $lowest_load) =
+		        &compare_server_load($try_server, $spare_server, $lowest_load);
+                }
+	    }
+        }
     }
 
     if (!$want_server_name) {
@@ -843,9 +888,18 @@ sub compare_server_load {
 # --------------------------- ask offload servers if user already has a session
 sub find_existing_session {
     my ($udom,$uname) = @_;
-    foreach my $try_server (@{ $spareid{'primary'} },
-			    @{ $spareid{'default'} }) {
-	return $try_server if (&has_user_session($try_server, $udom, $uname));
+    my $spareshash = &this_host_spares($udom);
+    if (ref($spareshash) eq 'HASH') {
+        if (ref($spareshash->{'primary'}) eq 'ARRAY') {
+            foreach my $try_server (@{ $spareshash->{'primary'} }) {
+                return $try_server if (&has_user_session($try_server, $udom, $uname));
+            }
+        }
+        if (ref($spareshash->{'default'}) eq 'ARRAY') {
+            foreach my $try_server (@{ $spareshash->{'default'} }) {
+                return $try_server if (&has_user_session($try_server, $udom, $uname));
+            }
+        }
     }
     return;
 }
@@ -1035,15 +1089,19 @@ sub can_host_session {
     }
     if ($canhost) {
         if (ref($hostedsessions) eq 'HASH') {
+            my $uprimary_id = &Apache::lonnet::domain($udom,'primary');
+            my $uint_dom = &Apache::lonnet::internet_dom($uprimary_id);
             if (ref($hostedsessions->{'excludedomain'}) eq 'ARRAY') {
-                if (grep(/^\Q$udom\E$/,@{$hostedsessions->{'excludedomain'}})) {
+                if (($uint_dom ne '') && 
+                    (grep(/^\Q$uint_dom\E$/,@{$hostedsessions->{'excludedomain'}}))) {
                     $canhost = 0;
                 } else {
                     $canhost = 1;
                 }
             }
             if (ref($hostedsessions->{'includedomain'}) eq 'ARRAY') {
-                if (grep(/^\Q$udom\E$/,@{$hostedsessions->{'includedomain'}})) {
+                if (($uint_dom ne '') && 
+                    (grep(/^\Q$uint_dom\E$/,@{$hostedsessions->{'includedomain'}}))) {
                     $canhost = 1;
                 } else {
                     $canhost = 0;
@@ -1074,6 +1132,47 @@ sub spare_can_host {
     return $canhost;
 }
 
+sub this_host_spares {
+    my ($dom) = @_;
+    my $cachetime = 60*60*24;
+    my @hosts = &current_machine_ids();
+    foreach my $lonhost (@hosts) {
+        if (&host_domain($lonhost) eq $dom) {
+            my ($result,$cached)=&is_cached_new('spares',$dom);
+            if (defined($cached)) {
+                return $result;
+            } else {
+                my %domconfig =
+                    &Apache::lonnet::get_dom('configuration',['usersessions'],$dom);
+                if (ref($domconfig{'usersessions'}) eq 'HASH') {
+                    if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') {
+                        if (ref($domconfig{'usersessions'}{'spares'}{$lonhost}) eq 'HASH') {
+                            return &do_cache_new('spares',$dom,$domconfig{'usersessions'}{'spares'}{$lonhost},$cachetime);
+                        }
+                    }
+                }
+            }
+            last;
+        }
+    }
+    my $serverhomedom = &host_domain($perlvar{'lonHostID'});
+    my ($result,$cached)=&is_cached_new('spares',$serverhomedom);
+    if (defined($cached)) {
+        return $result;
+    } else {
+        my %homedomconfig =
+            &Apache::lonnet::get_dom('configuration',['usersessions'],$serverhomedom);
+        if (ref($homedomconfig{'usersessions'}) eq 'HASH') {
+            if (ref($homedomconfig{'usersessions'}{'spares'}) eq 'HASH') {
+                if (ref($homedomconfig{'usersessions'}{'spares'}{$perlvar{'lonHostID'}}) eq 'HASH') {
+                    return &do_cache_new('spares',$serverhomedom,$homedomconfig{'usersessions'}{'spares'}{$perlvar{'lonHostID'}},$cachetime);
+                }
+            }
+        }
+    }
+    return \%spareid;
+}
+
 # ---------------------- Find the homebase for a user from domain's lib servers
 
 my %homecache;