Situation:
User A requests an item from the cache (CFileCache::getValue()). This item appears to be expired, so the code will generate a new value and saves this with CFileCache::setValue().
This can be a time-consuming processs, let’s say three seconds.
In this three seconds, User B can come along, finds an expired cacheValue and also tries to rebuild this cachevalue.
On a very busy site, even more users (or requests) can rebuild the same cache value.
This can be prevented by modifying the getValue() function in CFileCache.php.
protected function getValue($key)
{
$cacheFile=$this->getCacheFile($key);
if(($time=@filemtime($cacheFile))>time())
return @file_get_contents($cacheFile);
else if($time>0)
@unlink($cacheFile);
return false;
}
Instead of unlinking the cachefile, it might be an option to touch this file again and thus extending the lifetime of this cached item bij a few seconds.
This can be accomplished by adding an public variable:
public $autoExtendExpiredCache = null;
and change the function getValue into:
protected function getValue($key)
{
$cacheFile=$this->getCacheFile($key);
if(($time=@filemtime($cacheFile))>time())
return @file_get_contents($cacheFile);
else if($time>0) {
if (is_null($this->autoExtendExpiredCache) {
@unlink($cacheFile);
} else {
@touch($cacheFile,time()+$this->autoExtendExpiredCache);
}
}
return false;
}
Any thoughts on this?
(This idea is based on the same problem occuring with PEAR’s Cache_Lite, and is described here: http://www.4pmp.com/2009/09/pear-cache_lite-preventing-stampeding/)