protected $cache;
/** @var HashBagOStuff Script instance PHP cache */
protected $procCache;
- /** @var string Cache pool name */
- protected $pool;
+ /** @var string Purge channel name */
+ protected $purgeChannel;
/** @var EventRelayer Bus that handles purge broadcasts */
- protected $relayer;
+ protected $purgeRelayer;
/** @var LoggerInterface */
protected $logger;
/** Cache format version number */
const VERSION = 1;
- const FLD_VERSION = 0;
- const FLD_VALUE = 1;
- const FLD_TTL = 2;
- const FLD_TIME = 3;
- const FLD_FLAGS = 4;
- const FLD_HOLDOFF = 5;
+ const FLD_VERSION = 0; // key to cache version number
+ const FLD_VALUE = 1; // key to the cached value
+ const FLD_TTL = 2; // key to the original TTL
+ const FLD_TIME = 3; // key to the cache time
+ const FLD_FLAGS = 4; // key to the flags bitfield
+ const FLD_HOLDOFF = 5; // key to any hold-off TTL
/** @var integer Treat this value as expired-on-arrival */
const FLG_STALE = 1;
const MAX_PC_KEYS = 1000; // max keys to keep in process cache
+ const DEFAULT_PURGE_CHANNEL = 'wancache-purge';
+
/**
* @param array $params
- * - cache : BagOStuff object
- * - pool : pool name
- * - relayer : EventRelayer object
- * - logger : LoggerInterface object
+ * - cache : BagOStuff object for a persistent cache
+ * - channels : Map of (action => channel string). Actions include "purge".
+ * - relayers : Map of (action => EventRelayer object). Actions include "purge".
+ * - logger : LoggerInterface object
*/
public function __construct( array $params ) {
$this->cache = $params['cache'];
- $this->pool = $params['pool'];
- $this->relayer = $params['relayer'];
$this->procCache = new HashBagOStuff( [ 'maxKeys' => self::MAX_PC_KEYS ] );
+ $this->purgeChannel = isset( $params['channels']['purge'] )
+ ? $params['channels']['purge']
+ : self::DEFAULT_PURGE_CHANNEL;
+ $this->purgeRelayer = isset( $params['relayers']['purge'] )
+ ? $params['relayers']['purge']
+ : new EventRelayerNull( [] );
$this->setLogger( isset( $params['logger'] ) ? $params['logger'] : new NullLogger() );
}
* @return bool Success
*/
final public function set( $key, $value, $ttl = 0, array $opts = [] ) {
+ $now = microtime( true );
$lockTSE = isset( $opts['lockTSE'] ) ? $opts['lockTSE'] : self::TSE_NONE;
- $age = isset( $opts['since'] ) ? max( 0, microtime( true ) - $opts['since'] ) : 0;
+ $age = isset( $opts['since'] ) ? max( 0, $now - $opts['since'] ) : 0;
$lag = isset( $opts['lag'] ) ? $opts['lag'] : 0;
// Do not cache potentially uncommitted data as it might get rolled back
}
// Wrap that value with time/TTL/version metadata
- $wrapped = $this->wrap( $value, $ttl ) + $wrapExtra;
+ $wrapped = $this->wrap( $value, $ttl, $now ) + $wrapExtra;
$func = function ( $cache, $key, $cWrapped ) use ( $wrapped ) {
return ( is_string( $cWrapped ) )
*
* return CatConfig::newFromRow( $dbr->selectRow( ... ) );
* },
- * array(
+ * [
* // Calling touchCheckKey() on this key invalidates the cache
- * 'checkKeys' => array( $cache->makeKey( 'site-cat-config' ) ),
+ * 'checkKeys' => [ $cache->makeKey( 'site-cat-config' ) ],
* // Try to only let one datacenter thread manage cache updates at a time
* 'lockTSE' => 30
- * )
+ * ]
* );
* @endcode
*
*
* return CatState::newFromResults( $dbr->select( ... ) );
* },
- * array(
+ * [
* // The "check" keys that represent things the value depends on;
* // Calling touchCheckKey() on any of them invalidates the cache
- * 'checkKeys' => array(
+ * 'checkKeys' => [
* $cache->makeKey( 'sustenance-bowls', $cat->getRoomId() ),
* $cache->makeKey( 'people-present', $cat->getHouseId() ),
* $cache->makeKey( 'cat-laws', $cat->getCityId() ),
- * )
- * )
+ * ]
+ * ]
* );
* @endcode
*
* $setOpts += Database::getCacheSetOptions( $dbr );
*
* // Start off with the last cached list
- * $list = $oldValue ?: array();
+ * $list = $oldValue ?: [];
* // Fetch the last 100 relevant rows in descending order;
* // only fetch rows newer than $list[0] to reduce scanning
* $rows = iterator_to_array( $dbr->select( ... ) );
* return array_slice( array_merge( $new, $list ), 0, 100 );
* },
* // Try to only let one datacenter thread manage cache updates at a time
- * array( 'lockTSE' => 30 )
+ * [ 'lockTSE' => 30 ]
* );
* @endcode
*
'sbt' => true, // substitute $UNIXTIME$ with actual microtime
] );
- $ok = $this->relayer->notify( "{$this->pool}:purge", $event );
+ $ok = $this->purgeRelayer->notify( $this->purgeChannel, $event );
if ( !$ok ) {
$this->lastRelayError = self::ERR_RELAY;
}
'key' => $key,
] );
- $ok = $this->relayer->notify( "{$this->pool}:purge", $event );
+ $ok = $this->purgeRelayer->notify( $this->purgeChannel, $event );
if ( !$ok ) {
$this->lastRelayError = self::ERR_RELAY;
}
*
* @param mixed $value
* @param integer $ttl [0=forever]
+ * @param float $now Unix Current timestamp just before calling set()
* @return array
*/
- protected function wrap( $value, $ttl ) {
+ protected function wrap( $value, $ttl, $now ) {
return [
self::FLD_VERSION => self::VERSION,
self::FLD_VALUE => $value,
self::FLD_TTL => $ttl,
- self::FLD_TIME => microtime( true )
+ self::FLD_TIME => $now
];
}
* Do not use this method outside WANObjectCache
*
* @param array|string|bool $wrapped
- * @param float $now Unix Current timestamp (preferrable pre-query)
+ * @param float $now Unix Current timestamp (preferrably pre-query)
* @return array (mixed; false if absent/invalid, current time left)
*/
protected function unwrap( $wrapped, $now ) {