whales / cache
Caching library
Installs: 16
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/whales/cache
Requires (Dev)
- phpunit/phpunit: 4.3.*
This package is not auto-updated.
Last update: 2025-10-21 06:42:45 UTC
README
#Cache ##Examples ###Stampede Protection ####Object Instantiation
// Service in need of caching and stampede protection $callableService = function ($key) { return 'resourceIntensiveData'; }; // Would need to be database-backed lock to actual work in the example // since the InMemoryLock has a per request lifecycle. $lock = new Cache\StampedeProtection\Locks\InMemoryLock; $memcached = new \Memcached(); $memcached->addServer('127.0.0.1', 11211); $transientCache = new Cache\Maps\MemcachedCacheMap($memcached); // Acts as stale cache while service is processing data $persistentCache = new Cache\Maps\PdoCacheMap( new \PDO('mysql:host=localhost;dbname=test'), 'cache' );
####Object Composition
$cachedService = new CallableServiceCachingDecorator( new MutexLockAcquiringDecorator( $callableService, $lock, $persistentCache ), new LockReleaseOnSettingCacheMap( new LinkedNodeCacheMap( $transientCache, new LockAffectedCacheMap( $persistentCache, $lock ) ), $lock ) ); $data = call_user_func($cachedService, 'key1234');
####Explanation
Assumption: The $persistentCache is primed so that there will always be some data returned even while the new data is being retrieved/regenerated.
- When a request comes into
$cachedServiceit will attempt to find the item in the cache- The call to
findwill get passed on through:LockReleaseOnSettingCacheMap, which delegates to:LinkedNodeCacheMap- Here it will first check the
$transientCacheand either:- Hit, in which case it will return the cached value all the way back up to the original caller.
- Miss and then:
- Check the
$persistentCache, which is primed and should result in a hit, however since theLockAffectedCacheMapis wrapping the$persistentCacheit will report a cache miss since the lock is available (i.e. nobody else is currently working on regenerating the data for the cache) - The cache miss is then propogated all the way back up to
CallableServiceCachingDecorator.
- Check the
- Here it will first check the
- Since the iterator returned from
findis empty, the code then needs to call into the actual service to retrieve the fresh data.- The call to the service will pass through the
MutexLockAcquiringDecoratorobject which will acquire the lock and let all future requests to the service know that someone is currently retrieving the data from the original datasource and regenerating the new cache data. - While the lock is held, all future requests will retrieve data from the stale
$persistentCache. Remember that since this is wrapped in theLockAffectedCacheMapand the lock is now unavailable the$persistentCachewill now report a cache hit and return it's stale data.
- The call to the service will pass through the
- After the service is called and the fresh data is returned back up to
CallableServiceCachingDecorator, we then set the cache to reflect the new data. - The call to
setpasses throughLockReleaseOnSettingCacheMapwhich delegates the setting toLinkedNodeCacheMapwhich then will add the new data to both the$transientCacheand$persistentCache(future stale cache). - After setting the new values, the lock is then released.
- Finally the fresh data is passed out to the top-level caller.
- The call to