gitweb/lib - Use locking to avoid 'cache miss stampede' problem
authorJakub Narebski <jnareb@gmail.com>
Sun, 5 Dec 2010 23:01:03 +0000 (00:01 +0100)
committerJakub Narebski <jnareb@gmail.com>
Sun, 5 Dec 2010 23:01:03 +0000 (00:01 +0100)
commitdc6d39c9b9432f02a03a7aaabc5cb2feb9c19b9a
treef7e4578ff1073fcc6d7c0cca2423325f4d01bd20
parent54ac40e7c464fa21674def755026a3e99bafd88b
gitweb/lib - Use locking to avoid 'cache miss stampede' problem

Create GitwebCache::FileCacheWithLocking module (class), derived from
GitwebCache::SimpleFileCache, where the ->compute($key, $code) method
use locking (via flock) to ensure that only one process would generate
data to update/fill-in cache; the rest would wait for the cache to
be (re)generated and would read data from cache.  If process that was
to (re)generate data dies or exits, one of the readers would take its
role.  This also means that if some data is not cached (like e.g. error
pages in gitweb), then it would work correctly even in rare case of
simultaneous access to the same non-cached entry.

Currently this feature can not be disabled via %cache_options,
although you can set $cache to 'GitwebCache::SimpleFileCache' instead.
Future new features (like: serving stale data while cache is being
regenerated, (re)generating cache in background, activity indicator)
all depend on locking.

A test in t9503 shows that in the case where there are two clients
trying to simultaneously access non-existent or stale cache entry,
(and generating data takes (artifically) a bit of time), if they are
using ->compute method the data is (re)generated once, as opposed to
situation when those clients are just using ->get/->set methods.

The situation where subroutine used to generate data dies is also
tested in t9503.

Note that there is very slight inefficiency, in that filename for
lockfile depends on the filename for cache entry (it just adds '.lock'
suffix), but is recalculated from $key for both paths.

Inspired-by-code-by: John 'Warthog9' Hawley <warthog9@kernel.org>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb/Makefile
gitweb/README
gitweb/gitweb.perl
gitweb/lib/GitwebCache/FileCacheWithLocking.pm [new file with mode: 0644]
t/t9503/test_cache_interface.pl