23use Wikimedia\ObjectFactory\ObjectFactory;
44 private $consistencyWindow;
46 private $lastKeyWrites = [];
49 private const MAX_WRITE_DELAY = 5;
67 if ( !isset(
$params[
'writeFactory'] ) ) {
68 throw new InvalidArgumentException(
69 __METHOD__ .
': the "writeFactory" parameter is required' );
70 } elseif ( !isset(
$params[
'readFactory'] ) ) {
71 throw new InvalidArgumentException(
72 __METHOD__ .
': the "readFactory" parameter is required' );
75 $this->consistencyWindow =
$params[
'sessionConsistencyWindow'] ?? self::MAX_WRITE_DELAY;
78 : ObjectFactory::getObjectFromSpec(
$params[
'writeFactory'] );
81 : ObjectFactory::getObjectFromSpec(
$params[
'readFactory'] );
82 $this->attrMap = $this->
mergeFlagMaps( [ $this->readStore, $this->writeStore ] );
85 public function get( $key, $flags = 0 ) {
87 $this->hadRecentSessionWrite( [ $key ] ) ||
95 return $store->proxyCall(
104 public function set( $key, $value, $exptime = 0, $flags = 0 ) {
105 $this->remarkRecentSessionWrite( [ $key ] );
107 return $this->writeStore->proxyCall(
116 public function delete( $key, $flags = 0 ) {
117 $this->remarkRecentSessionWrite( [ $key ] );
119 return $this->writeStore->proxyCall(
128 public function add( $key, $value, $exptime = 0, $flags = 0 ) {
129 $this->remarkRecentSessionWrite( [ $key ] );
131 return $this->writeStore->proxyCall(
140 public function merge( $key, callable $callback, $exptime = 0, $attempts = 10, $flags = 0 ) {
141 $this->remarkRecentSessionWrite( [ $key ] );
143 return $this->writeStore->proxyCall(
152 public function changeTTL( $key, $exptime = 0, $flags = 0 ) {
153 $this->remarkRecentSessionWrite( [ $key ] );
155 return $this->writeStore->proxyCall(
164 public function lock( $key, $timeout = 6, $exptime = 6, $rclass =
'' ) {
165 return $this->writeStore->proxyCall(
175 return $this->writeStore->proxyCall(
186 callable $progress =
null,
190 return $this->writeStore->proxyCall(
199 public function getMulti( array $keys, $flags = 0 ) {
201 $this->hadRecentSessionWrite( $keys ) ||
209 return $store->proxyCall(
218 public function setMulti( array $valueByKey, $exptime = 0, $flags = 0 ) {
219 $this->remarkRecentSessionWrite( array_keys( $valueByKey ) );
221 return $this->writeStore->proxyCall(
231 $this->remarkRecentSessionWrite( $keys );
233 return $this->writeStore->proxyCall(
243 $this->remarkRecentSessionWrite( $keys );
245 return $this->writeStore->proxyCall(
254 public function incrWithInit( $key, $exptime, $step = 1, $init =
null, $flags = 0 ) {
255 $this->remarkRecentSessionWrite( [ $key ] );
257 return $this->writeStore->proxyCall(
267 parent::setMockTime( $time );
268 $this->writeStore->setMockTime( $time );
269 $this->readStore->setMockTime( $time );
276 private function hadRecentSessionWrite( array $keys ) {
278 foreach ( $keys as $key ) {
279 $ts = $this->lastKeyWrites[$key] ?? 0;
280 if ( $ts && ( $now - $ts ) <= $this->consistencyWindow ) {
291 private function remarkRecentSessionWrite( array $keys ) {
293 foreach ( $keys as $key ) {
295 unset( $this->lastKeyWrites[$key] );
296 $this->lastKeyWrites[$key] = $now;
299 if ( ( $now - reset( $this->lastKeyWrites ) ) > $this->consistencyWindow ) {
300 $this->lastKeyWrites = array_filter(
301 $this->lastKeyWrites,
302 function ( $timestamp ) use ( $now ) {
303 return ( ( $now - $timestamp ) <= $this->consistencyWindow );
array $params
The job parameters.
A cache class that directs writes to one set of servers and reads to another.
add( $key, $value, $exptime=0, $flags=0)
Insert an item if it does not already exist.
deleteObjectsExpiringBefore( $timestamp, callable $progress=null, $limit=INF, string $tag=null)
Delete all objects expiring before a certain date.
__construct( $params)
Constructor.
changeTTLMulti(array $keys, $exptime, $flags=0)
Change the expiration of multiple items.
incrWithInit( $key, $exptime, $step=1, $init=null, $flags=0)
Increase the value of the given key (no TTL change) if it exists or create it otherwise.
lock( $key, $timeout=6, $exptime=6, $rclass='')
Acquire an advisory lock on a key string, exclusive to the caller.
deleteMulti(array $keys, $flags=0)
Delete a batch of items.
getMulti(array $keys, $flags=0)
Get a batch of items.
changeTTL( $key, $exptime=0, $flags=0)
Change the expiration on an item.
setMulti(array $valueByKey, $exptime=0, $flags=0)
Set a batch of items.
merge( $key, callable $callback, $exptime=0, $attempts=10, $flags=0)
Merge changes into the existing cache value (possibly creating a new one)
unlock( $key)
Release an advisory lock on a key string.