X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Flibs%2Fobjectcache%2FWANObjectCache.php;h=658b225b44fed3b49cadbdd852ab362871e94741;hp=d9398196f5d4d9d03c45f0f0ee4a55a3d62f1ae8;hb=631e8695b15412ec16c31623cbd6e5aa3d6efb1e;hpb=a9f438227050c1fac6efe91fa8ff38947ae7c089 diff --git a/includes/libs/objectcache/WANObjectCache.php b/includes/libs/objectcache/WANObjectCache.php index d9398196f5..658b225b44 100644 --- a/includes/libs/objectcache/WANObjectCache.php +++ b/includes/libs/objectcache/WANObjectCache.php @@ -118,6 +118,9 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { /** @var int Key fetched */ private $warmupKeyMisses = 0; + /** @var float|null */ + private $wallClockOverride; + /** Max time expected to pass between delete() and DB commit finishing */ const MAX_COMMIT_DELAY = 3; /** Max replication+snapshot lag before applying TTL_LAGGED or disallowing set() */ @@ -134,8 +137,6 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { const LOCK_TTL = 10; /** Default remaining TTL at which to consider pre-emptive regeneration */ const LOW_TTL = 30; - /** Default time-since-expiry on a miss that makes a key "hot" */ - const LOCK_TSE = 1; /** Never consider performing "popularity" refreshes until a key reaches this age */ const AGE_NEW = 60; @@ -284,7 +285,8 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { * (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 delete() hold-off TTL + * - 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. @@ -518,18 +520,18 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { // Case B: any long-running transaction; ignore this set() } elseif ( $age > self::MAX_READ_LAG ) { $this->logger->info( 'Rejected set() for {cachekey} due to snapshot lag.', - [ 'cachekey' => $key ] ); + [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ] ); return true; // no-op the write for being unsafe // Case C: high replication lag; lower TTL instead of ignoring all set()s } elseif ( $lag === false || $lag > self::MAX_READ_LAG ) { $ttl = $ttl ? min( $ttl, self::TTL_LAGGED ) : self::TTL_LAGGED; $this->logger->warning( 'Lowered set() TTL for {cachekey} due to replication lag.', - [ 'cachekey' => $key ] ); + [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ] ); // Case D: medium length request with medium replication lag; ignore this set() } else { $this->logger->info( 'Rejected set() for {cachekey} due to high read lag.', - [ 'cachekey' => $key ] ); + [ 'cachekey' => $key, 'lag' => $lag, 'age' => $age ] ); return true; // no-op the write for being unsafe } @@ -1537,7 +1539,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { } /** - * Locally set a key to expire soon if it is stale based on $purgeTimestamp + * 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. @@ -1569,7 +1571,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { } /** - * Locally set a "check" key to expire soon if it is stale based on $purgeTimestamp + * Set a "check" key to soon expire in the local cluster if it pre-dates $purgeTimestamp * * @param string $key Cache key * @param int $purgeTimestamp UNIX timestamp of purge @@ -1582,7 +1584,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { if ( $purge && $purge[self::FLD_TIME] < $purgeTimestamp ) { $isStale = true; $this->logger->warning( "Reaping stale check key '$key'." ); - $ok = $this->cache->changeTTL( self::TIME_KEY_PREFIX . $key, 1 ); + $ok = $this->cache->changeTTL( self::TIME_KEY_PREFIX . $key, self::TTL_SECOND ); if ( !$ok ) { $this->logger->error( "Could not complete reap of check key '$key'." ); } @@ -1825,7 +1827,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { 'cmd' => 'set', 'key' => $key, 'val' => 'PURGED:$UNIXTIME$:' . (int)$holdoff, - 'ttl' => max( $ttl, 1 ), + 'ttl' => max( $ttl, self::TTL_SECOND ), 'sbt' => true, // substitute $UNIXTIME$ with actual microtime ] ); @@ -2065,14 +2067,6 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { return isset( $parts[1] ) ? $parts[1] : $parts[0]; // sanity } - /** - * @return float UNIX timestamp - * @codeCoverageIgnore - */ - protected function getCurrentTime() { - return microtime( true ); - } - /** * @param string $value Wrapped value like "PURGED::" * @return array|bool Array containing a UNIX timestamp (float) and holdoff period (integer), @@ -2174,4 +2168,21 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface { return $warmupCache; } + + /** + * @return float UNIX timestamp + * @codeCoverageIgnore + */ + protected function getCurrentTime() { + return $this->wallClockOverride ?: microtime( true ); + } + + /** + * @param float|null &$time Mock UNIX timestamp for testing + * @codeCoverageIgnore + */ + public function setMockTime( &$time ) { + $this->wallClockOverride =& $time; + $this->cache->setMockTime( $time ); + } }