Replace wfGetDB with LoadBalancer in LinkCache service

Avoid use of global loadbalancer

Change-Id: I4991e9501cef4fd294d9cae197b31080ca907d45
This commit is contained in:
Umherirrender 2020-08-13 22:10:35 +02:00
parent 40ea479085
commit 0f9d316dff
3 changed files with 30 additions and 6 deletions

View file

@ -531,10 +531,15 @@ return [
},
'LinkCache' => function ( MediaWikiServices $services ) : LinkCache {
// Database layer may be disabled, so processing without database connection
$dbLoadBalancer = $services->isServiceDisabled( 'DBLoadBalancer' )
? null
: $services->getDBLoadBalancer();
return new LinkCache(
$services->getTitleFormatter(),
$services->getMainWANObjectCache(),
$services->getNamespaceInfo()
$services->getNamespaceInfo(),
$dbLoadBalancer
);
},

View file

@ -25,6 +25,7 @@ use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
use Wikimedia\Rdbms\Database;
use Wikimedia\Rdbms\IDatabase;
use Wikimedia\Rdbms\ILoadBalancer;
/**
* Cache for article titles (prefixed DB keys) and ids linked from one source
@ -48,16 +49,26 @@ class LinkCache {
/** @var NamespaceInfo */
private $nsInfo;
/** @var ILoadBalancer|null */
private $loadBalancer;
/**
* How many Titles to store. There are two caches, so the amount actually
* stored in memory can be up to twice this.
*/
private const MAX_SIZE = 10000;
/**
* @param TitleFormatter $titleFormatter
* @param WANObjectCache $cache
* @param NamespaceInfo|null $nsInfo Null for backward compatibility, but deprecated
* @param ILoadBalancer|null $loadBalancer Use null when no database is set up, for example on installation
*/
public function __construct(
TitleFormatter $titleFormatter,
WANObjectCache $cache,
NamespaceInfo $nsInfo = null
NamespaceInfo $nsInfo = null,
ILoadBalancer $loadBalancer = null
) {
if ( !$nsInfo ) {
wfDeprecated( __METHOD__ . ' with no NamespaceInfo argument', '1.34' );
@ -68,6 +79,7 @@ class LinkCache {
$this->wanCache = $cache;
$this->titleFormatter = $titleFormatter;
$this->nsInfo = $nsInfo;
$this->loadBalancer = $loadBalancer;
}
/**
@ -255,9 +267,15 @@ class LinkCache {
return 0;
}
// Only query database, when load balancer is provided by service wiring
// This maybe not happen when running as part of the installer
if ( $this->loadBalancer === null ) {
return 0;
}
// Cache template/file pages as they are less often viewed but heavily used
if ( $this->mForUpdate ) {
$row = $this->fetchPageRow( wfGetDB( DB_MASTER ), $nt );
$row = $this->fetchPageRow( $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_MASTER ), $nt );
} elseif ( $this->isCacheable( $nt ) ) {
// These pages are often transcluded heavily, so cache them
$cache = $this->wanCache;
@ -265,7 +283,7 @@ class LinkCache {
$cache->makeKey( 'page', $nt->getNamespace(), sha1( $nt->getDBkey() ) ),
$cache::TTL_DAY,
function ( $curValue, &$ttl, array &$setOpts ) use ( $cache, $nt ) {
$dbr = wfGetDB( DB_REPLICA );
$dbr = $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA );
$setOpts += Database::getCacheSetOptions( $dbr );
$row = $this->fetchPageRow( $dbr, $nt );
@ -276,7 +294,7 @@ class LinkCache {
}
);
} else {
$row = $this->fetchPageRow( wfGetDB( DB_REPLICA ), $nt );
$row = $this->fetchPageRow( $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA ), $nt );
}
if ( $row ) {

View file

@ -144,7 +144,8 @@ class LinkRendererTest extends MediaWikiLangTestCase {
$nsInfo = $services->getNamespaceInfo();
$specialPageFactory = $services->getSpecialPageFactory();
$hookContainer = $services->getHookContainer();
$linkCache = new LinkCache( $titleFormatter, $wanCache, $nsInfo );
$loadBalancer = $services->getDBLoadBalancer();
$linkCache = new LinkCache( $titleFormatter, $wanCache, $nsInfo, $loadBalancer );
$foobarTitle = new TitleValue( NS_MAIN, 'FooBar' );
$redirectTitle = new TitleValue( NS_MAIN, 'Redirect' );
$userTitle = new TitleValue( NS_USER, 'Someuser' );