[open-ils-commits] [GIT] Evergreen ILS branch master updated. 18d51a404ada15f07b94c4cc3d6d678cadcf607b

Evergreen Git git at git.evergreen-ils.org
Wed Jun 10 13:37:06 EDT 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  18d51a404ada15f07b94c4cc3d6d678cadcf607b (commit)
       via  984ea80e7c8b331591a256369faabeea0a6acd89 (commit)
       via  ce4baf43de81892a2761f76ece26eadbeb64f0c5 (commit)
       via  e675997df5e832f9a8612dd929159369922bd1b7 (commit)
       via  23ec5c03102bff5eb09ad67b196d8b4b7373fa94 (commit)
       via  4edf58b71a57769c2ef28cf81a86bc9deeaaf079 (commit)
       via  a42f4e9f3d45a5dbc5eefcd86f0d0ee0ad001660 (commit)
       via  bc55788c14222f5b40db418d5faa841350dd42c5 (commit)
      from  10426dffb768ac9176fa06d7c023cc38c1730f2c (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 18d51a404ada15f07b94c4cc3d6d678cadcf607b
Author: Mike Rylander <mrylander at gmail.com>
Date:   Fri May 22 13:11:18 2015 -0400

    LP#1449709: Always get a real hostname for the cache key
    
    EGCatLoader overwrites $ctx->{hostname} when serving the staff client
    version of TT-generated content.  This is bad for us because we use
    that as part of the TT Processor cache key.  Instead, we'll just
    always ask Apache, via $r.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
index f2f6f40..da18d7e 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
@@ -86,7 +86,7 @@ sub handler_guts {
     my $text_handler = set_text_handler($ctx, $r);
 
     my $processor_key = $as_xml ? 'xml:' : 'text:';                 # separate by XML strictness
-    $processor_key .= $ctx->{hostname}.':';                         # ... and vhost
+    $processor_key .= $r->hostname.':';                         # ... and vhost
     $processor_key .= $r->dir_config('OILSWebContextLoader').':';   # ... and context loader
     $processor_key .= $ctx->{locale};                               # ... and locale
     # NOTE: context loader and vhost together imply template path and debug template values
@@ -297,8 +297,8 @@ sub find_template {
     my $ext = $r->dir_config('OILSWebDefaultTemplateExtension');
     my $at_index = $r->dir_config('OILSWebStopAtIndex');
 
-    $vhost_path_cache{$ctx->{hostname}} ||= {};
-    my $path_cache = $vhost_path_cache{$ctx->{hostname}};
+    $vhost_path_cache{$r->hostname} ||= {};
+    my $path_cache = $vhost_path_cache{$r->hostname};
 
     my @parts = split('/', $path);
     my $localpath = $path;

commit 984ea80e7c8b331591a256369faabeea0a6acd89
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Tue May 5 22:15:39 2015 +0000

    LP#1452366: allow EGWeb context loaders to have child_init actions
    
    This patch adds the ability for EGWeb to call
    an initialization function for context loaders
    during the child_init phase of Apache backend
    startup.
    
    In particular, portions of the R/O object cache
    for EGCatLoader are now initialized when a backend
    starts up; testing indicates that this can shave
    a couple seconds off the time it takes for a
    backend to render a bib details page the first time.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/examples/apache/eg_startup.in b/Open-ILS/examples/apache/eg_startup.in
index 1d77c05..855159e 100755
--- a/Open-ILS/examples/apache/eg_startup.in
+++ b/Open-ILS/examples/apache/eg_startup.in
@@ -10,7 +10,7 @@ use OpenILS::WWW::AddedContent qw( @sysconfdir@/opensrf_core.xml );
 use OpenILS::WWW::Proxy ('@sysconfdir@/opensrf_core.xml');
 use OpenILS::WWW::Vandelay qw( @sysconfdir@/opensrf_core.xml );
 use OpenILS::WWW::TemplateBatchBibUpdate qw( @sysconfdir@/opensrf_core.xml );
-use OpenILS::WWW::EGWeb;
+use OpenILS::WWW::EGWeb ('@sysconfdir@/opensrf_core.xml', 'OpenILS::WWW::EGCatLoader', 'en_us');;
 use OpenILS::WWW::IDL2js ('@sysconfdir@/opensrf_core.xml');
 use OpenILS::WWW::FlatFielder;
 use OpenILS::WWW::PhoneList ('@sysconfdir@/opensrf_core.xml');
diff --git a/Open-ILS/examples/apache_24/eg.conf.in b/Open-ILS/examples/apache_24/eg.conf.in
index b33581d..33f7d03 100644
--- a/Open-ILS/examples/apache_24/eg.conf.in
+++ b/Open-ILS/examples/apache_24/eg.conf.in
@@ -20,6 +20,7 @@ PerlChildInitHandler OpenILS::WWW::SuperCat::child_init
 PerlChildInitHandler OpenILS::WWW::AddedContent::child_init
 PerlChildInitHandler OpenILS::WWW::AutoSuggest::child_init
 PerlChildInitHandler OpenILS::WWW::PhoneList::child_init
+PerlChildInitHandler OpenILS::WWW::EGWeb::child_init
 
 # ----------------------------------------------------------------------------------
 # Set some defaults for our working directories
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
index 43f4a37..69bb898 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
@@ -25,6 +25,31 @@ our %cache = ( # cached data
     authority_fields => {en_us => {}}
 );
 
+sub child_init {
+    my $class = shift;
+    my %locales = @_;
+
+    # create a stub object with just enough in place
+    # to call init_ro_object_cache()
+    my $stub = bless({}, ref($class) || $class);
+    my $ctx = {};
+    $stub->ctx($ctx);
+
+    foreach my $locale (sort keys %locales) {
+        OpenSRF::AppSession->default_locale($locales{$locale});
+        $ctx->{locale} = $locale;
+        $stub->init_ro_object_cache();
+
+        # pre-cache various sets of objects
+        # known to be time-consuming to retrieve
+        # the first go around
+        $ro_object_subs->{$locale}->{aou_tree}();
+        $ro_object_subs->{$locale}->{aouct_tree}();
+        $ro_object_subs->{$locale}->{ccvm_list}();
+        $ro_object_subs->{$locale}->{get_authority_fields}(1);
+    }
+}
+
 sub init_ro_object_cache {
     my $self = shift;
     my $ctx = $self->ctx;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
index 8b3fcbf..f2f6f40 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
@@ -25,6 +25,30 @@ my %vhost_path_cache;
 # cache template processors by vhost
 my %vhost_processor_cache;
 
+my $bootstrap_config;
+my @context_loaders_to_preinit = ();
+my %locales_to_preinit = ();
+
+sub import {
+    my ($self, $bootstrap_config, $loaders, $locales) = @_;
+    @context_loaders_to_preinit = split /\s+/, $loaders, -1 if defined($loaders);
+    %locales_to_preinit = map { $_ => parse_eg_locale($_) }
+                          split /\s+/, $locales, -1 if defined($locales);
+}
+
+sub child_init {
+    OpenSRF::System->bootstrap_client(config_file => $bootstrap_config);
+    my $idl = OpenSRF::Utils::SettingsClient->new->config_value("IDL");
+    Fieldmapper->import(IDL => $idl);
+    foreach my $loader (@context_loaders_to_preinit) {
+        eval {
+            $loader->use;
+            $loader->child_init(%locales_to_preinit);
+        };
+    }
+    return Apache2::Const::OK;
+}
+
 sub handler {
     my $r = shift;
     my $stat = handler_guts($r);

commit ce4baf43de81892a2761f76ece26eadbeb64f0c5
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Wed May 6 18:23:49 2015 +0000

    LP#1452352: use fresh CStore editors when populating R/O cache
    
    This change ensures that there's no longer a cached
    editor with its original session locale grabbing
    the wrong labels when a template invokes ctx.search_foo.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
index 0401d20..43f4a37 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
@@ -27,7 +27,6 @@ our %cache = ( # cached data
 
 sub init_ro_object_cache {
     my $self = shift;
-    my $e = $self->editor;
     my $ctx = $self->ctx;
 
     # reset org unit setting cache on each page load to avoid the
@@ -64,7 +63,9 @@ sub init_ro_object_cache {
         # Retrieve the full set of objects with class $hint
         $locale_subs->{$list_key} = sub {
             my $method = "retrieve_all_$eclass";
+            my $e = new_editor();
             $cache{list}{$locale}{$hint} = $e->$method() unless $cache{list}{$locale}{$hint};
+            undef $e;
             return $cache{list}{$locale}{$hint};
         };
 
@@ -94,8 +95,10 @@ sub init_ro_object_cache {
                 $cacheval .= ':' . $filterfield . ':' . $filterval;
             }
             #$cache{search}{$locale}{$hint}{$field} = {} unless $cache{search}{$locale}{$hint}{$field};
+            my $e = new_editor();
             $cache{search}{$locale}{$hint}{$field}{$cacheval} = $e->$method($search_obj)
                 unless $cache{search}{$locale}{$hint}{$field}{$cacheval};
+            undef $e;
             return $cache{search}{$locale}{$hint}{$field}{$cacheval};
         };
     }
@@ -104,6 +107,7 @@ sub init_ro_object_cache {
 
         # fetch the org unit tree
         unless($cache{aou_tree}{$locale}) {
+            my $e = new_editor();
             my $tree = $e->search_actor_org_unit([
                 {   parent_ou => undef},
                 {   flesh            => -1,
@@ -123,7 +127,7 @@ sub init_ro_object_cache {
                 flesh_aout($_, $locale_subs, $locale) foreach @{$node->children};
             };
             flesh_aout($tree, $locale_subs, $locale);
-
+            undef $e;
             $cache{aou_tree}{$locale} = $tree;
         }
 
@@ -157,6 +161,7 @@ sub init_ro_object_cache {
         unless(exists $cache{aouct_tree}{$locale}) {
             $cache{aouct_tree}{$locale} = undef;
 
+            my $e = new_editor();
             my $tree_id = $e->search_actor_org_unit_custom_tree(
                 {purpose => 'opac', active => 't'},
                 {idlist => 1}
@@ -189,6 +194,7 @@ sub init_ro_object_cache {
                 $cache{aouct_tree}{$locale} = 
                     $node_tree->org_unit if $node_tree;
             }
+            undef $e;
         }
 
         return $cache{aouct_tree}{$locale};
@@ -243,11 +249,18 @@ sub init_ro_object_cache {
         my ($control_set) = @_;
 
         if (not exists $cache{authority_fields}{$locale}{$control_set}) {
-            my $acs = $e->search_authority_control_set_authority_field(
-                {control_set => $control_set}
-            ) or return;
-            $cache{authority_fields}{$locale}{$control_set} =
-                +{ map { $_->id => $_ } @$acs };
+            my $e = new_editor();
+            if (my $acs = $e->search_authority_control_set_authority_field(
+                                    {control_set => $control_set}
+                                )
+            ) {
+                $cache{authority_fields}{$locale}{$control_set} =
+                 +{ map { $_->id => $_ } @$acs };
+                undef $e;
+            } else {
+                undef $e;
+                return;
+            }
         }
 
         return $cache{authority_fields}{$locale}{$control_set};

commit e675997df5e832f9a8612dd929159369922bd1b7
Author: Mike Rylander <mrylander at gmail.com>
Date:   Wed May 6 11:10:44 2015 -0400

    LP#1452352: don't leak $ctx when initializing TPAC R/O object cache
    
    Create a closure over a simple scalar instead of the
    whole $ctx object when all we need is the locale.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
index c164b74..0401d20 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
@@ -41,6 +41,7 @@ sub init_ro_object_cache {
     }
 
     my $locale_subs = {};
+    my $locale = $ctx->{locale};
 
     # make all "field_safe" classes accesible by default in the template context
     my @classes = grep {
@@ -63,17 +64,17 @@ sub init_ro_object_cache {
         # Retrieve the full set of objects with class $hint
         $locale_subs->{$list_key} = sub {
             my $method = "retrieve_all_$eclass";
-            $cache{list}{$ctx->{locale}}{$hint} = $e->$method() unless $cache{list}{$ctx->{locale}}{$hint};
-            return $cache{list}{$ctx->{locale}}{$hint};
+            $cache{list}{$locale}{$hint} = $e->$method() unless $cache{list}{$locale}{$hint};
+            return $cache{list}{$locale}{$hint};
         };
 
         # locate object of class $hint with Ident field $id
         $cache{map}{$hint} = {};
         $locale_subs->{$get_key} = sub {
             my $id = shift;
-            return $cache{map}{$ctx->{locale}}{$hint}{$id} if $cache{map}{$ctx->{locale}}{$hint}{$id};
-            ($cache{map}{$ctx->{locale}}{$hint}{$id}) = grep { $_->$ident_field eq $id } @{$locale_subs->{$list_key}->()};
-            return $cache{map}{$ctx->{locale}}{$hint}{$id};
+            return $cache{map}{$locale}{$hint}{$id} if $cache{map}{$locale}{$hint}{$id};
+            ($cache{map}{$locale}{$hint}{$id}) = grep { $_->$ident_field eq $id } @{$locale_subs->{$list_key}->()};
+            return $cache{map}{$locale}{$hint}{$id};
         };
 
         # search for objects of class $hint where field=value
@@ -92,17 +93,17 @@ sub init_ro_object_cache {
                 $search_obj->{$filterfield} = $filterval;
                 $cacheval .= ':' . $filterfield . ':' . $filterval;
             }
-            #$cache{search}{$ctx->{locale}}{$hint}{$field} = {} unless $cache{search}{$ctx->{locale}}{$hint}{$field};
-            $cache{search}{$ctx->{locale}}{$hint}{$field}{$cacheval} = $e->$method($search_obj)
-                unless $cache{search}{$ctx->{locale}}{$hint}{$field}{$cacheval};
-            return $cache{search}{$ctx->{locale}}{$hint}{$field}{$cacheval};
+            #$cache{search}{$locale}{$hint}{$field} = {} unless $cache{search}{$locale}{$hint}{$field};
+            $cache{search}{$locale}{$hint}{$field}{$cacheval} = $e->$method($search_obj)
+                unless $cache{search}{$locale}{$hint}{$field}{$cacheval};
+            return $cache{search}{$locale}{$hint}{$field}{$cacheval};
         };
     }
 
     $locale_subs->{aou_tree} = sub {
 
         # fetch the org unit tree
-        unless($cache{aou_tree}{$ctx->{locale}}) {
+        unless($cache{aou_tree}{$locale}) {
             my $tree = $e->search_actor_org_unit([
                 {   parent_ou => undef},
                 {   flesh            => -1,
@@ -116,17 +117,17 @@ sub init_ro_object_cache {
             sub flesh_aout {
                 my $node = shift;
                 my $locale_subs = shift;
-                my $ctx = shift;
+                my $locale = shift;
                 $node->ou_type( $locale_subs->{get_aout}->($node->ou_type) );
-                $cache{map}{$ctx->{locale}}{aou}{$node->id} = $node;
-                flesh_aout($_, $locale_subs, $ctx) foreach @{$node->children};
+                $cache{map}{$locale}{aou}{$node->id} = $node;
+                flesh_aout($_, $locale_subs, $locale) foreach @{$node->children};
             };
-            flesh_aout($tree, $locale_subs, $ctx);
+            flesh_aout($tree, $locale_subs, $locale);
 
-            $cache{aou_tree}{$ctx->{locale}} = $tree;
+            $cache{aou_tree}{$locale} = $tree;
         }
 
-        return $cache{aou_tree}{$ctx->{locale}};
+        return $cache{aou_tree}{$locale};
     };
 
     # Add a special handler for the tree-shaped org unit cache
@@ -134,13 +135,13 @@ sub init_ro_object_cache {
         my $org_id = shift;
         return undef unless defined $org_id;
         $locale_subs->{aou_tree}->(); # force the org tree to load
-        return $cache{map}{$ctx->{locale}}{aou}{$org_id};
+        return $cache{map}{$locale}{aou}{$org_id};
     };
 
     # Returns a flat list of aou objects.  often easier to manage than a tree.
     $locale_subs->{aou_list} = sub {
         $locale_subs->{aou_tree}->(); # force the org tree to load
-        return [ values %{$cache{map}{$ctx->{locale}}{aou}} ];
+        return [ values %{$cache{map}{$locale}{aou}} ];
     };
 
     # returns the org unit object by shortname
@@ -153,8 +154,8 @@ sub init_ro_object_cache {
     $locale_subs->{aouct_tree} = sub {
 
         # fetch the org unit tree
-        unless(exists $cache{aouct_tree}{$ctx->{locale}}) {
-            $cache{aouct_tree}{$ctx->{locale}} = undef;
+        unless(exists $cache{aouct_tree}{$locale}) {
+            $cache{aouct_tree}{$locale} = undef;
 
             my $tree_id = $e->search_actor_org_unit_custom_tree(
                 {purpose => 'opac', active => 't'},
@@ -185,12 +186,12 @@ sub init_ro_object_cache {
                     }
                 }
 
-                $cache{aouct_tree}{$ctx->{locale}} = 
+                $cache{aouct_tree}{$locale} = 
                     $node_tree->org_unit if $node_tree;
             }
         }
 
-        return $cache{aouct_tree}{$ctx->{locale}};
+        return $cache{aouct_tree}{$locale};
     };
 
     # turns an ISO date into something TT can understand
@@ -230,30 +231,30 @@ sub init_ro_object_cache {
     $locale_subs->{get_org_setting} = sub {
         my($org_id, $setting) = @_;
 
-        $cache{org_settings}{$ctx->{locale}}{$org_id}{$setting} =
+        $cache{org_settings}{$locale}{$org_id}{$setting} =
             $U->ou_ancestor_setting_value($org_id, $setting)
-                unless exists $cache{org_settings}{$ctx->{locale}}{$org_id}{$setting};
+                unless exists $cache{org_settings}{$locale}{$org_id}{$setting};
 
-        return $cache{org_settings}{$ctx->{locale}}{$org_id}{$setting};
+        return $cache{org_settings}{$locale}{$org_id}{$setting};
     };
 
     # retrieve and cache acsaf values
     $locale_subs->{get_authority_fields} = sub {
         my ($control_set) = @_;
 
-        if (not exists $cache{authority_fields}{$ctx->{locale}}{$control_set}) {
+        if (not exists $cache{authority_fields}{$locale}{$control_set}) {
             my $acs = $e->search_authority_control_set_authority_field(
                 {control_set => $control_set}
             ) or return;
-            $cache{authority_fields}{$ctx->{locale}}{$control_set} =
+            $cache{authority_fields}{$locale}{$control_set} =
                 +{ map { $_->id => $_ } @$acs };
         }
 
-        return $cache{authority_fields}{$ctx->{locale}}{$control_set};
+        return $cache{authority_fields}{$locale}{$control_set};
     };
 
     $ctx->{$_} = $locale_subs->{$_} for keys %$locale_subs;
-    $ro_object_subs->{$ctx->{locale}} = $locale_subs;
+    $ro_object_subs->{$locale} = $locale_subs;
 }
 
 sub generic_redirect {

commit 23ec5c03102bff5eb09ad67b196d8b4b7373fa94
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Wed May 6 13:50:32 2015 +0000

    LP#1452352: fix generation of locale-specific RO object fetchers
    
    The TPAC R/O object cache is now keyed by locale.  This
    fixes an issue where an OPAC session that starts in one
    locale and gets switched to another could see (e.g.)
    format labels for the original locale.
    
    The issue fixed by this patch can be most readily reproduced
    as follows:
    
    [1] Enable both the en-US and fr-CA locales. Make sure
        that there are some translations for record format
        coded values in place as well.
    [2] Run Apache in single-process mode
        (e.g., ". /etc/apache2/envvars && apache2 -X")
    [3] Visit a record details page in the en-US locale. Note
        the label associated with the record format.
    [4] Change the locale to fr-CA. Note that the label is
        still the English version.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
index 1e86db6..c164b74 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
@@ -34,12 +34,14 @@ sub init_ro_object_cache {
     # requirement of reloading apache with each org-setting change
     $cache{org_settings} = {};
 
-    if($ro_object_subs) {
+    if($ro_object_subs->{$ctx->{locale}}) {
         # subs have been built.  insert into the context then move along.
-        $ctx->{$_} = $ro_object_subs->{$_} for keys %$ro_object_subs;
+        $ctx->{$_} = $ro_object_subs->{$ctx->{locale}}->{$_} for keys %{ $ro_object_subs->{$ctx->{locale}} };
         return;
     }
 
+    my $locale_subs = {};
+
     # make all "field_safe" classes accesible by default in the template context
     my @classes = grep {
         ($Fieldmapper::fieldmap->{$_}->{field_safe} || '') =~ /true/i
@@ -59,7 +61,7 @@ sub init_ro_object_cache {
         my $search_key = "search_$hint";
 
         # Retrieve the full set of objects with class $hint
-        $ro_object_subs->{$list_key} = sub {
+        $locale_subs->{$list_key} = sub {
             my $method = "retrieve_all_$eclass";
             $cache{list}{$ctx->{locale}}{$hint} = $e->$method() unless $cache{list}{$ctx->{locale}}{$hint};
             return $cache{list}{$ctx->{locale}}{$hint};
@@ -67,16 +69,16 @@ sub init_ro_object_cache {
 
         # locate object of class $hint with Ident field $id
         $cache{map}{$hint} = {};
-        $ro_object_subs->{$get_key} = sub {
+        $locale_subs->{$get_key} = sub {
             my $id = shift;
             return $cache{map}{$ctx->{locale}}{$hint}{$id} if $cache{map}{$ctx->{locale}}{$hint}{$id};
-            ($cache{map}{$ctx->{locale}}{$hint}{$id}) = grep { $_->$ident_field eq $id } @{$ro_object_subs->{$list_key}->()};
+            ($cache{map}{$ctx->{locale}}{$hint}{$id}) = grep { $_->$ident_field eq $id } @{$locale_subs->{$list_key}->()};
             return $cache{map}{$ctx->{locale}}{$hint}{$id};
         };
 
         # search for objects of class $hint where field=value
         $cache{search}{$hint} = {};
-        $ro_object_subs->{$search_key} = sub {
+        $locale_subs->{$search_key} = sub {
             my ($field, $val, $filterfield, $filterval) = @_;
             my $method = "search_$eclass";
             my $cacheval = $val;
@@ -97,7 +99,7 @@ sub init_ro_object_cache {
         };
     }
 
-    $ro_object_subs->{aou_tree} = sub {
+    $locale_subs->{aou_tree} = sub {
 
         # fetch the org unit tree
         unless($cache{aou_tree}{$ctx->{locale}}) {
@@ -113,13 +115,13 @@ sub init_ro_object_cache {
             # and simultaneously set the id => aou map cache
             sub flesh_aout {
                 my $node = shift;
-                my $ro_object_subs = shift;
+                my $locale_subs = shift;
                 my $ctx = shift;
-                $node->ou_type( $ro_object_subs->{get_aout}->($node->ou_type) );
+                $node->ou_type( $locale_subs->{get_aout}->($node->ou_type) );
                 $cache{map}{$ctx->{locale}}{aou}{$node->id} = $node;
-                flesh_aout($_, $ro_object_subs, $ctx) foreach @{$node->children};
+                flesh_aout($_, $locale_subs, $ctx) foreach @{$node->children};
             };
-            flesh_aout($tree, $ro_object_subs, $ctx);
+            flesh_aout($tree, $locale_subs, $ctx);
 
             $cache{aou_tree}{$ctx->{locale}} = $tree;
         }
@@ -128,27 +130,27 @@ sub init_ro_object_cache {
     };
 
     # Add a special handler for the tree-shaped org unit cache
-    $ro_object_subs->{get_aou} = sub {
+    $locale_subs->{get_aou} = sub {
         my $org_id = shift;
         return undef unless defined $org_id;
-        $ro_object_subs->{aou_tree}->(); # force the org tree to load
+        $locale_subs->{aou_tree}->(); # force the org tree to load
         return $cache{map}{$ctx->{locale}}{aou}{$org_id};
     };
 
     # Returns a flat list of aou objects.  often easier to manage than a tree.
-    $ro_object_subs->{aou_list} = sub {
-        $ro_object_subs->{aou_tree}->(); # force the org tree to load
+    $locale_subs->{aou_list} = sub {
+        $locale_subs->{aou_tree}->(); # force the org tree to load
         return [ values %{$cache{map}{$ctx->{locale}}{aou}} ];
     };
 
     # returns the org unit object by shortname
-    $ro_object_subs->{get_aou_by_shortname} = sub {
+    $locale_subs->{get_aou_by_shortname} = sub {
         my $sn = shift or return undef;
-        my $list = $ro_object_subs->{aou_list}->();
+        my $list = $locale_subs->{aou_list}->();
         return (grep {$_->shortname eq $sn} @$list)[0];
     };
 
-    $ro_object_subs->{aouct_tree} = sub {
+    $locale_subs->{aouct_tree} = sub {
 
         # fetch the org unit tree
         unless(exists $cache{aouct_tree}{$ctx->{locale}}) {
@@ -177,7 +179,7 @@ sub init_ro_object_cache {
                     for my $cnode (@{$node->children}) {
                         my $child_org = $cnode->org_unit;
                         $child_org->parent_ou($aou->id);
-                        $child_org->ou_type( $ro_object_subs->{get_aout}->($child_org->ou_type) );
+                        $child_org->ou_type( $locale_subs->{get_aout}->($child_org->ou_type) );
                         push(@{$aou->children}, $child_org);
                         push(@nodes, $cnode);
                     }
@@ -192,7 +194,7 @@ sub init_ro_object_cache {
     };
 
     # turns an ISO date into something TT can understand
-    $ro_object_subs->{parse_datetime} = sub {
+    $locale_subs->{parse_datetime} = sub {
         my $date = shift;
 
         # Calling parse_datetime() with empty $date will lead to Internal Server Error
@@ -225,7 +227,7 @@ sub init_ro_object_cache {
     };
 
     # retrieve and cache org unit setting values
-    $ro_object_subs->{get_org_setting} = sub {
+    $locale_subs->{get_org_setting} = sub {
         my($org_id, $setting) = @_;
 
         $cache{org_settings}{$ctx->{locale}}{$org_id}{$setting} =
@@ -236,7 +238,7 @@ sub init_ro_object_cache {
     };
 
     # retrieve and cache acsaf values
-    $ro_object_subs->{get_authority_fields} = sub {
+    $locale_subs->{get_authority_fields} = sub {
         my ($control_set) = @_;
 
         if (not exists $cache{authority_fields}{$ctx->{locale}}{$control_set}) {
@@ -250,7 +252,8 @@ sub init_ro_object_cache {
         return $cache{authority_fields}{$ctx->{locale}}{$control_set};
     };
 
-    $ctx->{$_} = $ro_object_subs->{$_} for keys %$ro_object_subs;
+    $ctx->{$_} = $locale_subs->{$_} for keys %$locale_subs;
+    $ro_object_subs->{$ctx->{locale}} = $locale_subs;
 }
 
 sub generic_redirect {

commit 4edf58b71a57769c2ef28cf81a86bc9deeaaf079
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Tue May 5 16:43:18 2015 +0000

    LP#1449709: add release notes
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/docs/RELEASE_NOTES_NEXT/Administration/WebServerTemplateCaching.txt b/docs/RELEASE_NOTES_NEXT/Administration/WebServerTemplateCaching.txt
new file mode 100644
index 0000000..f91b8fe
--- /dev/null
+++ b/docs/RELEASE_NOTES_NEXT/Administration/WebServerTemplateCaching.txt
@@ -0,0 +1,20 @@
+Improved caching of web server templates
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Template Toolkit processors used by Apache are now cached for
+better performance (by virtue of thereby being able to take advantage
+of Template Toolkit's internal caching mechanism). In addition, the
+*compiled* versions of the templates themselves can be cached to
+provide an additional performance boost.
+
+Two Apache virtualhost configuration variables are added to
+control caching of compiled templates:
+
+ * `OILSWebCompiledTemplateCache` - specifies location on the
+   web server filesystem to store compiled templates.
+ * `OILSWebTemplateStatTTL` - specifies number of seconds before
+   checking to see if a newer version of a cached template is
+   available.
+
+As a result of the caching changes, it is now necessary for
+Evergreen administrators to reload Apache to ensure that a change
+to (say) TPAC templates becomes visible.

commit a42f4e9f3d45a5dbc5eefcd86f0d0ee0ad001660
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Tue Apr 28 19:06:48 2015 +0000

    LP#1449709: caching compiled Template Toolkit templates
    
    This patch enables caching of compiled Template Toolkit
    files on Evergreen web servers, which can provide a modest
    improvement in the time it takes (say) TPAC to render
    a page, particularly by a fresh Apache backend.
    
    This is controlled by a new Apache virtualhost variable,
    OILSWebCompiledTemplateCache, which can be set to a
    directory on the webserver for storing compiled templates. This
    is enabled by default for new installations.
    
    This patch also adds OILSWebTemplateStatTTL, which can be
    use to tweak the STAT_TTL Template Toolkit setting. Note this
    bit works because of the caching of TT handlers added by
    the previous patch.
    
    Finally, this patch also fixes a bug where attempting to
    disable OILSWebDebugTemplate would result in internal server errors;
    it also sets the default value of this setting to false.
    
    Note: the caching added by this patch and the previous one
    mean that if a change to (say) TPAC templates is made on
    the file system, it is now required to reload Apache to have
    a guarantee that the change is visible, although one can also
    wait the OILSWebTemplateStatTTL interval.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/examples/apache/eg_vhost.conf.in b/Open-ILS/examples/apache/eg_vhost.conf.in
index 87e9054..d26151e 100644
--- a/Open-ILS/examples/apache/eg_vhost.conf.in
+++ b/Open-ILS/examples/apache/eg_vhost.conf.in
@@ -646,7 +646,12 @@ RewriteRule ^/openurl$ ${openurl:%1} [NE,PT]
     PerlSetVar OILSWebDefaultTemplateExtension "tt2"
 
     # Enable Template-Toolkit error debugging messages (apache error log)
-    PerlSetVar OILSWebDebugTemplate "true"
+    PerlSetVar OILSWebDebugTemplate "false"
+    # local cache of compiled Template Toolkit templates
+    PerlSetVar OILSWebCompiledTemplateCache "/tmp/eg_template_cache"
+    # template TTL - how long, in seconds, that Template Toolkit
+    # waits to check for updated template files
+    #PerlSetVar OILSWebTemplateStatTTL 60
 
     # -------------------------------------------------------
     # Media Prefix.  In the 3rd example, the protocol (http) is enforced
diff --git a/Open-ILS/examples/apache_24/eg_vhost.conf.in b/Open-ILS/examples/apache_24/eg_vhost.conf.in
index d4bbd78..f733616 100644
--- a/Open-ILS/examples/apache_24/eg_vhost.conf.in
+++ b/Open-ILS/examples/apache_24/eg_vhost.conf.in
@@ -644,7 +644,12 @@ RewriteRule ^/openurl$ ${openurl:%1} [NE,PT]
     PerlSetVar OILSWebDefaultTemplateExtension "tt2"
 
     # Enable Template-Toolkit error debugging messages (apache error log)
-    PerlSetVar OILSWebDebugTemplate "true"
+    PerlSetVar OILSWebDebugTemplate "false"
+    # local cache of compiled Template Toolkit templates
+    PerlSetVar OILSWebCompiledTemplateCache "/tmp/eg_template_cache"
+    # template TTL - how long, in seconds, that Template Toolkit
+    # waits to check for updated template files
+    #PerlSetVar OILSWebTemplateStatTTL 60
 
     # -------------------------------------------------------
     # Media Prefix.  In the 3rd example, the protocol (http) is enforced
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
index db0645d..8b3fcbf 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
@@ -66,13 +66,22 @@ sub handler_guts {
     $processor_key .= $r->dir_config('OILSWebContextLoader').':';   # ... and context loader
     $processor_key .= $ctx->{locale};                               # ... and locale
     # NOTE: context loader and vhost together imply template path and debug template values
-    # TODO: maybe add STAT_TTL and cache dir from LP#1449709?
 
     my $tt = $vhost_processor_cache{$processor_key} || Template->new({
         ENCODING => 'utf-8',
         OUTPUT => ($as_xml) ?  sub { parse_as_xml($r, $ctx, @_); } : $r,
         INCLUDE_PATH => $ctx->{template_paths},
         DEBUG => $ctx->{debug_template},
+        (
+            $r->dir_config('OILSWebCompiledTemplateCache') ?
+                (COMPILE_DIR => $r->dir_config('OILSWebCompiledTemplateCache')) :
+                ()
+        ),
+        (
+            ($r->dir_config('OILSWebTemplateStatTTL') =~ /^\d+$/) ?
+                (STAT_TTL => $r->dir_config('OILSWebTemplateStatTTL')) :
+                ()
+        ),
         PLUGINS => {
             EGI18N => 'OpenILS::WWW::EGWeb::I18NFilter',
             CGI_utf8 => 'OpenILS::WWW::EGWeb::CGI_utf8'
@@ -174,7 +183,7 @@ sub load_context {
 
     $ctx->{base_path} = $r->dir_config('OILSWebBasePath');
     $ctx->{web_dir} = $r->dir_config('OILSWebWebDir');
-    $ctx->{debug_template} = ($r->dir_config('OILSWebDebugTemplate') =~ /true/io);
+    $ctx->{debug_template} = ($r->dir_config('OILSWebDebugTemplate') =~ /true/io) ? 1 : 0;
     $ctx->{media_prefix} = $r->dir_config('OILSWebMediaPrefix');
     $ctx->{hostname} = $r->hostname;
     $ctx->{base_url} = $cgi->url(-base => 1);

commit bc55788c14222f5b40db418d5faa841350dd42c5
Author: Mike Rylander <mrylander at gmail.com>
Date:   Mon May 4 17:06:54 2015 -0400

    LP#1449709: Persist template processor for speed
    
    By persisting the Template Toolkit processor object per
    vhost/locale/context-loader/xml-strictness instead
    of creating a new one for every request, we allow TT
    to maintain an in-memory cache of all the templates it
    has compiled.  This increases speed by as much as 80%.
    
    In addition, we reduce the number of times the TPAC checks
    for the existance of a template by remembering the state
    of the first readability probe.  This is most important
    on systems where the templates are stored on NFS, where
    stat(2) system calls can be particularly expensive.
    
    We now pass the Apache object ($r) to the template processor
    instead of relying on tied-STDOUT behaviour, because each
    request gets a new tied file handle.  After the first one,
    it's the wrong one.
    
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>
    Signed-off-by: Bill Erickson <berickxx at gmail.com>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
index 682e2d6..db0645d 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
@@ -19,6 +19,12 @@ use constant OILS_HTTP_COOKIE_LOCALE => 'eg_locale';
 # cache string bundles
 my %registered_locales;
 
+# cache template path -r tests
+my %vhost_path_cache;
+
+# cache template processors by vhost
+my %vhost_processor_cache;
+
 sub handler {
     my $r = shift;
     my $stat = handler_guts($r);
@@ -55,7 +61,14 @@ sub handler_guts {
 
     my $text_handler = set_text_handler($ctx, $r);
 
-    my $tt = Template->new({
+    my $processor_key = $as_xml ? 'xml:' : 'text:';                 # separate by XML strictness
+    $processor_key .= $ctx->{hostname}.':';                         # ... and vhost
+    $processor_key .= $r->dir_config('OILSWebContextLoader').':';   # ... and context loader
+    $processor_key .= $ctx->{locale};                               # ... and locale
+    # NOTE: context loader and vhost together imply template path and debug template values
+    # TODO: maybe add STAT_TTL and cache dir from LP#1449709?
+
+    my $tt = $vhost_processor_cache{$processor_key} || Template->new({
         ENCODING => 'utf-8',
         OUTPUT => ($as_xml) ?  sub { parse_as_xml($r, $ctx, @_); } : $r,
         INCLUDE_PATH => $ctx->{template_paths},
@@ -80,9 +93,10 @@ sub handler_guts {
         return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
     }   
 
+    $vhost_processor_cache{$processor_key} = $tt;
     $ctx->{encode_utf8} = sub {return encode_utf8(shift())};
 
-    unless($tt->process($template, {ctx => $ctx, ENV => \%ENV, l => $text_handler})) {
+    unless($tt->process($template, {ctx => $ctx, ENV => \%ENV, l => $text_handler}, $r)) {
         $r->log->warn('egweb: template error: ' . $tt->error);
         return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -250,6 +264,9 @@ sub find_template {
     my $ext = $r->dir_config('OILSWebDefaultTemplateExtension');
     my $at_index = $r->dir_config('OILSWebStopAtIndex');
 
+    $vhost_path_cache{$ctx->{hostname}} ||= {};
+    my $path_cache = $vhost_path_cache{$ctx->{hostname}};
+
     my @parts = split('/', $path);
     my $localpath = $path;
 
@@ -258,18 +275,24 @@ sub find_template {
     } else {
         $r->content_type('text/html; encoding=utf8');
     }
+
     my @args;
     while(@parts) {
         last unless $localpath;
         for my $tpath (@{$ctx->{template_paths}}) {
             my $fpath = "$tpath/$localpath.$ext";
             $r->log->debug("egweb: looking at possible template $fpath");
-            if(-r $fpath) {
-                $template = "$localpath.$ext";
+            if ($template = $path_cache->{$fpath}) { # we've checked with -r before...
+                next if ($template eq '0E0'); # ... and found nothing
                 last;
-            } 
+            } elsif (-r $fpath) { # or, we haven't checked, and if we find a file...
+                $path_cache->{$fpath} = $template = "$localpath.$ext"; # ... note it
+                last;
+            } else { # Nothing there...
+                $path_cache->{$fpath} = '0E0'; # ... note that fact
+            }
         }
-        last if $template;
+        last if $template and $template ne '0E0';
 
         if ($at_index) {
             # no matching template was found in the current directory.
@@ -284,13 +307,18 @@ sub find_template {
                 }
                 my $fpath = "$tpath/$localpath.$ext";
                 $r->log->debug("egweb: looking at possible template $fpath");
-                if (-r $fpath) {
-                    $template = "$localpath.$ext";
+                if ($template = $path_cache->{$fpath}) { # See above block
+                    next if ($template eq '0E0');
                     last;
-                }
+                } elsif (-r $fpath) {
+                    $path_cache->{$fpath} = $template = "$localpath.$ext";
+                    last;
+                } else {
+                    $path_cache->{$fpath} = '0E0';
+                } 
             }
         }
-        last if $template;
+        last if $template and $template ne '0E0';
 
         push(@args, pop @parts);
         $localpath = join('/', @parts);
@@ -299,7 +327,7 @@ sub find_template {
     $page_args = [@args];
 
     # no template configured or found
-    unless($template) {
+    if(!$template or $template eq '0E0') {
         $r->log->debug("egweb: No template configured for path $path");
         return ();
     }

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/examples/apache/eg_startup.in             |    2 +-
 Open-ILS/examples/apache/eg_vhost.conf.in          |    7 +-
 Open-ILS/examples/apache_24/eg.conf.in             |    1 +
 Open-ILS/examples/apache_24/eg_vhost.conf.in       |    7 +-
 .../perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm   |  150 +++++++++++++-------
 Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm     |   85 ++++++++++--
 .../Administration/WebServerTemplateCaching.txt    |   20 +++
 7 files changed, 203 insertions(+), 69 deletions(-)
 create mode 100644 docs/RELEASE_NOTES_NEXT/Administration/WebServerTemplateCaching.txt


hooks/post-receive
-- 
Evergreen ILS



More information about the open-ils-commits mailing list