From bc55788c14222f5b40db418d5faa841350dd42c5 Mon Sep 17 00:00:00 2001 From: Mike Rylander Date: Mon, 4 May 2015 17:06:54 -0400 Subject: [PATCH] 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 Signed-off-by: Galen Charlton Signed-off-by: Bill Erickson --- .../src/perlmods/lib/OpenILS/WWW/EGWeb.pm | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm index 682e2d6559..db0645ddbc 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 (); } -- 2.43.2