From 96bc83e8ebaa69f2f4c48c1fdd06e4097a996ae6 Mon Sep 17 00:00:00 2001 From: Derick Alangi Date: Wed, 8 Sep 2021 18:19:11 +0100 Subject: [PATCH] Add BacklinkCacheFactory Service Bug: T279433 Change-Id: I2943935e2d8148fce4457f76eca0234be72a5a5a --- RELEASE-NOTES-1.37 | 2 + includes/MediaWikiServices.php | 9 +++ includes/ServiceWiring.php | 5 ++ includes/cache/BacklinkCache.php | 26 +++++--- includes/cache/BacklinkCacheFactory.php | 63 +++++++++++++++++++ .../includes/cache/BacklinkCacheTest.php | 11 ++++ .../cache/BacklinkCacheFactoryTest.php | 30 +++++++++ 7 files changed, 137 insertions(+), 9 deletions(-) create mode 100644 includes/cache/BacklinkCacheFactory.php create mode 100644 tests/phpunit/unit/includes/cache/BacklinkCacheFactoryTest.php diff --git a/RELEASE-NOTES-1.37 b/RELEASE-NOTES-1.37 index 70e80c95f5c..4dc1c151f9b 100644 --- a/RELEASE-NOTES-1.37 +++ b/RELEASE-NOTES-1.37 @@ -631,6 +631,8 @@ because of Phabricator reports. It wasn't used and job given the purpose of JobSpecification class it's not needed. * The protected method File::getImageSize() is deprecated. +* BacklinkCache::get() was deprecated, use + BacklinkCacheFactory::getBacklinkCache() instead. * MediaHandler::getImageSize(), ::getMetadata() and ::isMetadataValid were deprecated and should no longer be overridden. Instead, subclasses should override getSizeAndMetadata(). diff --git a/includes/MediaWikiServices.php b/includes/MediaWikiServices.php index d8001920e05..7a9815e86c4 100644 --- a/includes/MediaWikiServices.php +++ b/includes/MediaWikiServices.php @@ -38,6 +38,7 @@ use MediaWiki\Block\BlockUserFactory; use MediaWiki\Block\BlockUtils; use MediaWiki\Block\DatabaseBlockStore; use MediaWiki\Block\UnblockUserFactory; +use MediaWiki\Cache\BacklinkCacheFactory; use MediaWiki\Cache\LinkBatchFactory; use MediaWiki\Collation\CollationFactory; use MediaWiki\Config\ConfigRepository; @@ -607,6 +608,14 @@ class MediaWikiServices extends ServiceContainer { return $this->getService( 'AuthManager' ); } + /** + * @since 1.37 + * @return BacklinkCacheFactory + */ + public function getBacklinkCacheFactory(): BacklinkCacheFactory { + return $this->getService( 'BacklinkCacheFactory' ); + } + /** * @since 1.34 * @return BadFileLookup diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index a54a574ef8f..051e7209d1f 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -58,6 +58,7 @@ use MediaWiki\Block\BlockUtils; use MediaWiki\Block\DatabaseBlockStore; use MediaWiki\Block\UnblockUserFactory; use MediaWiki\Block\UserBlockCommandFactory; +use MediaWiki\Cache\BacklinkCacheFactory; use MediaWiki\Cache\LinkBatchFactory; use MediaWiki\Collation\CollationFactory; use MediaWiki\Config\ConfigRepository; @@ -211,6 +212,10 @@ return [ return $authManager; }, + 'BacklinkCacheFactory' => static function ( MediaWikiServices $services ): BacklinkCacheFactory { + return new BacklinkCacheFactory( $services->getMainWANObjectCache() ); + }, + 'BadFileLookup' => static function ( MediaWikiServices $services ): BadFileLookup { return new BadFileLookup( static function () { diff --git a/includes/cache/BacklinkCache.php b/includes/cache/BacklinkCache.php index 22ca1e79aea..d9b3f072dd6 100644 --- a/includes/cache/BacklinkCache.php +++ b/includes/cache/BacklinkCache.php @@ -77,9 +77,7 @@ class BacklinkCache { */ protected $fullResultCache = []; - /** - * @var WANObjectCache - */ + /** @var WANObjectCache */ protected $wanCache; /** @@ -102,11 +100,12 @@ class BacklinkCache { /** * Create a new BacklinkCache * + * @param WANObjectCache $wanCache * @param PageReference $page Page to create a backlink cache for */ - public function __construct( PageReference $page ) { + public function __construct( WANObjectCache $wanCache, PageReference $page ) { $this->page = $page; - $this->wanCache = MediaWikiServices::getInstance()->getMainWANObjectCache(); + $this->wanCache = $wanCache; } /** @@ -114,14 +113,23 @@ class BacklinkCache { * Currently, only one cache instance can exist; callers that * need multiple backlink cache objects should keep them in scope. * + * @deprecated since 1.37 Use BacklinkCacheFactory::getBacklinkCache() instead + * * @param PageReference $page Page to get a backlink cache for * @return BacklinkCache */ public static function get( PageReference $page ): self { - if ( !self::$instance || !self::$instance->page->isSamePageAs( $page ) ) { - self::$instance = new self( $page ); - } - return self::$instance; + $backlinkCacheFactory = MediaWikiServices::getInstance()->getBacklinkCacheFactory(); + + return $backlinkCacheFactory->getBacklinkCache( $page ); + } + + /** + * @since 1.37 + * @return PageReference + */ + public function getPage(): PageReference { + return $this->page; } /** diff --git a/includes/cache/BacklinkCacheFactory.php b/includes/cache/BacklinkCacheFactory.php new file mode 100644 index 00000000000..7ac0e28f074 --- /dev/null +++ b/includes/cache/BacklinkCacheFactory.php @@ -0,0 +1,63 @@ +wanCache = $wanCache; + } + + /** + * Returns a BacklinkCache for $page. May re-use previously + * created instances. + * + * Currently, only one cache instance can exist; callers that + * need multiple backlink cache objects should keep them in scope. + * + * @param PageReference $page Page to get a backlink cache for + * @return BacklinkCache + */ + public function getBacklinkCache( PageReference $page ): BacklinkCache { + if ( !$this->latestBacklinkCache || !$this->latestBacklinkCache->getPage()->isSamePageAs( $page ) ) { + $this->latestBacklinkCache = new BacklinkCache( $this->wanCache, $page ); + } + return $this->latestBacklinkCache; + } +} diff --git a/tests/phpunit/includes/cache/BacklinkCacheTest.php b/tests/phpunit/includes/cache/BacklinkCacheTest.php index fbeb7707a13..2e21f8458dd 100644 --- a/tests/phpunit/includes/cache/BacklinkCacheTest.php +++ b/tests/phpunit/includes/cache/BacklinkCacheTest.php @@ -1,5 +1,7 @@ assertTrue( self::$backlinkCacheTest['title']->isSamePageAs( $array[0] ) ); } + /** + * @covers BacklinkCache::get + */ + public function testGet() { + $page = PageReferenceValue::localReference( NS_CATEGORY, "kittens" ); + $cache = BacklinkCache::get( $page ); + $this->assertTrue( $cache->getPage()->isSamePageAs( $page ) ); + } + } diff --git a/tests/phpunit/unit/includes/cache/BacklinkCacheFactoryTest.php b/tests/phpunit/unit/includes/cache/BacklinkCacheFactoryTest.php new file mode 100644 index 00000000000..e6f782e8a67 --- /dev/null +++ b/tests/phpunit/unit/includes/cache/BacklinkCacheFactoryTest.php @@ -0,0 +1,30 @@ + new EmptyBagOStuff() ] ); + $page = PageReferenceValue::localReference( NS_CATEGORY, "kittens" ); + $factory = new BacklinkCacheFactory( $wanCache ); + $cache = $factory->getBacklinkCache( $page ); + $this->assertTrue( $cache->getPage()->isSamePageAs( $page ) ); + + $cache2 = $factory->getBacklinkCache( $page ); + $this->assertSame( $cache, $cache2 ); + + $page2 = PageReferenceValue::localReference( NS_CATEGORY, "doggos" ); + $cache2 = $factory->getBacklinkCache( $page2 ); + $this->assertNotSame( $cache, $cache2 ); + $this->assertTrue( $cache2->getPage()->isSamePageAs( $page2 ) ); + } + +}