Signed-off-by: Jakub Narebski <jnareb@xxxxxxxxx> --- This patch, as you can see, lack proper commit message: it is work in progress. As you can see cache_fetch() subroutine is much, much simpler that the one in original patch by J.H.: [PATCH 9/9] gitweb: File based caching layer (from git.kernel.org) Message-ID: <1263432185-21334-10-git-send-email-warthog9@xxxxxxxxxxxxxx> http://permalink.gmane.org/gmane.comp.version-control.git/136917 As you can see I have introduced $cache_pm variable, to be able to test caching in t/t9500-gitweb-standalone-no-errors.sh, but also to be able to install cache.pm in some other place than along gitweb.cgi. There would be no such problems if we used 'require GitwebCache' or somesuch, in place of 'do "cache.pm"' like in original patch by J.H. But at leats for now I have decided to follow J.H. in this issue. Instead of using binary (sic!) valued $cache_enable as in J.H. patch, I use set of two variables: $cache (to be able to select what caching engine to use, and what features should be enabled), and $caching_enabled to actually enable/disable cache. When caching is enabled gitweb do not output timing info (time to generate page), as it would contain incorrect information if the page was retrieved from cache; in this place we could put cachetime info from the original patch by J.H., which means writing Cache Last Updated: ". gmtime( time ) I have forgot about adding this feature... ATTENTION !!!: I have run both tests (t9500 to check for errors in gitweb.perl, and t9503 to test the API), but I haven't actually tested that *gitweb itself* behaves correctly. gitweb/cache.pm | 36 ++++++++++++++++++++++++++++ gitweb/gitweb.perl | 40 +++++++++++++++++++++++++++++-- t/gitweb-lib.sh | 2 + t/t9500-gitweb-standalone-no-errors.sh | 13 ++++++++++ 4 files changed, 88 insertions(+), 3 deletions(-) diff --git a/gitweb/cache.pm b/gitweb/cache.pm index 12a7a78..3a33158 100644 --- a/gitweb/cache.pm +++ b/gitweb/cache.pm @@ -359,4 +359,41 @@ sub compute { 1; } # end of package GitwebCache::SimpleFileCache; +# human readable key identifying gitweb output +sub gitweb_output_key { + return href(-replay => 1, -full => 1, -path_info => 0); +} + +sub cache_fetch { + my ($cache, $action) = @_; + + my $key = gitweb_output_key(); + my $data = $cache->get($key); + + if (defined $data) { + # print cached data + binmode STDOUT, ':raw'; + print STDOUT $data; + + } else { + # calculate data and regenerate data + open my $data_fh, '>', \$data + or die "Can't open memory file: $!"; + # matches "binmode STDOUT, ':uft8'" at beginning + binmode $data_fh, ':utf8'; + + $out = $data_fh || \*STDOUT; + $actions{$action}->(); + + if (defined $data) { + $cache->set($key, $data); + binmode STDOUT, ':raw'; + local $/ = undef; + print STDOUT $data; + } + + close $data_fh; + } +} + 1; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index cd5073c..0394dc8 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -234,6 +234,22 @@ our $gitlinkurl_base = ("++GITWEB_BASE_URL++" =~ m!^(git://.*)$!) ? $1 : ''; # Leave it undefined (or set to 'undef') to turn off load checking. our $maxload = 300; +# This enables/disables the caching layer in gitweb. Currently supported +# is only output (response) caching, similar to the one used on git.kernel.org. +our $caching_enabled = 0; +# Set to _initialized_ instance of cache interface implementing (at least) +# get($key) and set($key, $data) methods (Cache::Cache and CHI interfaces). +# If unset, GitwebCache::SimpleFileCache would be used, which is 'dumb' +# (but fast) file based caching layer, currently without any support for +# cache size limiting. It is therefore recommended that the cache directory +# be periodically completely deleted; this operation is safe to perform. +# Suggested mechanism: +# mv $cachedir $cachedir.flush && mkdir $cachedir && rm -rf $cachedir.flush +our $cache; +# Locations of 'cache.pm' file; if it is relative path, it is relative to +# the directory gitweb is run from +our $cache_pm = 'cache.pm'; + # You define site-wide feature defaults here; override them with # $GITWEB_CONFIG as necessary. our %feature = ( @@ -998,7 +1014,21 @@ if ($action !~ m/^(?:opml|project_list|project_index)$/ && !$project) { die_error(400, "Project needed"); } -$actions{$action}->(); + +if ($caching_enabled) { + do $cache_pm; + die $@ if $@; + + $cache ||= GitwebCache::SimpleFileCache->new({ + 'cache_root' => '/tmp/cache', + 'cache_depth' => 2, + 'expires_in' => 20, # in seconds + }); + cache_fetch($cache, $action); +} else { + $actions{$action}->(); +} + exit; ## ====================================================================== @@ -3207,7 +3237,9 @@ sub git_header_html { # 'application/xhtml+xml', otherwise send it as plain old 'text/html'. # we have to do this because MSIE sometimes globs '*/*', pretending to # support xhtml+xml but choking when it gets what it asked for. - if (defined $cgi->http('HTTP_ACCEPT') && + # Disable content-type negotiation when caching (use mimetype good for all). + if (!$caching_enabled && + defined $cgi->http('HTTP_ACCEPT') && $cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ && $cgi->Accept('application/xhtml+xml') != 0) { $content_type = 'application/xhtml+xml'; @@ -3380,7 +3412,9 @@ sub git_footer_html { } print {$out} "</div>\n"; # class="page_footer" - if (defined $t0 && gitweb_check_feature('timed')) { + # timing info doesn't make much sense with output (response) caching + if (!$caching_enabled && + defined $t0 && gitweb_check_feature('timed')) { print {$out} "<div id=\"generating_info\">\n"; print {$out} 'This page took '. '<span id="generating_time" class="time_span">'. diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh index d9ffc90..d041083 100755 --- a/t/gitweb-lib.sh +++ b/t/gitweb-lib.sh @@ -27,6 +27,8 @@ our \$export_ok = ''; our \$strict_export = ''; our \$git_versions_must_match = 0; +our \$cache_pm = '$TEST_DIRECTORY/../gitweb/cache.pm'; + EOF cat >.git/description <<EOF diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 2fc7fdb..0f93962 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -639,4 +639,17 @@ test_expect_success \ gitweb_run "p=.git;a=summary"' test_debug 'cat gitweb.log' +# ---------------------------------------------------------------------- +# caching + +cat >>gitweb_config.perl <<\EOF + +$caching_enabled = 1; +EOF +test_expect_success \ + 'caching enabled' \ + 'gitweb_run "p=.git;a=summary"' +test_debug 'cat gitweb.log' + + test_done -- 1.6.6.1 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html