--- loncom/lonnet/perl/lonnet.pm 2004/09/09 08:26:46 1.540 +++ loncom/lonnet/perl/lonnet.pm 2004/09/27 19:00:16 1.548 @@ -1,7 +1,7 @@ # The LearningOnline Network # TCP networking package # -# $Id: lonnet.pm,v 1.540 2004/09/09 08:26:46 albertel Exp $ +# $Id: lonnet.pm,v 1.548 2004/09/27 19:00:16 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -795,11 +795,11 @@ sub getsection { if ($key eq $courseid.'_st') { $section=''; } my ($dummy,$end,$start)=split(/\_/,&unescape($value)); my $now=time; - if (defined($end) && ($now > $end)) { + if (defined($end) && $end && ($now > $end)) { $Expired{$end}=$section; next; } - if (defined($start) && ($now < $start)) { + if (defined($start) && $start && ($now < $start)) { $Pending{$start}=$section; next; } @@ -821,15 +821,17 @@ sub getsection { } -my $disk_caching_disabled=1; +my $disk_caching_disabled=0; sub devalidate_cache { my ($cache,$id,$name) = @_; delete $$cache{$id.'.time'}; + delete $$cache{$id.'.file'}; delete $$cache{$id}; - if ($disk_caching_disabled) { return; } + if (1 || $disk_caching_disabled) { return; } my $filename=$perlvar{'lonDaemons'}.'/tmp/lonnet_internal_cache_'.$name.".db"; - open(DB,"$filename.lock"); + if (!-e $filename) { return; } + open(DB,">$filename.lock"); flock(DB,LOCK_EX); my %hash; if (tie(%hash,'GDBM_File',$filename,&GDBM_WRCREAT(),0640)) { @@ -856,16 +858,32 @@ sub is_cached { my ($cache,$id,$name,$time) = @_; if (!$time) { $time=300; } if (!exists($$cache{$id.'.time'})) { - &load_cache_item($cache,$name,$id); + &load_cache_item($cache,$name,$id,$time); } if (!exists($$cache{$id.'.time'})) { # &logthis("Didn't find $id"); return (undef,undef); } else { if (time-($$cache{$id.'.time'})>$time) { -# &logthis("Devalidating $id - ".time-($$cache{$id.'.time'})); - &devalidate_cache($cache,$id,$name); - return (undef,undef); + if (exists($$cache{$id.'.file'})) { + foreach my $filename (@{ $$cache{$id.'.file'} }) { + my $mtime=(stat($filename))[9]; + #+1 is to take care of edge effects + if ($mtime && (($mtime+1) < ($$cache{$id.'.time'}))) { +# &logthis("Upping $mtime - ".$$cache{$id.'.time'}. +# "$id because of $filename"); + } else { + &logthis("Devalidating $filename $id - ".(time-($$cache{$id.'.time'}))); + &devalidate_cache($cache,$id,$name); + return (undef,undef); + } + } + $$cache{$id.'.time'}=time; + } else { +# &logthis("Devalidating $id - ".time-($$cache{$id.'.time'})); + &devalidate_cache($cache,$id,$name); + return (undef,undef); + } } } return ($$cache{$id},1); @@ -881,44 +899,69 @@ sub do_cache { $$cache{$id}; } +my %do_save_item; +my %do_save; sub save_cache_item { my ($cache,$name,$id)=@_; if ($disk_caching_disabled) { return; } - my $starttime=&Time::HiRes::time(); -# &logthis("Saving :$name:$id"); - my %hash; - my $filename=$perlvar{'lonDaemons'}.'/tmp/lonnet_internal_cache_'.$name.".db"; - open(DB,"$filename.lock"); - flock(DB,LOCK_EX); - if (tie(%hash,'GDBM_File',$filename,&GDBM_WRCREAT(),0640)) { - eval <<'EVALBLOCK'; - $hash{$id.'.time'}=$$cache{$id.'.time'}; - $hash{$id}=freeze({'item'=>$$cache{$id}}); + $do_save{$name}=$cache; + if (!exists($do_save_item{$name})) { $do_save_item{$name}={} } + $do_save_item{$name}->{$id}=1; + return; +} + +sub save_cache { + if ($disk_caching_disabled) { return; } + my ($cache,$name,$id); + foreach $name (keys(%do_save)) { + $cache=$do_save{$name}; + + my $starttime=&Time::HiRes::time(); + &logthis("Saving :$name:"); + my %hash; + my $filename=$perlvar{'lonDaemons'}.'/tmp/lonnet_internal_cache_'.$name.".db"; + open(DB,">$filename.lock"); + flock(DB,LOCK_EX); + if (tie(%hash,'GDBM_File',$filename,&GDBM_WRCREAT(),0640)) { + foreach $id (keys(%{ $do_save_item{$name} })) { + eval <<'EVALBLOCK'; + $hash{$id.'.time'}=$$cache{$id.'.time'}; + $hash{$id}=freeze({'item'=>$$cache{$id}}); + if (exists($$cache{$id.'.file'})) { + $hash{$id.'.file'}=freeze({'item'=>$$cache{$id.'.file'}}); + } EVALBLOCK - if ($@) { - &logthis("save_cache blew up :$@:$name"); - unlink($filename); - } - } else { - if (-e $filename) { - &logthis("Unable to tie hash (save cache item): $name ($!)"); - unlink($filename); + if ($@) { + &logthis("save_cache blew up :$@:$name"); + unlink($filename); + last; + } + } + } else { + if (-e $filename) { + &logthis("Unable to tie hash (save cache): $name ($!)"); + unlink($filename); + } } + untie(%hash); + flock(DB,LOCK_UN); + close(DB); + &logthis("save_cache $name took ".(&Time::HiRes::time()-$starttime)); } - untie(%hash); - flock(DB,LOCK_UN); - close(DB); -# &logthis("save_cache_item $name took ".(&Time::HiRes::time()-$starttime)); + undef(%do_save); + undef(%do_save_item); + } sub load_cache_item { - my ($cache,$name,$id)=@_; + my ($cache,$name,$id,$time)=@_; if ($disk_caching_disabled) { return; } my $starttime=&Time::HiRes::time(); # &logthis("Before Loading $name for $id size is ".scalar(%$cache)); my %hash; my $filename=$perlvar{'lonDaemons'}.'/tmp/lonnet_internal_cache_'.$name.".db"; - open(DB,"$filename.lock"); + if (!-e $filename) { return; } + open(DB,">$filename.lock"); flock(DB,LOCK_SH); if (tie(%hash,'GDBM_File',$filename,&GDBM_READER(),0640)) { eval <<'EVALBLOCK'; @@ -935,9 +978,17 @@ sub load_cache_item { } # &logthis("Initial load: $count"); } else { - my $hashref=thaw($hash{$id}); - $$cache{$id}=$hashref->{'item'}; - $$cache{$id.'.time'}=$hash{$id.'.time'}; + if (($$cache{$id.'.time'}+$time) < time) { + $$cache{$id.'.time'}=$hash{$id.'.time'}; + { + my $hashref=thaw($hash{$id}); + $$cache{$id}=$hashref->{'item'}; + } + if (exists($hash{$id.'.file'})) { + my $hashref=thaw($hash{$id.'.file'}); + $$cache{$id.'.file'}=$hashref->{'item'}; + } + } } EVALBLOCK if ($@) { @@ -2723,7 +2774,9 @@ sub allowed { $uri=&deversion($uri); my $orguri=$uri; $uri=&declutter($uri); - + + + if (defined($ENV{'allowed.'.$priv})) { return $ENV{'allowed.'.$priv}; } # Free bre access to adm and meta resources if (((($uri=~/^adm\//) && ($uri !~ m|/bulletinboard$|)) @@ -2731,6 +2784,13 @@ sub allowed { return 'F'; } +# Free bre access to user's own portfolio contents + my ($space,$domain,$name,$dir)=split('/',$uri); + if (('uploaded' eq $space) && ($ENV{'user.name'} eq $name) && + ($ENV{'user.domain'} eq $domain) && ('portfolio' eq $dir)) { + return 'F'; + } + # Free bre to public access if ($priv eq 'bre') { @@ -3132,8 +3192,10 @@ sub log_query { sub fetch_enrollment_query { my ($context,$affiliatesref,$replyref,$dom,$cnum) = @_; my $homeserver; + my $maxtries = 1; if ($context eq 'automated') { $homeserver = $perlvar{'lonHostID'}; + $maxtries = 10; # will wait for up to 2000s for retrieval of classlist data before timeout } else { $homeserver = &homeserver($cnum,$dom); } @@ -3151,8 +3213,13 @@ sub fetch_enrollment_query { return 'error: '.$queryid; } my $reply = &get_query_reply($queryid); + my $tries = 1; + while (($reply=~/^timeout/) && ($tries < $maxtries)) { + $reply = &get_query_reply($queryid); + $tries ++; + } if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { - &logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$ENV{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum); + &logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$ENV{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries); } else { my @responses = split/:/,$reply; if ($homeserver eq $perlvar{'lonHostID'}) { @@ -4237,7 +4304,9 @@ sub metadata { unless ($filename=~/\.meta$/) { $filename.='.meta'; } my $metastring; if ($uri !~ m|^uploaded/|) { - $metastring=&getfile(&filelocation('',&clutter($filename))); + my $file=&filelocation('',&clutter($filename)); + push(@{$metacache{$uri.'.file'}},$file); + $metastring=&getfile($file); } my $parser=HTML::LCParser->new(\$metastring); my $token; @@ -4602,22 +4671,19 @@ sub deversion { sub symbread { my ($thisfn,$donotrecurse)=@_; - if (defined($ENV{'request.symbread.cached'})) { - return $ENV{'request.symbread.cached'}; - } + my $cache_str='request.symbread.cached.'.$thisfn; + if (defined($ENV{$cache_str})) { return $ENV{$cache_str}; } # no filename provided? try from environment unless ($thisfn) { if ($ENV{'request.symb'}) { - $ENV{'request.symbread.cached'}=&symbclean($ENV{'request.symb'}); - return $ENV{'request.symbread.cached'}; + return $ENV{$cache_str}=&symbclean($ENV{'request.symb'}); } $thisfn=$ENV{'request.filename'}; } # is that filename actually a symb? Verify, clean, and return if ($thisfn=~/\_\_\_\d+\_\_\_(.*)$/) { if (&symbverify($thisfn,$1)) { - $ENV{'request.symbread.cached'}=&symbclean($thisfn); - return $ENV{'request.symbread.cached'}; + return $ENV{$cache_str}=&symbclean($thisfn); } } $thisfn=declutter($thisfn); @@ -4639,8 +4705,7 @@ sub symbread { unless ($syval=~/\_\d+$/) { unless ($ENV{'form.request.prefix'}=~/\.(\d+)\_$/) { &appenv('request.ambiguous' => $thisfn); - $ENV{'request.symbread.cached'}=''; - return ''; + return $ENV{$cache_str}=''; } $syval.=$1; } @@ -4687,13 +4752,11 @@ sub symbread { } } if ($syval) { - $ENV{'request.symbread.cached'}=&symbclean($syval.'___'.$thisfn); - return $ENV{'request.symbread.cached'}; + return $ENV{$cache_str}=&symbclean($syval.'___'.$thisfn); } } &appenv('request.ambiguous' => $thisfn); - $ENV{'request.symbread.cached'}=''; - return ''; + return $ENV{$cache_str}=''; } # ---------------------------------------------------------- Return random seed