From 7e12163708c11ccf8445ef1c1a6f8268639a3e4d Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Thu, 29 Apr 2021 10:28:59 -0700 Subject: [PATCH] objectcache: simplify BagOStuff::ATTR_* flags and set them for backends * Remove unused ATTR_SYNCWRITES/QOS_SYNCWRITES_* constants * Remove unused ATTR_LOCALITY/QOS_LOCALITY_* constants Bug: T279977 Change-Id: I5ada228fbd504f8e94833df8a8414ed8da0bce4b --- includes/libs/objectcache/APCUBagOStuff.php | 8 +++ includes/libs/objectcache/CachedBagOStuff.php | 1 + includes/libs/objectcache/HashBagOStuff.php | 1 - .../libs/objectcache/MemcachedBagOStuff.php | 2 +- includes/libs/objectcache/RESTBagOStuff.php | 4 +- includes/libs/objectcache/RedisBagOStuff.php | 3 +- .../libs/objectcache/WinCacheBagOStuff.php | 8 +++ .../objectcache/utils/StorageAwareness.php | 53 +++++++------------ includes/objectcache/SqlBagOStuff.php | 4 +- .../libs/objectcache/HashBagOStuffTest.php | 5 -- 10 files changed, 40 insertions(+), 49 deletions(-) diff --git a/includes/libs/objectcache/APCUBagOStuff.php b/includes/libs/objectcache/APCUBagOStuff.php index 5c0e47460fc..2ff4ce98076 100644 --- a/includes/libs/objectcache/APCUBagOStuff.php +++ b/includes/libs/objectcache/APCUBagOStuff.php @@ -59,6 +59,14 @@ class APCUBagOStuff extends MediumSpecificBagOStuff { // key before it expires should never have the end-result of purging that key. Using // the web request time becomes increasingly problematic the longer the request lasts. ini_set( 'apc.use_request_time', '0' ); + + if ( PHP_SAPI === 'cli' ) { + $this->attrMap[self::ATTR_DURABILITY] = ini_get( 'apc.enable_cli' ) + ? self::QOS_DURABILITY_SCRIPT + : self::QOS_DURABILITY_NONE; + } else { + $this->attrMap[self::ATTR_DURABILITY] = self::QOS_DURABILITY_SERVICE; + } } protected function doGet( $key, $flags = 0, &$casToken = null ) { diff --git a/includes/libs/objectcache/CachedBagOStuff.php b/includes/libs/objectcache/CachedBagOStuff.php index 4678c228632..f318190747c 100644 --- a/includes/libs/objectcache/CachedBagOStuff.php +++ b/includes/libs/objectcache/CachedBagOStuff.php @@ -51,6 +51,7 @@ class CachedBagOStuff extends BagOStuff { $this->store = $backend; $this->procCache = new HashBagOStuff( $params ); + $this->attrMap = $backend->attrMap; } diff --git a/includes/libs/objectcache/HashBagOStuff.php b/includes/libs/objectcache/HashBagOStuff.php index 217d153adba..3575a0690bc 100644 --- a/includes/libs/objectcache/HashBagOStuff.php +++ b/includes/libs/objectcache/HashBagOStuff.php @@ -64,7 +64,6 @@ class HashBagOStuff extends MediumSpecificBagOStuff { $this->maxCacheKeys = $maxKeys; $this->attrMap[self::ATTR_DURABILITY] = self::QOS_DURABILITY_SCRIPT; - $this->attrMap[self::ATTR_LOCALITY] = self::QOS_LOCALITY_PROC; } protected function doGet( $key, $flags = 0, &$casToken = null ) { diff --git a/includes/libs/objectcache/MemcachedBagOStuff.php b/includes/libs/objectcache/MemcachedBagOStuff.php index 06db15e2393..97dc66cda14 100644 --- a/includes/libs/objectcache/MemcachedBagOStuff.php +++ b/includes/libs/objectcache/MemcachedBagOStuff.php @@ -43,9 +43,9 @@ abstract class MemcachedBagOStuff extends MediumSpecificBagOStuff { $params['segmentationSize'] = $params['segmentationSize'] ?? 917504; // < 1MiB parent::__construct( $params ); - $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_BE; // unreliable $this->routingPrefix = $params['routingPrefix'] ?? ''; + // ...and does not use special disk-cache plugins $this->attrMap[self::ATTR_DURABILITY] = self::QOS_DURABILITY_SERVICE; } diff --git a/includes/libs/objectcache/RESTBagOStuff.php b/includes/libs/objectcache/RESTBagOStuff.php index c7ad1548a63..70b15f8b559 100644 --- a/includes/libs/objectcache/RESTBagOStuff.php +++ b/includes/libs/objectcache/RESTBagOStuff.php @@ -127,9 +127,7 @@ class RESTBagOStuff extends MediumSpecificBagOStuff { // Make sure URL ends with / $this->url = rtrim( $params['url'], '/' ) . '/'; - // Default config, R+W > N; no locks on reads though; writes go straight to state-machine - // TODO: What does this mean^. What is "N"? What state-machine? - $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_QC; + $this->attrMap[self::ATTR_DURABILITY] = self::QOS_DURABILITY_DISK; } public function setLogger( LoggerInterface $logger ) { diff --git a/includes/libs/objectcache/RedisBagOStuff.php b/includes/libs/objectcache/RedisBagOStuff.php index 0ac14580f1a..b6a654afcd5 100644 --- a/includes/libs/objectcache/RedisBagOStuff.php +++ b/includes/libs/objectcache/RedisBagOStuff.php @@ -85,7 +85,8 @@ class RedisBagOStuff extends MediumSpecificBagOStuff { $this->automaticFailover = $params['automaticFailover'] ?? true; - $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_NONE; + // ...and uses rdb snapshots (redis.conf default) + $this->attrMap[self::ATTR_DURABILITY] = self::QOS_DURABILITY_DISK; } protected function doGet( $key, $flags = 0, &$casToken = null ) { diff --git a/includes/libs/objectcache/WinCacheBagOStuff.php b/includes/libs/objectcache/WinCacheBagOStuff.php index c1fe8127fd6..e88305bd27f 100644 --- a/includes/libs/objectcache/WinCacheBagOStuff.php +++ b/includes/libs/objectcache/WinCacheBagOStuff.php @@ -31,6 +31,14 @@ class WinCacheBagOStuff extends MediumSpecificBagOStuff { public function __construct( array $params = [] ) { $params['segmentationSize'] = $params['segmentationSize'] ?? INF; parent::__construct( $params ); + + if ( PHP_SAPI === 'cli' ) { + $this->attrMap[self::ATTR_DURABILITY] = ini_get( 'wincache.enablecli' ) + ? self::QOS_DURABILITY_SCRIPT + : self::QOS_DURABILITY_NONE; + } else { + $this->attrMap[self::ATTR_DURABILITY] = self::QOS_DURABILITY_SERVICE; + } } protected function doGet( $key, $flags = 0, &$casToken = null ) { diff --git a/includes/libs/objectcache/utils/StorageAwareness.php b/includes/libs/objectcache/utils/StorageAwareness.php index 6878c3387aa..a566da2b719 100644 --- a/includes/libs/objectcache/utils/StorageAwareness.php +++ b/includes/libs/objectcache/utils/StorageAwareness.php @@ -30,56 +30,39 @@ namespace Wikimedia\LightweightObjectStore; * @since 1.35 */ interface StorageAwareness { - /** @var int No error */ + /** No storage medium error */ public const ERR_NONE = 0; - /** @var int No store server/medium response */ + /** Storage medium failed to yield a response */ public const ERR_NO_RESPONSE = 1; - /** @var int Cannot connect to store server/medium */ + /** Storage medium could not be reached */ public const ERR_UNREACHABLE = 2; - /** @var int Operation failed */ + /** Storage medium operation failed due to usage limitations or an I/O error */ public const ERR_UNEXPECTED = 3; - /** @var int Emulation/fallback mode; see QOS_EMULATION_*; higher is better */ + /** Emulation/fallback mode; see QOS_EMULATION_*; higher is better */ public const ATTR_EMULATION = 1; - /** @var int Multi-DC consistency of SYNC_WRITES; see QOS_SYNCWRITES_*; higher is better */ - public const ATTR_SYNCWRITES = 2; - /** @var int Locality; see QOS_LOCALITY_*; higher is better */ - public const ATTR_LOCALITY = 3; - /** @var int Durability; see QOS_DURABILITY_*; higher is better */ - public const ATTR_DURABILITY = 4; + /** Durability of writes; see QOS_DURABILITY_* (higher means stronger) */ + public const ATTR_DURABILITY = 2; - /** @var int Fallback disk-based SQL store */ + /** Fallback disk-based SQL store */ public const QOS_EMULATION_SQL = 1; - /** @var int Asynchronous; eventually consistent or even "best effort" replicated */ - public const QOS_SYNCWRITES_NONE = 1; - /** @var int Synchronous; eventually consistent or even "best effort" replicated */ - public const QOS_SYNCWRITES_BE = 2; - /** @var int Synchronous with quorum; (replicas read + replicas written) > quorum */ - public const QOS_SYNCWRITES_QC = 3; - /** @var int Synchronous; strict serializable */ - public const QOS_SYNCWRITES_SS = 4; + /** Data is stored on remote hosts and accessed via the local area network */ + public const QOS_LOCALITY_LAN = 1; + /** Data is stored on the local host and accessed via shared RAM, sockets, or filesystems */ + public const QOS_LOCALITY_SRV = 2; - /** @var int Data is replicated accross a wide area network */ - public const QOS_LOCALITY_WAN = 1; - /** @var int Data is stored on servers within the local area network */ - public const QOS_LOCALITY_LAN = 2; - /** @var int Data is stored in RAM owned by another process or in the local filesystem */ - public const QOS_LOCALITY_SRV = 3; - /** @var int Data is stored in RAM owned by this process */ - public const QOS_LOCALITY_PROC = 4; - - /** @var int Data is never saved to begin with (blackhole store) */ + /** Data is never saved to begin with (blackhole store) */ public const QOS_DURABILITY_NONE = 1; - /** @var int Data is lost at the end of the current web request or CLI script */ + /** Data is lost at the end of the current web request or CLI script */ public const QOS_DURABILITY_SCRIPT = 2; - /** @var int Data is lost once the service storing the data restarts */ + /** Data is lost once the service storing the data restarts */ public const QOS_DURABILITY_SERVICE = 3; - /** @var int Data is saved to disk, though without immediate fsync() */ + /** Data is saved to disk and writes do not usually block on fsync() */ public const QOS_DURABILITY_DISK = 4; - /** @var int Data is saved to disk via an RDBMS, usually with immediate fsync() */ + /** Data is saved to disk and writes usually block on fsync(), like a standard RDBMS */ public const QOS_DURABILITY_RDBMS = 5; - /** @var int Generic "unknown" value; useful for comparisons (always "good enough") */ + /** Generic "unknown" value; useful for comparisons (always "good enough") */ public const QOS_UNKNOWN = INF; } diff --git a/includes/objectcache/SqlBagOStuff.php b/includes/objectcache/SqlBagOStuff.php index a7eeeecb8e3..435916b35d1 100644 --- a/includes/objectcache/SqlBagOStuff.php +++ b/includes/objectcache/SqlBagOStuff.php @@ -171,7 +171,6 @@ class SqlBagOStuff extends MediumSpecificBagOStuff { $dbType = $info['type']; ++$index; } - $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_NONE; } else { // Configuration uses the servers defined in LoadBalancer instances. // Object data is vertically partitioned via global vs local keys. @@ -193,7 +192,6 @@ class SqlBagOStuff extends MediumSpecificBagOStuff { "Config requires 'server', 'servers', or 'localKeyLB'/'globalKeyLB'" ); } - $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_BE; } $this->purgePeriod = intval( $params['purgePeriod'] ?? $this->purgePeriod ); @@ -211,8 +209,8 @@ class SqlBagOStuff extends MediumSpecificBagOStuff { $this->multiPrimaryModeType = $dbType; } - $this->attrMap[self::ATTR_EMULATION] = self::QOS_EMULATION_SQL; $this->attrMap[self::ATTR_DURABILITY] = self::QOS_DURABILITY_RDBMS; + $this->attrMap[self::ATTR_EMULATION] = self::QOS_EMULATION_SQL; } protected function doGet( $key, $flags = 0, &$casToken = null ) { diff --git a/tests/phpunit/unit/includes/libs/objectcache/HashBagOStuffTest.php b/tests/phpunit/unit/includes/libs/objectcache/HashBagOStuffTest.php index 38bc8ff2ef5..df327fcdad6 100644 --- a/tests/phpunit/unit/includes/libs/objectcache/HashBagOStuffTest.php +++ b/tests/phpunit/unit/includes/libs/objectcache/HashBagOStuffTest.php @@ -28,11 +28,6 @@ class HashBagOStuffTest extends PHPUnit\Framework\TestCase { BagOStuff::QOS_DURABILITY_SCRIPT, $bag->getQoS( BagOStuff::ATTR_DURABILITY ) ); - - $this->assertSame( - BagOStuff::QOS_LOCALITY_PROC, - $bag->getQoS( BagOStuff::ATTR_LOCALITY ) - ); } /**