From: jenkins-bot Date: Thu, 29 Aug 2019 18:06:28 +0000 (+0000) Subject: Merge "HashRing optimizations and PhpStorm warning work-arounds" X-Git-Tag: 1.34.0-rc.0~497 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/exercices/modifier.php?a=commitdiff_plain;h=784dc57710c7ec7124b13471ae43f4a8ac11e0c1;hp=7f2da3affc06cf1be0b79c586875b660808bd068;p=lhc%2Fweb%2Fwiklou.git Merge "HashRing optimizations and PhpStorm warning work-arounds" --- diff --git a/RELEASE-NOTES-1.34 b/RELEASE-NOTES-1.34 index f7790cb628..e57dacc498 100644 --- a/RELEASE-NOTES-1.34 +++ b/RELEASE-NOTES-1.34 @@ -81,6 +81,7 @@ For notes on 1.33.x and older releases, see HISTORY. password setups and deprecated since 1.24, is now removed. * $wgDBOracleDRCP - If you must use persistent connections, set DBO_PERSISTENT in the 'flags' field for servers in $wgDBServers (or $wgLBFactoryConf). +* $wgMemCachedDebug - Set the cache "debug" field in $wgObjectCaches instead. === New user-facing features in 1.34 === * Special:Mute has been added as a quick way for users to block unwanted emails diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 93a59190c4..9577a481d3 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -2554,11 +2554,6 @@ $wgPHPSessionHandling = 'enable'; */ $wgSessionPbkdf2Iterations = 10001; -/** - * If enabled, will send MemCached debugging information to $wgDebugLogFile - */ -$wgMemCachedDebug = false; - /** * The list of MemCached servers and port numbers */ diff --git a/includes/db/MWLBFactory.php b/includes/db/MWLBFactory.php index 80eb2f70fb..18030090df 100644 --- a/includes/db/MWLBFactory.php +++ b/includes/db/MWLBFactory.php @@ -66,7 +66,7 @@ abstract class MWLBFactory { * @param array $lbConf Config for LBFactory::__construct() * @param ServiceOptions $options * @param ConfiguredReadOnlyMode $readOnlyMode - * @param BagOStuff $srvCace + * @param BagOStuff $srvCache * @param BagOStuff $mainStash * @param WANObjectCache $wanCache * @return array @@ -76,7 +76,7 @@ abstract class MWLBFactory { array $lbConf, ServiceOptions $options, ConfiguredReadOnlyMode $readOnlyMode, - BagOStuff $srvCace, + BagOStuff $srvCache, BagOStuff $mainStash, WANObjectCache $wanCache ) { @@ -159,7 +159,7 @@ abstract class MWLBFactory { $options->get( 'DBprefix' ) ); - $lbConf = self::injectObjectCaches( $lbConf, $srvCace, $mainStash, $wanCache ); + $lbConf = self::injectObjectCaches( $lbConf, $srvCache, $mainStash, $wanCache ); return $lbConf; } @@ -222,6 +222,11 @@ abstract class MWLBFactory { private static function injectObjectCaches( array $lbConf, BagOStuff $sCache, BagOStuff $mStash, WANObjectCache $wCache ) { + // Fallback if APC style caching is not an option + if ( $sCache instanceof EmptyBagOStuff ) { + $sCache = new HashBagOStuff( [ 'maxKeys' => 100 ] ); + } + // Use APC/memcached style caching, but avoids loops with CACHE_DB (T141804) if ( $sCache->getQoS( $sCache::ATTR_EMULATION ) > $sCache::QOS_EMULATION_SQL ) { $lbConf['srvCache'] = $sCache; diff --git a/includes/libs/filebackend/FSFileBackend.php b/includes/libs/filebackend/FSFileBackend.php index c05dc286c8..c1a796f75a 100644 --- a/includes/libs/filebackend/FSFileBackend.php +++ b/includes/libs/filebackend/FSFileBackend.php @@ -593,7 +593,7 @@ class FSFileBackend extends FileBackendStore { } elseif ( !$hadError ) { return false; // file does not exist } else { - return null; // failure + return self::UNKNOWN; // failure } } @@ -610,7 +610,7 @@ class FSFileBackend extends FileBackendStore { $exists = is_dir( $dir ); $hadError = $this->untrapWarnings(); - return $hadError ? null : $exists; + return $hadError ? self::UNKNOWN : $exists; } /** @@ -632,7 +632,7 @@ class FSFileBackend extends FileBackendStore { } elseif ( !is_readable( $dir ) ) { $this->logger->warning( __METHOD__ . "() given directory is unreadable: '$dir'\n" ); - return null; // bad permissions? + return self::UNKNOWN; // bad permissions? } return new FSFileBackendDirList( $dir, $params ); @@ -657,7 +657,7 @@ class FSFileBackend extends FileBackendStore { } elseif ( !is_readable( $dir ) ) { $this->logger->warning( __METHOD__ . "() given directory is unreadable: '$dir'\n" ); - return null; // bad permissions? + return self::UNKNOWN; // bad permissions? } return new FSFileBackendFileList( $dir, $params ); diff --git a/includes/libs/filebackend/FileBackend.php b/includes/libs/filebackend/FileBackend.php index 4cacb7af63..905e925c40 100644 --- a/includes/libs/filebackend/FileBackend.php +++ b/includes/libs/filebackend/FileBackend.php @@ -131,6 +131,9 @@ abstract class FileBackend implements LoggerAwareInterface { const ATTR_METADATA = 2; // files can be stored with metadata key/values const ATTR_UNICODE_PATHS = 4; // files can have Unicode paths (not just ASCII) + /** @var null Idiom for "could not determine due to I/O errors" */ + const UNKNOWN = null; + /** * Create a new backend instance from configuration. * This should only be called from within FileBackendGroup. @@ -209,7 +212,8 @@ abstract class FileBackend implements LoggerAwareInterface { } /** - * Get the unique backend name. + * Get the unique backend name + * * We may have multiple different backends of the same type. * For example, we can have two Swift backends using different proxies. * @@ -231,6 +235,7 @@ abstract class FileBackend implements LoggerAwareInterface { /** * Alias to getDomainId() + * * @return string * @since 1.20 * @deprecated Since 1.34 Use getDomainId() @@ -1164,21 +1169,34 @@ abstract class FileBackend implements LoggerAwareInterface { abstract public function getFileHttpUrl( array $params ); /** - * Check if a directory exists at a given storage path. - * Backends using key/value stores will check if the path is a - * virtual directory, meaning there are files under the given directory. + * Check if a directory exists at a given storage path + * + * For backends using key/value stores, a directory is said to exist whenever + * there exist any files with paths using the given directory path as a prefix + * followed by a forward slash. For example, if there is a file called + * "mwstore://backend/container/dir/path.svg" then directories are said to exist + * at "mwstore://backend/container" and "mwstore://backend/container/dir". These + * can be thought of as "virtual" directories. + * + * Backends that directly use a filesystem layer might enumerate empty directories. + * The clean() method should always be used when files are deleted or moved if this + * is a concern. This is a trade-off to avoid write amplication/contention on file + * changes or read amplification when calling this method. * * Storage backends with eventual consistency might return stale data. * + * @see FileBackend::clean() + * * @param array $params Parameters include: * - dir : storage directory - * @return bool|null Returns null on failure + * @return bool|null Whether a directory exists or null on failure * @since 1.20 */ abstract public function directoryExists( array $params ); /** - * Get an iterator to list *all* directories under a storage directory. + * Get an iterator to list *all* directories under a storage directory + * * If the directory is of the form "mwstore://backend/container", * then all directories in the container will be listed. * If the directory is of form "mwstore://backend/container/dir", @@ -1189,10 +1207,12 @@ abstract class FileBackend implements LoggerAwareInterface { * * Failures during iteration can result in FileBackendError exceptions (since 1.22). * + * @see FileBackend::directoryExists() + * * @param array $params Parameters include: * - dir : storage directory * - topOnly : only return direct child dirs of the directory - * @return Traversable|array|null Returns null on failure + * @return Traversable|array|null Directory list enumerator null on failure * @since 1.20 */ abstract public function getDirectoryList( array $params ); @@ -1205,9 +1225,11 @@ abstract class FileBackend implements LoggerAwareInterface { * * Failures during iteration can result in FileBackendError exceptions (since 1.22). * + * @see FileBackend::directoryExists() + * * @param array $params Parameters include: * - dir : storage directory - * @return Traversable|array|null Returns null on failure + * @return Traversable|array|null Directory list enumerator or null on failure * @since 1.20 */ final public function getTopDirectoryList( array $params ) { @@ -1215,12 +1237,12 @@ abstract class FileBackend implements LoggerAwareInterface { } /** - * Get an iterator to list *all* stored files under a storage directory. - * If the directory is of the form "mwstore://backend/container", - * then all files in the container will be listed. - * If the directory is of form "mwstore://backend/container/dir", - * then all files under that directory will be listed. - * Results will be storage paths relative to the given directory. + * Get an iterator to list *all* stored files under a storage directory + * + * If the directory is of the form "mwstore://backend/container", then all + * files in the container will be listed. If the directory is of form + * "mwstore://backend/container/dir", then all files under that directory will + * be listed. Results will be storage paths relative to the given directory. * * Storage backends with eventual consistency might return stale data. * @@ -1230,7 +1252,7 @@ abstract class FileBackend implements LoggerAwareInterface { * - dir : storage directory * - topOnly : only return direct child files of the directory (since 1.20) * - adviseStat : set to true if stat requests will be made on the files (since 1.22) - * @return Traversable|array|null Returns null on failure + * @return Traversable|array|null File list enumerator or null on failure */ abstract public function getFileList( array $params ); @@ -1245,7 +1267,7 @@ abstract class FileBackend implements LoggerAwareInterface { * @param array $params Parameters include: * - dir : storage directory * - adviseStat : set to true if stat requests will be made on the files (since 1.22) - * @return Traversable|array|null Returns null on failure + * @return Traversable|array|null File list enumerator or null on failure * @since 1.20 */ final public function getTopFileList( array $params ) { @@ -1283,7 +1305,7 @@ abstract class FileBackend implements LoggerAwareInterface { * @param array $params Parameters include: * - srcs : list of source storage paths * - latest : use the latest available data - * @return bool All requests proceeded without I/O errors (since 1.24) + * @return bool Whether all requests proceeded without I/O errors (since 1.24) * @since 1.23 */ abstract public function preloadFileStat( array $params ); @@ -1526,7 +1548,7 @@ abstract class FileBackend implements LoggerAwareInterface { * * @param string $type One of (attachment, inline) * @param string $filename Suggested file name (should not contain slashes) - * @throws FileBackendError + * @throws InvalidArgumentException * @return string * @since 1.20 */ diff --git a/includes/libs/filebackend/FileBackendStore.php b/includes/libs/filebackend/FileBackendStore.php index aa95ee40bf..9b901dd1d1 100644 --- a/includes/libs/filebackend/FileBackendStore.php +++ b/includes/libs/filebackend/FileBackendStore.php @@ -604,7 +604,7 @@ abstract class FileBackendStore extends FileBackend { $ps = $this->scopedProfileSection( __METHOD__ . "-{$this->name}" ); $stat = $this->getFileStat( $params ); - return ( $stat === null ) ? null : (bool)$stat; // null => failure + return ( $stat === self::UNKNOWN ) ? self::UNKNOWN : (bool)$stat; } final public function getFileTimestamp( array $params ) { @@ -637,7 +637,7 @@ abstract class FileBackendStore extends FileBackend { // cache entries from mass object listings that do not include the SHA-1. In that // case, loading the persistent stat cache will likely yield the SHA-1. if ( - $stat === null || + $stat === self::UNKNOWN || ( $requireSHA1 && is_array( $stat ) && !isset( $stat['sha1'] ) ) ) { $this->primeFileCache( [ $path ] ); // check persistent cache @@ -936,7 +936,7 @@ abstract class FileBackendStore extends FileBackend { $res = true; break; // found one! } elseif ( $exists === null ) { // error? - $res = null; // if we don't find anything, it is indeterminate + $res = self::UNKNOWN; // if we don't find anything, it is indeterminate } } @@ -957,7 +957,7 @@ abstract class FileBackendStore extends FileBackend { final public function getDirectoryList( array $params ) { list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] ); if ( $dir === null ) { // invalid storage path - return null; + return self::UNKNOWN; } if ( $shard !== null ) { // File listing is confined to a single container/shard @@ -987,7 +987,7 @@ abstract class FileBackendStore extends FileBackend { final public function getFileList( array $params ) { list( $fullCont, $dir, $shard ) = $this->resolveStoragePath( $params['dir'] ); if ( $dir === null ) { // invalid storage path - return null; + return self::UNKNOWN; } if ( $shard !== null ) { // File listing is confined to a single container/shard diff --git a/includes/libs/filebackend/MemoryFileBackend.php b/includes/libs/filebackend/MemoryFileBackend.php index f0cbf3bbcd..88b281e380 100644 --- a/includes/libs/filebackend/MemoryFileBackend.php +++ b/includes/libs/filebackend/MemoryFileBackend.php @@ -148,7 +148,7 @@ class MemoryFileBackend extends FileBackendStore { protected function doGetFileStat( array $params ) { $src = $this->resolveHashKey( $params['src'] ); if ( $src === null ) { - return null; + return false; // invalid path } if ( isset( $this->files[$src] ) ) { diff --git a/includes/libs/filebackend/SwiftFileBackend.php b/includes/libs/filebackend/SwiftFileBackend.php index afd1688c1c..e576c6429e 100644 --- a/includes/libs/filebackend/SwiftFileBackend.php +++ b/includes/libs/filebackend/SwiftFileBackend.php @@ -593,7 +593,7 @@ class SwiftFileBackend extends FileBackendStore { $stat = $this->getContainerStat( $fullCont ); if ( is_array( $stat ) ) { return $status; // already there - } elseif ( $stat === null ) { + } elseif ( $stat === self::UNKNOWN ) { $status->fatal( 'backend-fail-internal', $this->name ); $this->logger->error( __METHOD__ . ': cannot get container stat' ); @@ -832,7 +832,7 @@ class SwiftFileBackend extends FileBackendStore { return ( count( $status->value ) ) > 0; } - return null; // error + return self::UNKNOWN; // error } /** @@ -1401,7 +1401,7 @@ class SwiftFileBackend extends FileBackendStore { if ( !$this->containerStatCache->hasField( $container, 'stat' ) ) { $auth = $this->getAuthentication(); if ( !$auth ) { - return null; + return self::UNKNOWN; } list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( [ @@ -1427,7 +1427,7 @@ class SwiftFileBackend extends FileBackendStore { $this->onError( null, __METHOD__, [ 'cont' => $container ], $rerr, $rcode, $rdesc ); - return null; + return self::UNKNOWN; } } @@ -1599,7 +1599,7 @@ class SwiftFileBackend extends FileBackendStore { $stats[$path] = false; continue; // invalid storage path } elseif ( !$auth ) { - $stats[$path] = null; + $stats[$path] = self::UNKNOWN; continue; } @@ -1609,7 +1609,7 @@ class SwiftFileBackend extends FileBackendStore { $stats[$path] = false; continue; // ok, nothing to do } elseif ( !is_array( $cstat ) ) { - $stats[$path] = null; + $stats[$path] = self::UNKNOWN; continue; } @@ -1642,7 +1642,7 @@ class SwiftFileBackend extends FileBackendStore { } elseif ( $rcode === 404 ) { $stat = false; } else { - $stat = null; + $stat = self::UNKNOWN; $this->onError( null, __METHOD__, $params, $rerr, $rcode, $rdesc ); } $stats[$path] = $stat; diff --git a/includes/objectcache/ObjectCache.php b/includes/objectcache/ObjectCache.php index ad0f67e590..8ffe824f79 100644 --- a/includes/objectcache/ObjectCache.php +++ b/includes/objectcache/ObjectCache.php @@ -204,9 +204,6 @@ class ObjectCache { if ( !isset( $params['servers'] ) ) { $params['servers'] = $GLOBALS['wgMemCachedServers']; } - if ( !isset( $params['debug'] ) ) { - $params['debug'] = $GLOBALS['wgMemCachedDebug']; - } if ( !isset( $params['persistent'] ) ) { $params['persistent'] = $GLOBALS['wgMemCachedPersistent']; } @@ -393,12 +390,19 @@ class ObjectCache { */ public static function detectLocalServerCache() { if ( function_exists( 'apcu_fetch' ) ) { - return 'apcu'; + // Make sure the APCu methods actually store anything + if ( PHP_SAPI !== 'cli' || ini_get( 'apc.enable_cli' ) ) { + return 'apcu'; + } } elseif ( function_exists( 'apc_fetch' ) ) { - return 'apc'; + // Make sure the APC methods actually store anything + if ( PHP_SAPI !== 'cli' || ini_get( 'apc.enable_cli' ) ) { + return 'apc'; + } } elseif ( function_exists( 'wincache_ucache_get' ) ) { return 'wincache'; } + return CACHE_NONE; } }