MediaWiki: WANObjectCache Class Reference
MediaWiki
REL1_39
Public Member Functions
Static Public Member Functions
Public Attributes
Protected Member Functions
Protected Attributes
List of all members
WANObjectCache Class Reference
Cache
Multi-datacenter aware caching interface.
More...
Inheritance diagram for WANObjectCache:
legend
Collaboration diagram for WANObjectCache:
legend
Public Member Functions
__construct
(array $params)
adaptiveTTL
( $mtime, $maxTTL, $minTTL=30, $factor=0.2)
Get a TTL that is higher for objects that have not changed recently.
clearLastError
()
Clear the "last error" registry.
clearProcessCache
()
Clear the in-process caches; useful for testing.
delete
( $key, $ttl=self::HOLDOFF_TTL)
Purge a key from all datacenters.
get
( $key, &$curTTL=null, array $checkKeys=[], &$info=[])
Fetch the value of a key from cache.
getCheckKeyTime
( $key)
Fetch the value of a timestamp "check" key.
getLastError
( $watchPoint=0)
Get the "last error" registry.
getMulti
(array $keys, &$curTTLs=[], array $checkKeys=[], &$info=[])
Fetch the value of several keys from cache.
getMultiCheckKeyTime
(array $keys)
Fetch the values of each timestamp "check" key.
getMultiWithSetCallback
(ArrayIterator $keyedIds, $ttl, callable $callback, array $opts=[])
Method to fetch multiple cache keys at once with regeneration.
getMultiWithUnionSetCallback
(ArrayIterator $keyedIds, $ttl, callable $callback, array $opts=[])
Method to fetch/regenerate multiple cache keys at once.
getQoS
( $flag)
getWarmupKeyMisses
()
getWithSetCallback
( $key, $ttl, $callback, array $opts=[], array $cbParams=[])
Method to fetch/regenerate a cache key.
hash256
( $component)
Hash a possibly long string into a suitable component for makeKey()/makeGlobalKey()
makeGlobalKey
( $collection,... $components)
Make a cache key for the global keyspace and given components.
makeKey
( $collection,... $components)
Make a cache key using the "global" keyspace for the given components.
makeMultiKeys
(array $ids, $keyCallback)
Get an iterator of (cache key => entity ID) for a list of entity IDs.
multiRemap
(array $ids, array $res)
Get an (ID => value) map from (i) a non-unique list of entity IDs, and (ii) the list of corresponding entity values by first appearance of each ID in the entity ID list.
reap
( $key, $purgeTimestamp, &$isStale=false)
Set a key to soon expire in the local cluster if it pre-dates $purgeTimestamp.
reapCheckKey
( $key, $purgeTimestamp, &$isStale=false)
Set a "check" key to soon expire in the local cluster if it pre-dates $purgeTimestamp.
resetCheckKey
( $key)
Clear the last-purge timestamp of a "check" key in all datacenters.
set
( $key, $value, $ttl=self::TTL_INDEFINITE, array $opts=[])
Set the value of a key in cache.
setLogger
(LoggerInterface $logger)
setMockTime
(&$time)
touchCheckKey
( $key, $holdoff=self::HOLDOFF_TTL)
Increase the last-purge timestamp of a "check" key in all datacenters.
useInterimHoldOffCaching
( $enabled)
Enable or disable the use of brief caching for tombstoned keys.
watchErrors
()
Get a "watch point" token that can be used to get the "last error" to occur after now.
Static Public Member Functions
static
getCollectionFromSisterKey
(string $sisterKey)
static
newEmpty
()
Get an instance that wraps
EmptyBagOStuff
Public Attributes
const
GRACE_TTL_NONE
= 0
Idiom for set()/getWithSetCallback() meaning "no post-expiration grace period".
const
HOLDOFF_TTL
= self::MAX_COMMIT_DELAY + self::MAX_READ_LAG + 1
Seconds to tombstone keys on delete() and to treat keys as volatile after purges.
const
HOLDOFF_TTL_NONE
= 0
Idiom for delete()/touchCheckKey() meaning "no hold-off period".
const
KEY_AS_OF
= 'asOf'
Generation completion timestamp attribute for a key; keep value for b/c (< 1.36)
const
KEY_CHECK_AS_OF
= 'lastCKPurge'
Highest "check" key timestamp for a key; keep value for b/c (< 1.36)
const
KEY_CUR_TTL
= 'curTTL'
Remaining TTL attribute for a key; keep value for b/c (< 1.36)
const
KEY_TOMB_AS_OF
= 'tombAsOf'
Tomstone timestamp attribute for a key; keep value for b/c (< 1.36)
const
KEY_TTL
= 'ttl'
Logical TTL attribute for a key.
const
KEY_VERSION
= 'version'
Version
number attribute for a key; keep value for b/c (< 1.36)
const
PASS_BY_REF
= []
Idiom for get()/getMulti() to return extra information by reference.
const
STALE_TTL_NONE
= 0
Idiom for set()/getWithSetCallback() meaning "no post-expiration persistence".
const
TTL_LAGGED
= 30
Max TTL, in seconds, to store keys when a data source has high replication lag.
Public Attributes inherited from
Wikimedia\LightweightObjectStore\StorageAwareness
const
ATTR_DURABILITY
= 2
Durability of writes; see QOS_DURABILITY_* (higher means stronger)
const
ATTR_EMULATION
= 1
Emulation/fallback mode; see QOS_EMULATION_*; higher is better.
const
ERR_NO_RESPONSE
= 1
Storage medium failed to yield a complete response to an operation.
const
ERR_NONE
= 0
No storage medium error.
const
ERR_UNEXPECTED
= 3
Storage medium operation failed due to usage limitations or an I/O error.
const
ERR_UNREACHABLE
= 2
Storage medium could not be reached to establish a connection.
const
QOS_DURABILITY_DISK
= 4
Data is saved to disk and writes do not usually block on fsync()
const
QOS_DURABILITY_NONE
= 1
Data is never saved to begin with (blackhole store)
const
QOS_DURABILITY_RDBMS
= 5
Data is saved to disk and writes usually block on fsync(), like a standard RDBMS.
const
QOS_DURABILITY_SCRIPT
= 2
Data is lost at the end of the current web request or CLI script.
const
QOS_DURABILITY_SERVICE
= 3
Data is lost once the service storing the data restarts.
const
QOS_EMULATION_SQL
= 1
Fallback disk-based SQL store.
const
QOS_UNKNOWN
= INF
Generic "unknown" value; useful for comparisons (always "good enough")
Protected Member Functions
fetchKeys
(array $keys, array $checkKeys, $touchedCb=null)
Fetch the value and key metadata of several keys from cache.
getCurrentTime
()
isLotteryRefreshDue
( $res, $lowTTL, $ageNew, $hotTTR, $now)
Check if a key is due for randomized regeneration due to near-expiration/popularity.
isValid
( $value, $asOf, $minAsOf)
Check that a wrapper value exists and has an acceptable age.
prependRoute
(string $sisterKey, string $route)
relayNonVolatilePurge
(string $sisterKey)
Remove a sister key from all datacenters.
relayVolatilePurges
(array $purgeBySisterKey, int $ttl)
Set a sister key to a purge value in all datacenters.
worthRefreshExpiring
( $curTTL, $logicalTTL, $lowTTL)
Check if a key is nearing expiration and thus due for randomized regeneration.
worthRefreshPopular
( $asOf, $ageNew, $timeTillRefresh, $now)
Check if a key is due for randomized regeneration due to its popularity.
Protected Attributes
callable null
$asyncHandler
Function that takes a WAN cache callback and runs it later.
string null
$broadcastRoute
Routing prefix for operations that should be broadcasted to all data centers.
BagOStuff
$cache
The local datacenter cache.
int
$coalesceScheme
Scheme to use for key coalescing (Hash Tags or Hash Stops)
float
$epoch
Unix timestamp of the oldest possible valid values.
LoggerInterface
$logger
MapCacheLRU
[]
$processCaches
= []
Map of group PHP instance caches.
string
$secret
Stable secret used for hashing long strings into key components.
StatsdDataFactoryInterface
$stats
bool
$useInterimHoldOffCaching
true
Whether to use "interim" caching while keys are tombstoned.
Detailed Description
Multi-datacenter aware caching interface.
Using WANObjectCache
All operations go to the local datacenter cache, except for delete(), touchCheckKey(), and resetCheckKey(), which broadcast to all datacenters.
This class is intended for caching data from primary stores. If the get() method does not return a value, then the caller should query the new value and backfill the cache using set(). The preferred way to do this logic is through getWithSetCallback(). When querying the store on cache miss, the closest DB replica should be used. Try to avoid heavyweight DB primary or quorum reads.
To ensure consumers of the cache see new values in a timely manner, you either need to follow either the validation strategy, or the purge strategy.
The validation strategy refers to the natural avoidance of stale data by one of the following means:
A) The cached value is immutable. If the consumer has access to an identifier that uniquely describes a value, cached value need not change. Instead, the key can change. This also allows all servers to access their perceived current version. This is important in context of multiple deployed versions of your application and/or cross-dc database replication, to ensure deterministic values without oscillation.
B) Validity is checked against the source after get(). This is the inverse of A. The unique identifier is embedded inside the value and validated after on retrieval. If outdated, the value is recomputed.
C) The value is cached with a modest TTL (without validation). If value recomputation is reasonably performant, and the value is allowed to be stale, one should consider using TTL only – using the value's age as method of validation.
The purge strategy refers to the approach whereby your application knows that source data has changed and can react by purging the relevant cache keys. As purges are expensive, this strategy should be avoided if possible. The simplest purge method is delete().
No matter which strategy you choose, callers must not rely on updates or purges being immediately visible to other servers. It should be treated similarly as one would a database replica.
The need for immediate updates should be avoided. If needed, solutions must be sought outside
WANObjectCache
Deploying WANObjectCache
There are two supported ways to set up broadcasted operations:
A) Set up mcrouter as the cache backend, with a memcached
BagOStuff
class for the 'cache' parameter, and a wildcard routing prefix for the 'broadcastRoutingPrefix' parameter. Configure mcrouter as follows:
Define a "" pool of memcached servers for each datacenter.
Define a "/wan" route to each datacenter, using "AllSyncRoute" for the routes that go to the local datacenter pool and "AllAsyncRoute" for the routes that go to remote datacenter pools. The child routes should use "HashRoute|". This allows for the use of a wildcard route for 'broadcastRoutingPrefix'. See
and
In order to reroute operations from "down" servers to spare ("gutter") servers, use "FailoverWithExptimeRoute" (failover_exptime=60) instead of "HashRoute|" in the "AllSyncRoute"/"AllAsyncRoute" child routes. The "gutter" pool is a set of memcached servers that only handle failover traffic. Such servers should be carefully spread over different rows and racks. See
B) Set up dynomite as the cache backend, using a memcached
BagOStuff
class for the 'cache' parameter. Note that with this setup, all key setting operations will be broadcasted, rather than just purges. Writes will be eventually consistent via the Dynamo replication model. See
Broadcasted operations like delete() and touchCheckKey() are intended to run immediately in the local datacenter and asynchronously in remote datacenters.
This means that callers in all datacenters may see older values for however many milliseconds that the purge took to reach that datacenter. As with any cache, this should not be relied on for cases where reads are used to determine writes to source (e.g. non-cache) data stores, except when reading immutable data.
Internally, access to a given key actually involves the use of one or more "sister" keys. A sister key is constructed by prefixing the base key with "WANCache:" (used to distinguish
WANObjectCache
formatted keys) and suffixing a colon followed by a single-character sister key type. The sister key types include the following:
: used to store "regular" values (metadata-wrapped) and temporary purge "tombstones".
: used to store "last purge" timestamps for "check" keys.
: used to store temporary mutex locks to avoid cache stampedes.
: used to store temporary interim values (metadata-wrapped) for tombstoned keys.
: used to store temporary "cool-off" indicators, which specify a period during which values cannot be stored, neither regularly nor using interim keys.
Stability: newable
Since
1.26
Definition at line
127
of file
WANObjectCache.php
Constructor & Destructor Documentation
__construct()
WANObjectCache::__construct
array
$params
Stability: stable
to call
Parameters
array
$params
cache :
BagOStuff
object for a persistent cache
logger : LoggerInterface object
stats : StatsdDataFactoryInterface object
asyncHandler : A function that takes a callback and runs it later. If supplied, whenever a preemptive refresh would be triggered in getWithSetCallback(), the current cache value is still used instead. However, the async-handler function receives a WAN cache callback that, when run, will execute the value generation callback supplied by the getWithSetCallback() caller. The result will be saved as normal. The handler is expected to call the WAN cache callback at an opportune time (e.g. HTTP post-send), though generally within a few 100ms. [optional]
broadcastRoutingPrefix: a routing prefix used to broadcast certain operations to all datacenters; See also
. This prefix takes the form
///
, where
datacenter
is usually a wildcard to select all matching routes (e.g. the WAN cluster in all DCs). See also
. This is required when using mcrouter as a multi-region backing store proxy. [optional]
epoch: lowest UNIX timestamp a value/tombstone must have to be valid. [optional]
secret: stable secret used for hashing long strings into key components. [optional]
coalesceScheme: which key scheme to use in order to encourage the backend to place any "helper" keys for a "value" key within the same cache server. This reduces network overhead and reduces the chance the a single downed cache server causes disruption. Use "hash_stop" with mcrouter and "hash_tag" with dynomite. [default: "hash_stop"]
keyHighQps: reads/second assumed during a hypothetical cache write stampede for a single key. This is used to decide when the overhead of checking short-lived write throttling keys is worth it. [default: 100]
keyHighUplinkBps: maximum tolerable bytes/second to spend on a cache write stampede for a single key. This is used to decide when the overhead of checking short-lived write throttling keys is worth it. [default: (1/100 of a 1Gbps link)]
Definition at line
347
of file
WANObjectCache.php
References
setLogger()
Member Function Documentation
adaptiveTTL()
WANObjectCache::adaptiveTTL
$mtime
$maxTTL
$minTTL
30
$factor
0.2
Get a TTL that is higher for objects that have not changed recently.
This is useful for keys that get explicit purges and DB or purge relay lag is a potential concern (especially how it interacts with CDN cache)
Example usage:
// Last-modified time of page
$mtime =
wfTimestamp
( TS_UNIX, $page->getTimestamp() );
// Get adjusted TTL. If $mtime is 3600 seconds ago and $minTTL/$factor left at
// defaults, then $ttl is 3600 * .2 = 720. If $minTTL was greater than 720, then
// $ttl would be $minTTL. If $maxTTL was smaller than 720, $ttl would be $maxTTL.
$ttl =
$cache
->adaptiveTTL( $mtime, $cache::TTL_DAY );
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition
GlobalFunctions.php:1424
$cache
$cache
Definition
mcc.php:33
Another use case is when there are no applicable "last modified" fields in the DB, and there are too many dependencies for explicit purges to be viable, and the rate of change to relevant content is unstable, and it is highly valued to have the cached value be as up-to-date as possible.
Example usage:
$query =
""
$idListFromComplexQuery =
$cache
->getWithSetCallback(
$cache
->makeKey(
'complex-graph-query'
, $hashOfQuery ),
GraphQueryClass::STARTING_TTL,
function ( $oldValue, &$ttl, array &$setOpts, $oldAsOf ) use ( $query,
$cache
) {
$gdb = $this->getReplicaGraphDbConnection();
// Account for any snapshot/replica DB lag
$setOpts += GraphDatabase::getCacheSetOptions( $gdb );
$newList = iterator_to_array( $gdb->query( $query ) );
sort( $newList, SORT_NUMERIC );
// normalize
$minTTL = GraphQueryClass::MIN_TTL;
$maxTTL = GraphQueryClass::MAX_TTL;
if
( $oldValue !==
false
) {
// Note that $oldAsOf is the last time this callback ran
$ttl = ( $newList === $oldValue )
// No change: cache for 150% of the age of $oldValue
$cache
->adaptiveTTL( $oldAsOf, $maxTTL, $minTTL, 1.5 )
// Changed: cache for 50% of the age of $oldValue
$cache
->adaptiveTTL( $oldAsOf, $maxTTL, $minTTL, .5 );
return
$newList;
},
// Keep stale values around for doing comparisons for TTL calculations.
// High values improve long-tail keys hit-rates, though might waste space.
'staleTTL'
=> GraphQueryClass::GRACE_TTL
);
Parameters
int | float | string | null
$mtime
UNIX timestamp; null if none
int
$maxTTL
Maximum TTL (seconds)
int
$minTTL
Minimum TTL (seconds); Default: 30
float
$factor
Value in the range (0,1); Default: .2
Returns
int Adaptive TTL
Since
1.28
Definition at line
2626
of file
WANObjectCache.php
References
getCurrentTime()
clearLastError()
WANObjectCache::clearLastError
final
Clear the "last error" registry.
Deprecated
Since 1.38
Definition at line
2517
of file
WANObjectCache.php
clearProcessCache()
WANObjectCache::clearProcessCache
Clear the in-process caches; useful for testing.
Since
1.27
Definition at line
2526
of file
WANObjectCache.php
delete()
WANObjectCache::delete
$key
$ttl
self::HOLDOFF_TTL
final
Purge a key from all datacenters.
This should only be called when the underlying data (being cached) changes in a significant way. This deletes the key and starts a hold-off period where the key cannot be written to for a few seconds (HOLDOFF_TTL). This is done to avoid the following race condition:
a) Some DB data changes and delete() is called on a corresponding key
b) A request refills the key with a stale value from a lagged DB
c) The stale value is stuck there until the key is expired/evicted
This is implemented by storing a special "tombstone" value at the cache key that this class recognizes; get() calls will return false for the key and any set() calls will refuse to replace tombstone values at the key. For this to always avoid stale value writes, the following must hold:
a) Replication lag is bounded to being less than HOLDOFF_TTL; or
b) If lag is higher, the DB will have gone into read-only mode already
Note that set() can also be lag-aware and lower the TTL if it's high.
Be aware that this does not clear the process cache. Even if it did, callbacks used by getWithSetCallback() might still return stale data in the case of either uncommitted or not-yet-replicated changes (callback generally use replica DBs).
When using potentially long-running ACID transactions, a good pattern is to use a pre-commit hook to issue the delete. This means that immediately after commit, callers will see the tombstone in cache upon purge relay. It also avoids the following race condition:
a) T1 begins, changes a row, and calls delete()
b) The HOLDOFF_TTL passes, expiring the delete() tombstone
c) T2 starts, reads the row and calls set() due to a cache miss
d) T1 finally commits
e) Stale value is stuck in cache
Example usage:
$dbw->startAtomic( __METHOD__ );
// start of request
... ...
// Update the row in the DB
$dbw->update( ... );
$key =
$cache
->makeKey(
'homes'
, $homeId );
// Purge the corresponding cache entry just before committing
$dbw->onTransactionPreCommitOrIdle(
function
() use (
$cache
, $key ) {
$cache
->delete( $key );
} );
... ...
$dbw->endAtomic( __METHOD__ );
// end of request
The $ttl parameter can be used when purging values that have not actually changed recently. For example, user-requested purges or cache cleanup scripts might not need to invoke a hold-off period on cache backfills, so they can use HOLDOFF_TTL_NONE.
Note that $ttl limits the effective range of 'lockTSE' for getWithSetCallback().
If called twice on the same key, then the last hold-off TTL takes precedence. For idempotence, the $ttl should not vary for different delete() calls on the same key.
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
int
$ttl
Tombstone TTL; Default: WANObjectCache::HOLDOFF_TTL
Returns
bool True if the item was purged or not found, false on failure
Definition at line
978
of file
WANObjectCache.php
References
getCurrentTime()
relayNonVolatilePurge()
, and
relayVolatilePurges()
fetchKeys()
WANObjectCache::fetchKeys
array
$keys
array
$checkKeys
$touchedCb
null
protected
Fetch the value and key metadata of several keys from cache.
$checkKeys holds the "check" keys used to validate values of applicable keys. The integer indexes hold "check" keys that apply to all of $keys while the string indexes hold "check" keys that only apply to the cache key with that name.
Parameters
string[]
$keys
List/map with makeKey()/makeGlobalKey() cache keys as values
string[] | string[][]
$checkKeys
Map of (integer or cache key => "check" key(s)); "check" keys must also be made with makeKey()/makeGlobalKey()
callable | null
$touchedCb
Callback yielding a UNIX timestamp from a value, or null
Returns
array Map of (key => WANObjectCache::RESULT_* map) in order of $keys
Note
Callable type hints are not used to avoid class-autoloading
Definition at line
554
of file
WANObjectCache.php
References
$keys
$res
, and
getCurrentTime()
Referenced by
get()
getMulti()
, and
getMultiWithUnionSetCallback()
get()
WANObjectCache::get
$key
$curTTL
null
array
$checkKeys
[]
$info
[]
final
Fetch the value of a key from cache.
If supplied, $curTTL is set to the remaining TTL (current time left):
a) INF; if $key exists, has no TTL, and is not purged by $checkKeys
b) float (>=0); if $key exists, has a TTL, and is not purged by $checkKeys
c) float (<0); if $key is tombstoned, stale, or existing but purged by $checkKeys
d) null; if $key does not exist and is not tombstoned
If a key is tombstoned, $curTTL will reflect the time since delete().
The timestamp of $key will be checked against the last-purge timestamp of each of $checkKeys. Those $checkKeys not in cache will have the last-purge initialized to the current timestamp. If any of $checkKeys have a timestamp greater than that of $key, then $curTTL will reflect how long ago $key became invalid. Callers can use $curTTL to know when the value is stale. The $checkKeys parameter allow mass key purges by updating a single key:
a) Each "check" key represents "last purged" of some source data
b) Callers pass in relevant "check" keys as $checkKeys in get()
c) When the source data that "check" keys represent changes, the touchCheckKey() method is called on them
Source data entities might exists in a DB that uses snapshot isolation (e.g. the default REPEATABLE-READ in innoDB). Even for mutable data, that isolation can largely be maintained by doing the following:
a) Calling delete() on entity change
and
creation, before DB commit
b) Keeping transaction duration shorter than the delete() hold-off TTL
c) Disabling interim key caching via useInterimHoldOffCaching() before get() calls
However, pre-snapshot values might still be seen if an update was made in a remote datacenter but the purge from delete() didn't relay yet.
Consider using getWithSetCallback(), which has cache slam avoidance and key versioning features, instead of bare get()/set() calls.
Do not use this method on versioned keys accessed via getWithSetCallback().
When using the $info parameter, it should be passed in as WANObjectCache::PASS_BY_REF. In that case, it becomes a key metadata map. Otherwise, for backwards compatibility, $info becomes the value generation timestamp (null if the key is nonexistant/tombstoned). Key metadata map fields include:
WANObjectCache::KEY_VERSION: value version number; null if key is nonexistant
WANObjectCache::KEY_AS_OF: value generation timestamp (UNIX); null if key is nonexistant
WANObjectCache::KEY_TTL: assigned TTL (seconds); null if key is nonexistant/tombstoned
WANObjectCache::KEY_CUR_TTL: remaining TTL (seconds); null if key is nonexistant
WANObjectCache::KEY_TOMB_AS_OF: tombstone timestamp (UNIX); null if key is not tombstoned
WANObjectCache::KEY_CHECK_AS_OF: highest "check" key timestamp (UNIX); null if none
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
float | null
&$curTTL
Seconds of TTL left [returned]
string[]
$checkKeys
Map of (integer or cache key => "check" key(s)); "check" keys must also be made with makeKey()/makeGlobalKey()
array
&$info
Metadata map [returned]
Returns
mixed Value of cache key; false on failure
Definition at line
449
of file
WANObjectCache.php
References
$res
fetchKeys()
, and
getCurrentTime()
getCheckKeyTime()
WANObjectCache::getCheckKeyTime
$key
final
Fetch the value of a timestamp "check" key.
The key will be
initialized
to the current time if not set, so only call this method if this behavior is actually desired
The timestamp can be used to check whether a cached value is valid. Callers should not assume that this returns the same timestamp in all datacenters due to relay delays.
The level of staleness can roughly be estimated from this key, but if the key was evicted from cache, such calculations may show the time since expiry as ~0 seconds.
Note that "check" keys won't collide with other regular keys.
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
Returns
float UNIX timestamp
Definition at line
1027
of file
WANObjectCache.php
References
getMultiCheckKeyTime()
getCollectionFromSisterKey()
static WANObjectCache::getCollectionFromSisterKey
string
$sisterKey
static
Parameters
string
$sisterKey
Sister key from makeSisterKey()
Returns
string Key collection name
Access: internal
For use by WANObjectCache/BagOStuff only
Since
1.36
Definition at line
1824
of file
WANObjectCache.php
getCurrentTime()
WANObjectCache::getCurrentTime
protected
Returns
float UNIX timestamp
Definition at line
3137
of file
WANObjectCache.php
Referenced by
adaptiveTTL()
delete()
fetchKeys()
get()
getMultiCheckKeyTime()
set()
, and
touchCheckKey()
getLastError()
WANObjectCache::getLastError
$watchPoint
final
Get the "last error" registry.
The method should be invoked by a caller as part of the following pattern:
The caller invokes watchErrors() to get a "since token"
The caller invokes a sequence of cache operation methods
The caller invokes getLastError() with the "since token"
External callers can also invoke this method as part of the following pattern:
The caller invokes clearLastError()
The caller invokes a sequence of cache operation methods
The caller invokes getLastError()
Parameters
int
$watchPoint
Only consider errors from after this "watch point" [optional]
Returns
int
BagOStuff
:ERR_* constant for the "last error" registry
Note
Parameters added in 1.38: $watchPoint
Definition at line
2499
of file
WANObjectCache.php
getMulti()
WANObjectCache::getMulti
array
$keys
$curTTLs
[]
array
$checkKeys
[]
$info
[]
final
Fetch the value of several keys from cache.
$curTTLs becomes a map of only present/tombstoned $keys to their current time-to-live.
$checkKeys holds the "check" keys used to validate values of applicable keys. The integer indexes hold "check" keys that apply to all of $keys while the string indexes hold "check" keys that only apply to the cache key with that name. The logic of "check" keys otherwise works the same as in WANObjectCache::get().
When using the $info parameter, it should be passed in as WANObjectCache::PASS_BY_REF. In that case, it becomes a mapping of all the $keys to their metadata maps, each in the style of WANObjectCache::get(). Otherwise, for backwards compatibility, $info becomes a map of only present/tombstoned $keys to their value generation timestamps.
See also
WANObjectCache::get()
Parameters
string[]
$keys
List/map with makeKey()/makeGlobalKey() cache keys as values
array
&$curTTLs Map of (key => seconds of TTL left) [returned]
string[] | string[][]
$checkKeys
Map of (integer or cache key => "check" key(s)); "check" keys must also be made with makeKey()/makeGlobalKey()
array
&$info Map of (key => metadata map) [returned]
Returns
array Map of (key => value) for existing values in order of $keys
Definition at line
502
of file
WANObjectCache.php
References
$keys
$res
, and
fetchKeys()
getMultiCheckKeyTime()
WANObjectCache::getMultiCheckKeyTime
array
$keys
final
Fetch the values of each timestamp "check" key.
This works like getCheckKeyTime() except it takes a list of keys and returns a map of timestamps instead of just that of one key
This might be useful if both:
a) a class of entities each depend on hundreds of other entities
b) these other entities are depended upon by millions of entities
The later entities can each use a "check" key to purge their dependee entities. However, it is expensive for the former entities to verify against all of the relevant "check" keys during each getWithSetCallback() call. A less expensive approach is to do these verifications only after a "time-till-verify" (TTV) has passed. This is a middle ground between using blind TTLs and using constant verification. The adaptiveTTL() method can be used to dynamically adjust the TTV. Also, the initial TTV can make use of the last-modified times of the dependent entities (either from the DB or the "check" keys).
Example usage:
$value =
$cache
->getWithSetCallback(
$cache
->makeGlobalKey(
'wikibase-item'
, $id ),
self::INITIAL_TTV,
// initial time-till-verify
function ( $oldValue, &$ttv, &$setOpts, $oldAsOf ) use ( $checkKeys,
$cache
) {
$now = microtime(
true
);
// Use $oldValue if it passes max ultimate age and "check" key comparisons
if
( $oldValue &&
$oldAsOf > max(
$cache
->getMultiCheckKeyTime( $checkKeys ) ) &&
( $now - $oldValue[
'ctime'
] ) <= self::MAX_CACHE_AGE
) {
// Increase time-till-verify by 50% of last time to reduce overhead
$ttv =
$cache
->adaptiveTTL( $oldAsOf, self::MAX_TTV, self::MIN_TTV, 1.5 );
// Unlike $oldAsOf, "ctime" is the ultimate age of the cached data
return
$oldValue;
$mtimes = [];
// dependency last-modified times; passed by reference
$value = [
'data'
=> $this->fetchEntityData( $mtimes ),
'ctime'
=> $now ];
// Guess time-till-change among the dependencies, e.g. 1/(total change rate)
$ttc = 1 / array_sum( array_map(
function
( $mtime ) use ( $now ) {
return
1 / ( $mtime ? ( $now - $mtime ) : 900 );
},
$mtimes
) );
// The time-to-verify should not be overly pessimistic nor optimistic
$ttv = min( max( $ttc, self::MIN_TTV ), self::MAX_TTV );
return
$value;
},
'staleTTL'
=> $cache::TTL_DAY ]
// keep around to verify and re-save
);
See also
WANObjectCache::getCheckKeyTime()
WANObjectCache::getWithSetCallback()
Parameters
string[]
$keys
Cache keys made with makeKey()/makeGlobalKey()
Returns
float[] Map of (key => UNIX timestamp)
Since
1.31
Definition at line
1092
of file
WANObjectCache.php
References
$keys
, and
getCurrentTime()
Referenced by
getCheckKeyTime()
getMultiWithSetCallback()
WANObjectCache::getMultiWithSetCallback
ArrayIterator
$keyedIds
$ttl
callable
$callback
array
$opts
[]
final
Method to fetch multiple cache keys at once with regeneration.
This works the same as getWithSetCallback() except:
a) The $keys argument must be the result of WANObjectCache::makeMultiKeys()
b) The $callback argument expects a function that returns an entity value, using boolean "false" if it does not exist. The callback takes the following arguments:
$id: ID of the entity to query
$oldValue: prior cache value or false if none was present
&$ttl: reference to the TTL to be assigned to the new value (alterable)
&$setOpts: reference to the new value set() options (alterable)
$oldAsOf: generation UNIX timestamp of $oldValue or null if not present
c) The return value is a map of (cache key => value) in the order of $keyedIds
See also
WANObjectCache::getWithSetCallback()
WANObjectCache::getMultiWithUnionSetCallback()
Example usage:
$rows =
$cache
->getMultiWithSetCallback(
// Map of cache keys to entity IDs
$cache
->makeMultiKeys(
$this->fileVersionIds(),
function ( $id ) use (
$cache
) {
return
$cache
->makeKey(
'file-version'
, $id );
),
// Time-to-live (in seconds)
$cache::TTL_DAY,
// Function that derives the new key value
function
( $id, $oldValue, &$ttl, array &$setOpts ) {
$dbr
wfGetDB
DB_REPLICA
);
// Account for any snapshot/replica DB lag
$setOpts += Database::getCacheSetOptions(
$dbr
);
// Load the row for this file
$queryInfo = File::getQueryInfo();
$row =
$dbr
->selectRow(
$queryInfo[
'tables'
],
$queryInfo[
'fields'
],
'id'
=> $id ],
__METHOD__,
[],
$queryInfo[
'joins'
);
return
$row ? (array)$row : false;
},
// Process cache for 30 seconds
'pcTTL'
=> 30,
// Use a dedicated 500 item cache (initialized on-the-fly)
'pcGroup'
=>
'file-versions:500'
);
$files = array_map( [ __CLASS__,
'newFromRow'
], $rows );
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition
GlobalFunctions.php:1942
DB_REPLICA
const DB_REPLICA
Definition
defines.php:26
$dbr
$dbr
Definition
testCompression.php:54
Parameters
ArrayIterator
$keyedIds
Result of WANObjectCache::makeMultiKeys()
int
$ttl
Seconds to live for key updates
callable
$callback
Callback that yields entity generation callbacks
array
$opts
Options map similar to that of getWithSetCallback()
Returns
mixed[] Map of (cache key => value) in the same order as $keyedIds
Since
1.28
Definition at line
2053
of file
WANObjectCache.php
References
getWithSetCallback()
getMultiWithUnionSetCallback()
WANObjectCache::getMultiWithUnionSetCallback
ArrayIterator
$keyedIds
$ttl
callable
$callback
array
$opts
[]
final
Method to fetch/regenerate multiple cache keys at once.
This works the same as getWithSetCallback() except:
a) The $keys argument expects the result of WANObjectCache::makeMultiKeys()
b) The $callback argument expects a function that returns a map of (ID => new value), using boolean "false" for entities that could not be found, for all entity IDs in $ids. The callback takes the following arguments:
$ids: list of entity IDs that require value generation
&$ttls: reference to the (entity ID => new TTL) map (alterable)
&$setOpts: reference to the new value set() options (alterable)
c) The return value is a map of (cache key => value) in the order of $keyedIds
d) The "lockTSE" and "busyValue" options are ignored
See also
WANObjectCache::getWithSetCallback()
WANObjectCache::getMultiWithSetCallback()
Example usage:
$rows =
$cache
->getMultiWithUnionSetCallback(
// Map of cache keys to entity IDs
$cache
->makeMultiKeys(
$this->fileVersionIds(),
function ( $id ) use (
$cache
) {
return
$cache
->makeKey(
'file-version'
, $id );
),
// Time-to-live (in seconds)
$cache::TTL_DAY,
// Function that derives the new key value
function
( array $ids, array &$ttls, array &$setOpts ) {
$dbr
wfGetDB
DB_REPLICA
);
// Account for any snapshot/replica DB lag
$setOpts += Database::getCacheSetOptions(
$dbr
);
// Load the rows for these files
$rows = array_fill_keys( $ids,
false
);
$queryInfo = File::getQueryInfo();
$res
$dbr
->select(
$queryInfo[
'tables'
],
$queryInfo[
'fields'
],
'id'
=> $ids ],
__METHOD__,
[],
$queryInfo[
'joins'
);
foreach
$res
as $row ) {
$rows[$row->id] = $row;
$mtime =
wfTimestamp
( TS_UNIX, $row->timestamp );
$ttls[$row->id] = $this->adaptiveTTL( $mtime, $ttls[$row->id] );
return
$rows;
},
);
$files = array_map( [ __CLASS__,
'newFromRow'
], $rows );
$res
$res
Definition
testCompression.php:57
Parameters
ArrayIterator
$keyedIds
Result of WANObjectCache::makeMultiKeys()
int
$ttl
Seconds to live for key updates
callable
$callback
Callback that yields entity generation callbacks
array
$opts
Options map similar to that of getWithSetCallback()
Returns
mixed[] Map of (cache key => value) in the same order as $keyedIds
Since
1.30
Definition at line
2156
of file
WANObjectCache.php
References
$res
fetchKeys()
, and
getWithSetCallback()
getQoS()
WANObjectCache::getQoS
$flag
Parameters
int
$flag
ATTR_* class constant
Returns
int QOS_* class constant
Since
1.28
Definition at line
2559
of file
WANObjectCache.php
getWarmupKeyMisses()
WANObjectCache::getWarmupKeyMisses
final
Access: internal
For use by unit tests only
Returns
int
Since
1.30
Definition at line
2644
of file
WANObjectCache.php
getWithSetCallback()
WANObjectCache::getWithSetCallback
$key
$ttl
$callback
array
$opts
[]
array
$cbParams
[]
final
Method to fetch/regenerate a cache key.
On cache miss, the key will be set to the callback result via set() (unless the callback returns false) and that result will be returned. The arguments supplied to the callback are:
$oldValue: prior cache value or false if none was present
&$ttl: alterable reference to the TTL to be assigned to the new value
&$setOpts: alterable reference to the set() options to be used with the new value
$oldAsOf: generation UNIX timestamp of $oldValue or null if not present (since 1.28)
$params: custom field/value map as defined by $cbParams (since 1.35)
It is strongly recommended to set the 'lag' and 'since' fields to avoid race conditions that can cause stale values to get stuck at keys. Usually, callbacks ignore the current value, but it can be used to maintain "most recent X" values that come from time or sequence based source data, provided that the "as of" id/time is tracked. Note that preemptive regeneration and $checkKeys can result in a non-false current value.
Usage of $checkKeys is similar to get() and getMulti(). However, rather than the caller having to inspect a "current time left" variable (e.g. $curTTL, $curTTLs), a cache regeneration will automatically be triggered using the callback.
The $ttl argument and "hotTTR" option (in $opts) use time-dependent randomization to avoid stampedes. Keys that are slow to regenerate and either heavily used or subject to explicit (unpredictable) purges, may need additional mechanisms. The simplest way to avoid stampedes for such keys is to use 'lockTSE' (in $opts). If explicit purges are needed, also:
a) Pass $key into $checkKeys
b) Use touchCheckKey( $key ) instead of delete( $key )
This applies cache server I/O stampede protection against duplicate cache sets. This is important when the callback is slow and/or yields large values for a key.
Example usage (typical key):
$catInfo =
$cache
->getWithSetCallback(
// Key to store the cached value under
$cache
->makeKey(
'cat-attributes'
, $catId ),
// Time-to-live (in seconds)
$cache::TTL_MINUTE,
// Function that derives the new key value
function ( $oldValue, &$ttl, array &$setOpts ) {
$dbr
wfGetDB
DB_REPLICA
);
// Account for any snapshot/replica DB lag
$setOpts += Database::getCacheSetOptions(
$dbr
);
return
$dbr
->selectRow( ... );
);
Example usage (key that is expensive and hot):
$catConfig =
$cache
->getWithSetCallback(
// Key to store the cached value under
$cache
->makeKey(
'site-cat-config'
),
// Time-to-live (in seconds)
$cache::TTL_DAY,
// Function that derives the new key value
function ( $oldValue, &$ttl, array &$setOpts ) {
$dbr
wfGetDB
DB_REPLICA
);
// Account for any snapshot/replica DB lag
$setOpts += Database::getCacheSetOptions(
$dbr
);
return
CatConfig::newFromRow(
$dbr
->selectRow( ... ) );
},
// Calling touchCheckKey() on this key purges the cache
'checkKeys'
=> [
$cache
->makeKey(
'site-cat-config'
) ],
// Try to only let one datacenter thread manage cache updates at a time
'lockTSE'
=> 30,
// Avoid querying cache servers multiple times in a web request
'pcTTL'
=> $cache::TTL_PROC_LONG
);
Example usage (key with dynamic dependencies):
$catState =
$cache
->getWithSetCallback(
// Key to store the cached value under
$cache
->makeKey(
'cat-state'
, $cat->getId() ),
// Time-to-live (seconds)
$cache::TTL_HOUR,
// Function that derives the new key value
function ( $oldValue, &$ttl, array &$setOpts ) {
// Determine new value from the DB
$dbr
wfGetDB
DB_REPLICA
);
// Account for any snapshot/replica DB lag
$setOpts += Database::getCacheSetOptions(
$dbr
);
return
CatState::newFromResults(
$dbr
->select( ... ) );
},
// The "check" keys that represent things the value depends on;
// Calling touchCheckKey() on any of them purges the cache
'checkKeys'
=> [
$cache
->makeKey(
'sustenance-bowls'
, $cat->getRoomId() ),
$cache
->makeKey(
'people-present'
, $cat->getHouseId() ),
$cache
->makeKey(
'cat-laws'
, $cat->getCityId() ),
);
Example usage (key that is expensive with too many DB dependencies for "check" keys):
$catToys =
$cache
->getWithSetCallback(
// Key to store the cached value under
$cache
->makeKey(
'cat-toys'
, $catId ),
// Time-to-live (seconds)
$cache::TTL_HOUR,
// Function that derives the new key value
function ( $oldValue, &$ttl, array &$setOpts ) {
// Determine new value from the DB
$dbr
wfGetDB
DB_REPLICA
);
// Account for any snapshot/replica DB lag
$setOpts += Database::getCacheSetOptions(
$dbr
);
return
CatToys::newFromResults(
$dbr
->select( ... ) );
},
// Get the highest timestamp of any of the cat's toys
'touchedCallback'
=>
function
( $value ) use ( $catId ) {
$dbr
wfGetDB
DB_REPLICA
);
$ts =
$dbr
->selectField(
'cat_toys'
'MAX(ct_touched)'
, ... );
return
wfTimestampOrNull
( TS_UNIX, $ts );
},
// Avoid DB queries for repeated access
'pcTTL'
=> $cache::TTL_PROC_SHORT
);
wfTimestampOrNull
wfTimestampOrNull( $outputtype=TS_UNIX, $ts=null)
Return a formatted timestamp, or null if input is null.
Definition
GlobalFunctions.php:1440
Example usage (hot key holding most recent 100 events):
$lastCatActions =
$cache
->getWithSetCallback(
// Key to store the cached value under
$cache
->makeKey(
'cat-last-actions'
, 100 ),
// Time-to-live (in seconds)
10,
// Function that derives the new key value
function ( $oldValue, &$ttl, array &$setOpts ) {
$dbr
wfGetDB
DB_REPLICA
);
// Account for any snapshot/replica DB lag
$setOpts += Database::getCacheSetOptions(
$dbr
);
// Start off with the last cached list
$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( ... ) );
// Merge them and get the new "last 100" rows
return
array_slice( array_merge( $new, $list ), 0, 100 );
},
// Try to only let one datacenter thread manage cache updates at a time
'lockTSE'
=> 30,
// Use a magic value when no cache value is ready rather than stampeding
'busyValue'
=>
'computing'
);
Example usage (key holding an LRU subkey:value map; this can avoid flooding cache with keys for an unlimited set of (constraint,situation) pairs, thereby avoiding elevated cache evictions and wasted memory):
$catSituationTolerabilityCache = $this->cache->getWithSetCallback(
// Group by constraint ID/hash, cat family ID/hash, or something else useful
$this->cache->makeKey(
'cat-situation-tolerability-checks'
, $groupKey ),
WANObjectCache::TTL_DAY,
// rarely used groups should fade away
// The $scenarioKey format is $constraintId:
function ( $cacheMap ) use ( $scenarioKey, $constraintId, $situation ) {
$lruCache = MapCacheLRU::newFromArray( $cacheMap ?: [], self::CACHE_SIZE );
$result = $lruCache->get( $scenarioKey );
// triggers LRU bump if present
if
( $result ===
null
|| $this->isScenarioResultExpired( $result ) ) {
$result = $this->checkScenarioTolerability( $constraintId, $situation );
$lruCache->set( $scenarioKey, $result, 3 / 8 );
// Save the new LRU cache map and reset the map's TTL
return
$lruCache->toArray();
},
// Once map is > 1 sec old, consider refreshing
'ageNew'
=> 1,
// Update within 5 seconds after "ageNew" given a 1hz cache check rate
'hotTTR'
=> 5,
// Avoid querying cache servers multiple times in a request; this also means
// that a request can only alter the value of any given constraint key once
'pcTTL'
=> WANObjectCache::TTL_PROC_LONG
);
$tolerability = isset( $catSituationTolerabilityCache[$scenarioKey] )
? $catSituationTolerabilityCache[$scenarioKey]
: $this->checkScenarioTolerability( $constraintId, $situation );
See also
WANObjectCache::get()
WANObjectCache::set()
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
int
$ttl
Nominal seconds-to-live for newly computed values. Special values are:
WANObjectCache::TTL_INDEFINITE: Cache forever (subject to LRU-style evictions)
WANObjectCache::TTL_UNCACHEABLE: Do not cache (if the key exists, it is not deleted)
callable
$callback
Value generation function
array
$opts
Options map:
checkKeys: List of "check" keys. The key at $key will be seen as stale when either touchCheckKey() or resetCheckKey() is called on any of the keys in this list. This is useful if thousands or millions of keys depend on the same entity. The entity can simply have its "check" key updated whenever the entity is modified. Default: [].
graceTTL: If the key is purged (by "checkKeys" or "touchedCallback") less than this many seconds ago, consider reusing the stale value. The odds of a refresh become more likely over time, becoming certain once the grace period is reached. This can reduce traffic spikes when millions of keys are compared to the same "check" key and touchCheckKey() or resetCheckKey() is called on that "check" key. This option is not useful for avoiding traffic spikes in the case of the key simply expiring on account of its TTL (use "lowTTL" instead). Default: WANObjectCache::GRACE_TTL_NONE.
lockTSE: Prefer the use of a mutex during value regeneration of the key if its TSE ("time since expiry") is less than the given number of seconds ago. The TSE of the key is influenced by purges (e.g. via delete(), "checkKeys", and "touchedCallback"), and various other options (e.g. "staleTTL"). A low enough TSE is assumed to indicate a high enough key access rate to justify stampede avoidance. A thread that tries and fails to acquire the mutex will use a stale value for the key, if there is one, and, if not, it will execute the callback. Note that no cache value exists after deletion or storage-layer expiration/eviction; to prevent stampedes during these cases, avoid using delete(), keep "lowTTL" enabled, and consider using "busyValue". Default: WANObjectCache::TSE_NONE.
busyValue: Specify a placeholder value to use when no value exists and another thread is currently regenerating it. This assures that cache stampedes cannot happen if the value falls out of cache. This also mitigates stampedes when value regeneration becomes very slow (greater than $ttl/"lowTTL"). If this is a closure, then it will be invoked to get the placeholder when needed. Default: null.
pcTTL: Process cache the value in this PHP instance for this many seconds. This avoids network I/O when a key is read several times. This will not cache when the callback returns false, however. Note that any purges will not be seen while process cached; since the callback should use replica DBs and they may be lagged or have snapshot isolation anyway, this should not typically matter. Default: WANObjectCache::TTL_UNCACHEABLE.
pcGroup: Process cache group to use instead of the primary one. If set, this must be of the format ALPHANUMERIC_NAME:MAX_KEY_SIZE, e.g. "mydata:10". Use this for storing large values, small yet numerous values, or some values with a high cost of eviction. It is generally preferable to use a class constant when setting this value. This has no effect unless pcTTL is used. Default: WANObjectCache::PC_PRIMARY.
version: Integer version number. This lets callers make breaking changes to the format of cached values without causing problems for sites that use non-instantaneous code deployments. Old and new code will recognize incompatible versions and purges from both old and new code will been seen by each other. When this method encounters an incompatibly versioned value at the provided key, a "variant key" will be used for reading from and saving to cache. The variant key is specific to the key and version number provided to this method. If the variant key value is older than that of the provided key, or the provided key is non-existant, then the variant key will be seen as non-existant. Therefore, delete() calls purge the provided key's variant keys. The "checkKeys" and "touchedCallback" options still apply to variant keys as usual. Avoid storing class objects, as this reduces compatibility (due to serialization). Default: null.
minAsOf: Reject values if they were generated before this UNIX timestamp. This is useful if the source of a key is suspected of having possibly changed recently, and the caller wants any such changes to be reflected. Default: WANObjectCache::MIN_TIMESTAMP_NONE.
hotTTR: Expected time-till-refresh (TTR) in seconds for keys that average ~1 hit per second (e.g. 1Hz). Keys with a hit rate higher than 1Hz will refresh sooner than this TTR and vise versa. Such refreshes won't happen until keys are "ageNew" seconds old. This uses randomization to avoid triggering cache stampedes. The TTR is useful at reducing the impact of missed cache purges, since the effect of a heavily referenced key being stale is worse than that of a rarely referenced key. Unlike simply lowering $ttl, seldomly used keys are largely unaffected by this option, which makes it possible to have a high hit rate for the "long-tail" of less-used keys. Default: WANObjectCache::HOT_TTR.
lowTTL: Consider pre-emptive updates when the current TTL (seconds) of the key is less than this. It becomes more likely over time, becoming certain once the key is expired. This helps avoid cache stampedes that might be triggered due to the key expiring. Default: WANObjectCache::LOW_TTL.
ageNew: Consider popularity refreshes only once a key reaches this age in seconds. Default: WANObjectCache::AGE_NEW.
staleTTL: Seconds to keep the key around if it is stale. This means that on cache miss the callback may get $oldValue/$oldAsOf values for keys that have already been expired for this specified time. This is useful if adaptiveTTL() is used on the old value's as-of time when it is verified as still being correct. Default: WANObjectCache::STALE_TTL_NONE
touchedCallback: A callback that takes the current value and returns a UNIX timestamp indicating the last time a dynamic dependency changed. Null can be returned if there are no relevant dependency changes to check. This can be used to check against things like last-modified times of files or DB timestamp fields. This should generally not be used for small and easily queried values in a DB if the callback itself ends up doing a similarly expensive DB query to check a timestamp. Usages of this option makes the most sense for values that are moderately to highly expensive to regenerate and easy to query for dependency timestamps. The use of "pcTTL" reduces timestamp queries. Default: null.
array
$cbParams
Custom field/value map to pass to the callback (since 1.35) @phpcs:ignore Generic.Files.LineLength
Returns
mixed Value found or written to the key
Note
Options added in 1.28: version, busyValue, hotTTR, ageNew, pcGroup, minAsOf
Options added in 1.31: staleTTL, graceTTL
Options added in 1.33: touchedCallback
Callable type hints are not used to avoid class-autoloading
Definition at line
1502
of file
WANObjectCache.php
References
makeGlobalKey()
Referenced by
getMultiWithSetCallback()
, and
getMultiWithUnionSetCallback()
hash256()
WANObjectCache::hash256
$component
Hash a possibly long string into a suitable component for makeKey()/makeGlobalKey()
Parameters
string
$component
A raw component used in building a cache key
Returns
string 64 character HMAC using a stable secret for public collision resistance
Since
1.34
Definition at line
2350
of file
WANObjectCache.php
isLotteryRefreshDue()
WANObjectCache::isLotteryRefreshDue
$res
$lowTTL
$ageNew
$hotTTR
$now
protected
Check if a key is due for randomized regeneration due to near-expiration/popularity.
Parameters
array
$res
Current value WANObjectCache::RES_* data map
float
$lowTTL
Consider a refresh when $curTTL is less than this; the "low" threshold
int
$ageNew
Age of key when this might recommend refreshing (seconds)
int
$hotTTR
Age of key when it should be refreshed if popular (seconds)
float
$now
The current UNIX timestamp
Returns
bool
Definition at line
2793
of file
WANObjectCache.php
References
$res
worthRefreshExpiring()
, and
worthRefreshPopular()
isValid()
WANObjectCache::isValid
$value
$asOf
$minAsOf
protected
Check that a wrapper value exists and has an acceptable age.
Parameters
array | false
$value
Value wrapper or false
float
$asOf
Value generation "as of" timestamp
float
$minAsOf
Minimum acceptable value "as of" UNIX timestamp
Returns
bool
Definition at line
2889
of file
WANObjectCache.php
makeGlobalKey()
WANObjectCache::makeGlobalKey
$collection
$components
Make a cache key for the global keyspace and given components.
See also
IStoreKeyEncoder::makeGlobalKey()
Parameters
string
$collection
Key collection name component
string|int
...$components Additional, ordered, key components for entity IDs
Returns
string Colon-separated, keyspace-prepended, ordered list of encoded components
Since
1.27
Implements
IStoreKeyEncoder
Definition at line
2323
of file
WANObjectCache.php
Referenced by
getWithSetCallback()
makeKey()
WANObjectCache::makeKey
$collection
$components
Make a cache key using the "global" keyspace for the given components.
See also
IStoreKeyEncoder::makeKey()
Parameters
string
$collection
Key collection name component
string|int
...$components Additional, ordered, key components for entity IDs
Returns
string Colon-separated, keyspace-prepended, ordered list of encoded components
Since
1.27
Implements
IStoreKeyEncoder
Definition at line
2338
of file
WANObjectCache.php
makeMultiKeys()
WANObjectCache::makeMultiKeys
array
$ids
$keyCallback
final
Get an iterator of (cache key => entity ID) for a list of entity IDs.
The callback takes an ID string and returns a key via makeKey()/makeGlobalKey(). There should be no network nor filesystem I/O used in the callback. The entity ID/key mapping must be 1:1 or an exception will be thrown. If hashing is needed, then use the hash256() method.
Example usage for the default keyspace:
$keyedIds =
$cache
->makeMultiKeys(
$modules
function
( $module ) use (
$cache
) {
return
$cache
->makeKey(
'module-info'
, $module );
);
$modules
$modules
Definition
HTMLFormElement.php:15
Example usage for mixed default and global keyspace:
$keyedIds =
$cache
->makeMultiKeys(
$filters,
function
( $filter ) use (
$cache
) {
return
self::isCentral( $filter )
$cache
->makeGlobalKey(
'regex-filter'
, $filter )
$cache
->makeKey(
'regex-filter'
, $filter )
);
Example usage with hashing:
$keyedIds =
$cache
->makeMultiKeys(
$urls,
function
( $url ) use (
$cache
) {
return
$cache
->makeKey(
'url-info'
$cache
->hash256( $url ) );
);
See also
WANObjectCache::makeKey()
WANObjectCache::makeGlobalKey()
WANObjectCache::hash256()
Parameters
string[] | int[]
$ids
List of entity IDs
callable
$keyCallback
Function returning makeKey()/makeGlobalKey() on the input ID
Returns
ArrayIterator Iterator of (cache key => ID); order of $ids is preserved
Since
1.28
Definition at line
2403
of file
WANObjectCache.php
multiRemap()
WANObjectCache::multiRemap
array
$ids
array
$res
final
Get an (ID => value) map from (i) a non-unique list of entity IDs, and (ii) the list of corresponding entity values by first appearance of each ID in the entity ID list.
For use with getMultiWithSetCallback() and getMultiWithUnionSetCallback().
Only
use this method if the entity ID/key mapping is trivially 1:1 without exception. Key generation method must utilize the
full
entity ID in the key (not a hash of it).
Example usage:
$poems =
$cache
->getMultiWithSetCallback(
$cache
->makeMultiKeys(
$uuids,
function ( $uuid ) use (
$cache
) {
return
$cache
->makeKey(
'poem'
, $uuid );
),
$cache::TTL_DAY,
function
( $uuid ) use ( $url ) {
return
$this->http->run( [
'method'
=>
'GET'
'url'
=>
"$url/$uuid"
] );
);
$poemsByUUID =
$cache
->multiRemap( $uuids, $poems );
See also
WANObjectCache::makeMultiKeys()
WANObjectCache::getMultiWithSetCallback()
WANObjectCache::getMultiWithUnionSetCallback()
Parameters
string[] | int[]
$ids
Entity ID list makeMultiKeys()
mixed[]
$res
Result of getMultiWithSetCallback()/getMultiWithUnionSetCallback()
Returns
mixed[] Map of (ID => value); order of $ids is preserved
Since
1.34
Definition at line
2459
of file
WANObjectCache.php
References
$res
newEmpty()
static WANObjectCache::newEmpty
static
Get an instance that wraps
EmptyBagOStuff
Returns
WANObjectCache
Definition at line
390
of file
WANObjectCache.php
prependRoute()
WANObjectCache::prependRoute
string
$sisterKey
string
$route
protected
Parameters
string
$sisterKey
string
$route
Key routing prefix
Returns
string
Definition at line
2707
of file
WANObjectCache.php
Referenced by
relayNonVolatilePurge()
, and
relayVolatilePurges()
reap()
WANObjectCache::reap
$key
$purgeTimestamp
$isStale
false
final
Set a key to soon expire in the local cluster if it pre-dates $purgeTimestamp.
This sets stale keys' time-to-live at HOLDOFF_TTL seconds, which both avoids broadcasting in mcrouter setups and also avoids races with new tombstones.
Deprecated
since 1.39 No longer supported.
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
int | float
$purgeTimestamp
UNIX timestamp of purge
bool
&$isStale
Whether the key is stale
Returns
bool Success
Since
1.28
Definition at line
2257
of file
WANObjectCache.php
References
wfDeprecated()
reapCheckKey()
WANObjectCache::reapCheckKey
$key
$purgeTimestamp
$isStale
false
final
Set a "check" key to soon expire in the local cluster if it pre-dates $purgeTimestamp.
Deprecated
since 1.39 No longer supported.
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
int
$purgeTimestamp
UNIX timestamp of purge
bool
&$isStale
Whether the key is stale
Returns
bool Success
Since
1.28
Definition at line
2291
of file
WANObjectCache.php
References
wfDeprecated()
relayNonVolatilePurge()
WANObjectCache::relayNonVolatilePurge
string
$sisterKey
protected
Remove a sister key from all datacenters.
This method should not wait for the operation to complete on remote datacenters
Parameters
string
$sisterKey
A value key or "check" key
Returns
bool Success
Definition at line
2692
of file
WANObjectCache.php
References
prependRoute()
Referenced by
delete()
, and
resetCheckKey()
relayVolatilePurges()
WANObjectCache::relayVolatilePurges
array
$purgeBySisterKey
int
$ttl
protected
Set a sister key to a purge value in all datacenters.
This method should not wait for the operation to complete on remote datacenters
Since older purge values can sometimes arrive after newer ones, use a relative expiry so that even if the older value replaces the newer value, the TTL will greater than the remaining TTL on the older value (assuming that all purges for a key use the same TTL).
Parameters
array
$purgeBySisterKey Map of (sister key => result of makeTombstonePurgeValue()/makeCheckKeyPurgeValue())
int
$ttl
Seconds to keep the purge value around
Returns
bool Success
Definition at line
2663
of file
WANObjectCache.php
References
prependRoute()
Referenced by
delete()
, and
touchCheckKey()
resetCheckKey()
WANObjectCache::resetCheckKey
$key
final
Clear the last-purge timestamp of a "check" key in all datacenters.
Similar to touchCheckKey(), in that keys fetched using get*() calls, that include the given "check" key, will be seen as purged. However, there are some differences:
a) The "check" key will be deleted from all caches and lazily re-initialized when accessed (rather than set everywhere)
b) Thus, dependent keys will be known to be stale, but not for how long (they are treated as "just" purged), which effects any lockTSE logic in getWithSetCallback()
c) Since "check" keys are initialized only on the server the key hashes to, any temporary ejection of that server will cause the value to be seen as purged as a new server will initialize the "check" key.
The advantage over touchCheckKey() is that the "check" keys, which have high TTLs, will only be created when a get*() method actually uses those keys. This is better when a large number of "check" keys must be changed in a short period of time.
Note that "check" keys won't collide with other regular keys.
See also
WANObjectCache::get()
WANObjectCache::getWithSetCallback()
WANObjectCache::touchCheckKey()
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
Returns
bool True if the item was purged or not found, false on failure
Definition at line
1189
of file
WANObjectCache.php
References
relayNonVolatilePurge()
set()
WANObjectCache::set
$key
$value
$ttl
self::TTL_INDEFINITE
array
$opts
[]
final
Set the value of a key in cache.
Simply calling this method when source data changes is not valid because the changes do not replicate to the other WAN sites. In that case, delete() should be used instead. This method is intended for use on cache misses.
If data was read using "view snapshots" (e.g. innodb REPEATABLE-READ), use 'since' to avoid the following race condition:
a) T1 starts
b) T2 updates a row, calls delete(), and commits
c) The HOLDOFF_TTL passes, expiring the delete() tombstone
d) T1 reads the row and calls set() due to a cache miss
e) Stale value is stuck in cache
Setting 'lag' and 'since' help avoids keys getting stuck in stale states.
Be aware that this does not update the process cache for getWithSetCallback() callers. Keys accessed via that method are not generally meant to also be set using this primitive method.
Consider using getWithSetCallback(), which has cache slam avoidance and key versioning features, instead of bare get()/set() calls.
Do not use this method on versioned keys accessed via getWithSetCallback().
Example usage:
$dbr
wfGetDB
DB_REPLICA
);
$setOpts = Database::getCacheSetOptions(
$dbr
);
// Fetch the row from the DB
$row =
$dbr
->selectRow( ... );
$key =
$cache
->makeKey(
'building'
, $buildingId );
$cache
->set( $key, $row, $cache::TTL_DAY, $setOpts );
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
mixed
$value
Value to set for the cache key
int
$ttl
Seconds to live. Special values are:
WANObjectCache::TTL_INDEFINITE: Cache forever (default)
WANObjectCache::TTL_UNCACHEABLE: Do not cache (if the key exists, it is not deleted)
array
$opts
Options map:
lag: Highest seconds of replication lag potentially affecting reads used to generate the value. This should not be affected by the duration of transaction "view snapshots" (e.g. innodb REPEATABLE-READ) nor the time elapsed since the first read (though both increase staleness). For reads using view snapshots, only the replication lag during snapshot initialization matters. Use false if replication is stopped/broken on a replica server involved in the reads. Default: 0 seconds
since: UNIX timestamp indicative of the highest possible staleness caused by the duration of transaction "view snapshots" (e.g. innodb REPEATABLE-READ) and the time elapsed since the first read. This should not be affected by replication lag. Default: 0 seconds
pending: Whether this data is possibly from an uncommitted write transaction. Generally, other threads should not see values from the future and they certainly should not see ones that ended up getting rolled back. Default: false
lockTSE: If excessive replication/snapshot lag is detected, then store the value with this TTL and flag it as stale. This is only useful if the reads for this key use getWithSetCallback() with "lockTSE" set. Note that if "staleTTL" is set then it will still add on to this TTL in the excessive lag scenario. Default: WANObjectCache::TSE_NONE
staleTTL: Seconds to keep the key around if it is stale. The get()/getMulti() methods return such stale values with a $curTTL of 0, and getWithSetCallback() will call the generation callback in such cases, passing in the old value and its as-of time to the callback. This is useful if adaptiveTTL() is used on the old value's as-of time when it is verified as still being correct. Default: WANObjectCache::STALE_TTL_NONE
creating: Optimize for the case where the key does not already exist. Default: false
version: Integer version number signifying the format of the value. Default: null
walltime: How long the value took to generate in seconds. Default: null @phpcs:ignore Generic.Files.LineLength
Note
Options added in 1.28: staleTTL
Options added in 1.33: creating
Options added in 1.34: version, walltime
Returns
bool Success
Definition at line
785
of file
WANObjectCache.php
References
$cache
, and
getCurrentTime()
Referenced by
MediaWiki\ResourceLoader\MessageBlobStore\recacheMessageBlob()
setLogger()
WANObjectCache::setLogger
LoggerInterface
$logger
Parameters
LoggerInterface
$logger
Definition at line
381
of file
WANObjectCache.php
Referenced by
__construct()
setMockTime()
WANObjectCache::setMockTime
$time
Parameters
float | null
&$time
Mock UNIX timestamp for testing
Definition at line
3145
of file
WANObjectCache.php
touchCheckKey()
WANObjectCache::touchCheckKey
$key
$holdoff
self::HOLDOFF_TTL
final
Increase the last-purge timestamp of a "check" key in all datacenters.
This method should only be called when some heavily referenced data changes in a significant way, such that it is impractical to call delete() on all the cache keys that should be purged. The get*() method calls used to fetch these keys must include the given "check" key in the relevant "check" keys argument/option.
A "check" key essentially represents a last-modified time of an entity. When the key is touched, the timestamp will be updated to the current time. Keys fetched using get*() calls, that include the "check" key, will be seen as purged.
The timestamp of the "check" key is treated as being HOLDOFF_TTL seconds in the future by get*() methods in order to avoid race conditions where keys are updated with stale values (e.g. from a lagged replica DB). A high TTL is set on the "check" key, making it possible to know the timestamp of the last change to the corresponding entities in most cases. This might use more cache space than resetCheckKey().
When a few important keys get a large number of hits, a high cache time is usually desired as well as "lockTSE" logic. The resetCheckKey() method is less appropriate in such cases since the "time since expiry" cannot be inferred, causing any get() after the reset to treat the key as being "hot", resulting in more stale value usage.
Note that "check" keys won't collide with other regular keys.
See also
WANObjectCache::get()
WANObjectCache::getWithSetCallback()
WANObjectCache::resetCheckKey()
Parameters
string
$key
Cache key made with makeKey()/makeGlobalKey()
int
$holdoff
HOLDOFF_TTL or HOLDOFF_TTL_NONE constant
Returns
bool True if the item was purged or not found, false on failure
Definition at line
1149
of file
WANObjectCache.php
References
getCurrentTime()
, and
relayVolatilePurges()
useInterimHoldOffCaching()
WANObjectCache::useInterimHoldOffCaching
$enabled
final
Enable or disable the use of brief caching for tombstoned keys.
When a key is purged via delete(), there normally is a period where caching is hold-off limited to an extremely short time. This method will disable that caching, forcing the callback to run for any of:
WANObjectCache::getWithSetCallback()
WANObjectCache::getMultiWithSetCallback()
WANObjectCache::getMultiWithUnionSetCallback()
This is useful when both:
a) the database used by the callback is known to be up-to-date enough for some particular purpose (e.g. replica DB has applied transaction X)
b) the caller needs to exploit that fact, and therefore needs to avoid the use of inherently volatile and possibly stale interim keys
See also
WANObjectCache::delete()
Parameters
bool
$enabled
Whether to enable interim caching
Since
1.31
Definition at line
2550
of file
WANObjectCache.php
References
useInterimHoldOffCaching()
Referenced by
useInterimHoldOffCaching()
watchErrors()
WANObjectCache::watchErrors
Get a "watch point" token that can be used to get the "last error" to occur after now.
Returns
int A token that the current error event
Since
1.38
Definition at line
2478
of file
WANObjectCache.php
worthRefreshExpiring()
WANObjectCache::worthRefreshExpiring
$curTTL
$logicalTTL
$lowTTL
protected
Check if a key is nearing expiration and thus due for randomized regeneration.
If $curTTL is greater than the "low" threshold (e.g. not nearing expiration) then this returns false. If $curTTL <= 0 (e.g. value already expired), then this returns false. Otherwise, the chance of this returning true increases steadily from 0% to 100% as $curTTL moves from the "low" threshold down to 0 seconds.
The logical TTL will be used as the "low" threshold if it is less than $lowTTL.
This method uses deadline-aware randomization in order to handle wide variations of cache access traffic without the need for configuration or expensive state.
Parameters
float
$curTTL
Approximate TTL left on the key
float
$logicalTTL
Full logical TTL assigned to the key
float
$lowTTL
Consider a refresh when $curTTL is less than this; the "low" threshold
Returns
bool
Definition at line
2863
of file
WANObjectCache.php
Referenced by
isLotteryRefreshDue()
worthRefreshPopular()
WANObjectCache::worthRefreshPopular
$asOf
$ageNew
$timeTillRefresh
$now
protected
Check if a key is due for randomized regeneration due to its popularity.
This is used so that popular keys can preemptively refresh themselves for higher consistency (especially in the case of purge loss/delay). Unpopular keys can remain in cache with their high nominal TTL. This means popular keys keep good consistency, whether the data changes frequently or not, and long-tail keys get to stay in cache and get hits too. Similar to worthRefreshExpiring(), randomization is used.
Parameters
float
$asOf
UNIX timestamp of the value
int
$ageNew
Age of key when this might recommend refreshing (seconds)
int
$timeTillRefresh
Age of key when it should be refreshed if popular (seconds)
float
$now
The current UNIX timestamp
Returns
bool
Definition at line
2819
of file
WANObjectCache.php
Referenced by
isLotteryRefreshDue()
Member Data Documentation
$asyncHandler
callable null WANObjectCache::$asyncHandler
protected
Function that takes a WAN cache callback and runs it later.
Definition at line
142
of file
WANObjectCache.php
$broadcastRoute
string null WANObjectCache::$broadcastRoute
protected
Routing prefix for operations that should be broadcasted to all data centers.
If null, the there is only one datacenter or a backend proxy broadcasts everything.
Definition at line
151
of file
WANObjectCache.php
$cache
BagOStuff
WANObjectCache::$cache
protected
The local datacenter cache.
Definition at line
134
of file
WANObjectCache.php
$coalesceScheme
int WANObjectCache::$coalesceScheme
protected
Scheme to use for key coalescing (Hash Tags or Hash Stops)
Definition at line
159
of file
WANObjectCache.php
$epoch
float WANObjectCache::$epoch
protected
Unix timestamp of the oldest possible valid values.
Definition at line
155
of file
WANObjectCache.php
$logger
LoggerInterface WANObjectCache::$logger
protected
Definition at line
138
of file
WANObjectCache.php
$processCaches
MapCacheLRU
[] WANObjectCache::$processCaches = []
protected
Map of group PHP instance caches.
Definition at line
136
of file
WANObjectCache.php
$secret
string WANObjectCache::$secret
protected
Stable secret used for hashing long strings into key components.
Definition at line
157
of file
WANObjectCache.php
$stats
StatsdDataFactoryInterface WANObjectCache::$stats
protected
Definition at line
140
of file
WANObjectCache.php
$useInterimHoldOffCaching
bool WANObjectCache::$useInterimHoldOffCaching =
true
protected
Whether to use "interim" caching while keys are tombstoned.
Definition at line
153
of file
WANObjectCache.php
GRACE_TTL_NONE
const WANObjectCache::GRACE_TTL_NONE = 0
Idiom for set()/getWithSetCallback() meaning "no post-expiration grace period".
Definition at line
202
of file
WANObjectCache.php
HOLDOFF_TTL
const WANObjectCache::HOLDOFF_TTL = self::MAX_COMMIT_DELAY + self::MAX_READ_LAG + 1
Seconds to tombstone keys on delete() and to treat keys as volatile after purges.
Definition at line
184
of file
WANObjectCache.php
HOLDOFF_TTL_NONE
const WANObjectCache::HOLDOFF_TTL_NONE = 0
Idiom for delete()/touchCheckKey() meaning "no hold-off period".
Definition at line
204
of file
WANObjectCache.php
KEY_AS_OF
const WANObjectCache::KEY_AS_OF = 'asOf'
Generation completion timestamp attribute for a key; keep value for b/c (< 1.36)
Definition at line
258
of file
WANObjectCache.php
KEY_CHECK_AS_OF
const WANObjectCache::KEY_CHECK_AS_OF = 'lastCKPurge'
Highest "check" key timestamp for a key; keep value for b/c (< 1.36)
Definition at line
266
of file
WANObjectCache.php
KEY_CUR_TTL
const WANObjectCache::KEY_CUR_TTL = 'curTTL'
Remaining TTL attribute for a key; keep value for b/c (< 1.36)
Definition at line
262
of file
WANObjectCache.php
KEY_TOMB_AS_OF
const WANObjectCache::KEY_TOMB_AS_OF = 'tombAsOf'
Tomstone timestamp attribute for a key; keep value for b/c (< 1.36)
Definition at line
264
of file
WANObjectCache.php
KEY_TTL
const WANObjectCache::KEY_TTL = 'ttl'
Logical TTL attribute for a key.
Definition at line
260
of file
WANObjectCache.php
KEY_VERSION
const WANObjectCache::KEY_VERSION = 'version'
Version
number attribute for a key; keep value for b/c (< 1.36)
Definition at line
256
of file
WANObjectCache.php
PASS_BY_REF
const WANObjectCache::PASS_BY_REF = []
Idiom for get()/getMulti() to return extra information by reference.
Definition at line
213
of file
WANObjectCache.php
STALE_TTL_NONE
const WANObjectCache::STALE_TTL_NONE = 0
Idiom for set()/getWithSetCallback() meaning "no post-expiration persistence".
Definition at line
200
of file
WANObjectCache.php
TTL_LAGGED
const WANObjectCache::TTL_LAGGED = 30
Max TTL, in seconds, to store keys when a data source has high replication lag.
Definition at line
189
of file
WANObjectCache.php
The documentation for this class was generated from the following file:
includes/libs/objectcache/wancache/
WANObjectCache.php
WANObjectCache
Generated on Mon Jan 5 2026 11:25:49 for MediaWiki by
1.10.0