Addshore has uploaded a new change for review.
https://gerrit.wikimedia.org/r/278596
Change subject: WatchedItemStore use Taggable PSR6 cache
......................................................................
WatchedItemStore use Taggable PSR6 cache
Depends-On: I9ccd16afa63b60b3fb3ee8c73654aac48bb7d19a
Change-Id: I3a775d77f59086b2206ccbf52d6a7bc2f471cf26
---
M composer.json
M includes/WatchedItemStore.php
M tests/phpunit/includes/WatchedItemStoreUnitTest.php
3 files changed, 72 insertions(+), 38 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/96/278596/3
diff --git a/composer.json b/composer.json
index ccb9398..e67c73d 100644
--- a/composer.json
+++ b/composer.json
@@ -16,6 +16,7 @@
"wiki": "https://www.mediawiki.org/"
},
"require": {
+ "cache/taggable-cache": "0.4.0",
"composer/semver": "1.2.0",
"cssjanus/cssjanus": "1.1.2",
"ext-iconv": "*",
diff --git a/includes/WatchedItemStore.php b/includes/WatchedItemStore.php
index 1c6053c..b44ce35 100644
--- a/includes/WatchedItemStore.php
+++ b/includes/WatchedItemStore.php
@@ -1,6 +1,7 @@
<?php
-use Psr\Cache\CacheItemPoolInterface;
+use Cache\Taggable\TaggablePoolInterface;
+use Cache\Taggable\TaggablePSR6PoolAdapter;
use Wikimedia\Assert\Assert;
/**
@@ -19,17 +20,9 @@
private $loadBalancer;
/**
- * @var CacheItemPoolInterface
+ * @var TaggablePoolInterface
*/
private $cache;
-
- /**
- * @var array[] Looks like $cacheIndex[Namespace ID][Target DB
Key][User Id] => 'key'
- * The index is needed so that on mass changes all relevant items can
be un-cached.
- * For example: Clearing a users watchlist of all items or updating
notification timestamps
- * for all users watching a single target.
- */
- private $cacheIndex = [];
/**
* @var callable|null
@@ -48,11 +41,11 @@
/**
* @param LoadBalancer $loadBalancer
- * @param CacheItemPoolInterface $cache
+ * @param TaggablePoolInterface $cache
*/
public function __construct(
LoadBalancer $loadBalancer,
- CacheItemPoolInterface $cache
+ TaggablePoolInterface $cache
) {
$this->loadBalancer = $loadBalancer;
$this->cache = $cache;
@@ -144,7 +137,11 @@
if ( !self::$instance ) {
self::$instance = new self(
wfGetLB(),
- new BagOStuffPsrCache( new HashBagOStuff( [
'maxKeys' => 100 ] ) )
+ TaggablePSR6PoolAdapter::makeTaggable(
+ new BagOStuffPsrCache(
+ new HashBagOStuff( [ 'maxKeys'
=> 100 ] )
+ )
+ )
);
}
return self::$instance;
@@ -163,23 +160,24 @@
private function cache( WatchedItem $item ) {
$user = $item->getUser();
$target = $item->getLinkTarget();
- $key = $this->getCacheKey( $user, $target );
- $this->cache->save( $this->cache->getItem( $key )->set( $item )
);
-
$this->cacheIndex[$target->getNamespace()][$target->getDBkey()][$user->getId()]
= $key;
+ $this->cache->save(
+ $this->cache->getItem( $this->getCacheKey( $user,
$target ) )
+ ->set( $item )
+ ->setTags(
+ [
+ 'user-' . $user->getId(),
+ 'target-' .
$target->getNamespace() . '-' . $target->getDBkey(),
+ ]
+ )
+ );
}
private function uncache( User $user, LinkTarget $target ) {
$this->cache->deleteItem( $this->getCacheKey( $user, $target )
);
- unset(
$this->cacheIndex[$target->getNamespace()][$target->getDBkey()][$user->getId()]
);
}
private function uncacheLinkTarget( LinkTarget $target ) {
- if ( !isset(
$this->cacheIndex[$target->getNamespace()][$target->getDBkey()] ) ) {
- return;
- }
- foreach (
$this->cacheIndex[$target->getNamespace()][$target->getDBkey()] as $key ) {
- $this->cache->deleteItem( $key );
- }
+ $this->cache->clearTags( [ 'target-' . $target->getNamespace()
. '-' . $target->getDBkey() ] );
}
/**
diff --git a/tests/phpunit/includes/WatchedItemStoreUnitTest.php
b/tests/phpunit/includes/WatchedItemStoreUnitTest.php
index 2c6b8e6..92e23f8 100644
--- a/tests/phpunit/includes/WatchedItemStoreUnitTest.php
+++ b/tests/phpunit/includes/WatchedItemStoreUnitTest.php
@@ -1,5 +1,7 @@
<?php
-use Psr\Cache\CacheItemPoolInterface;
+
+use Cache\Taggable\TaggableItemInterface;
+use Cache\Taggable\TaggablePoolInterface;
/**
* @author Addshore
@@ -32,10 +34,10 @@
}
/**
- * @return
PHPUnit_Framework_MockObject_MockObject|CacheItemPoolInterface
+ * @return PHPUnit_Framework_MockObject_MockObject|TaggablePoolInterface
*/
private function getMockCache() {
- $mock = $this->getMockBuilder( BagOStuffPsrCache::class )
+ $mock = $this->getMockBuilder( TaggablePoolInterface::class )
->disableOriginalConstructor()
->getMock();
return $mock;
@@ -45,7 +47,7 @@
* @param bool $isHit
* @param string[] $expectedMethods Method names that we want to expect
*
- * @return PHPUnit_Framework_MockObject_MockObject|BagOStuffPsrCacheItem
+ * @return PHPUnit_Framework_MockObject_MockObject|TaggableItemInterface
*/
private function getMockCacheItem( $isHit, array $expectedMethods = []
) {
$methods = [
@@ -54,8 +56,11 @@
'set',
'expiresAt',
'expiresAfter',
+ 'getTags',
+ 'setTags',
+ 'addTag',
];
- $mock = $this->getMockBuilder( BagOStuffPsrCacheItem::class )
+ $mock = $this->getMockBuilder( TaggableItemInterface::class )
->disableOriginalConstructor()
->getMock();
$mock->expects( $this->any() )
@@ -70,7 +75,7 @@
/**
* @param string[] $expectedMethods Method names that we want to expect
*
- * @return
PHPUnit_Framework_MockObject_MockObject|CacheItemPoolInterface
+ * @return PHPUnit_Framework_MockObject_MockObject|TaggablePoolInterface
*/
private function getMockCacheWithNoExpectedCalls( array
$expectedMethods = [] ) {
$methods =
@@ -84,6 +89,7 @@
'save',
'saveDeferred',
'commit',
+ 'clearTags',
];
$mockCache = $this->getMockCache();
foreach ( array_diff( $methods, $expectedMethods ) as $method )
{
@@ -1052,10 +1058,14 @@
$this->getFakeRow( [ 'wl_notificationtimestamp'
=> '20151212010101' ] )
) );
- $mockCacheItem = $this->getMockCacheItem( false, [ 'set' ] );
+ $mockCacheItem = $this->getMockCacheItem( false, [ 'set',
'setTags' ] );
$mockCacheItem->expects( $this->once() )
->method( 'set' )
->with( $this->isInstanceOf( WatchedItem::class ) )
+ ->will( $this->returnValue( $mockCacheItem ) );
+ $mockCacheItem->expects( $this->once() )
+ ->method( 'setTags' )
+ ->with( [ 'user-1', 'target-0-SomeDbKey' ] )
->will( $this->returnValue( $mockCacheItem ) );
$mockCache = $this->getMockCache();
@@ -1248,10 +1258,14 @@
$this->getFakeRow( [ 'wl_notificationtimestamp'
=> '20151212010101' ] )
) );
- $mockCacheItem = $this->getMockCacheItem( false, [ 'set' ] );
+ $mockCacheItem = $this->getMockCacheItem( false, [ 'set',
'setTags' ] );
$mockCacheItem->expects( $this->once() )
->method( 'set' )
->with( $this->isInstanceOf( WatchedItem::class ) )
+ ->will( $this->returnValue( $mockCacheItem ) );
+ $mockCacheItem->expects( $this->once() )
+ ->method( 'setTags' )
+ ->with( [ 'user-1', 'target-0-SomeDbKey' ] )
->will( $this->returnValue( $mockCacheItem ) );
$mockCache = $this->getMockCache();
@@ -1389,10 +1403,14 @@
$this->getFakeRow( [ 'wl_notificationtimestamp'
=> '20151212010101' ] )
) );
- $mockCacheItem = $this->getMockCacheItem( false, [ 'set' ] );
+ $mockCacheItem = $this->getMockCacheItem( false, [ 'set',
'setTags' ] );
$mockCacheItem->expects( $this->once() )
->method( 'set' )
->with( $this->isInstanceOf( WatchedItem::class ) )
+ ->will( $this->returnValue( $mockCacheItem ) );
+ $mockCacheItem->expects( $this->once() )
+ ->method( 'setTags' )
+ ->with( [ 'user-1', 'target-0-SomeDbKey' ] )
->will( $this->returnValue( $mockCacheItem ) );
$mockCache = $this->getMockCache();
@@ -1540,10 +1558,14 @@
$this->getFakeRow( [ 'wl_notificationtimestamp'
=> '20151212010101' ] )
) );
- $mockCacheItem = $this->getMockCacheItem( false, [ 'set' ] );
+ $mockCacheItem = $this->getMockCacheItem( false, [ 'set',
'setTags' ] );
$mockCacheItem->expects( $this->once() )
->method( 'set' )
->with( $this->isInstanceOf( WatchedItem::class ) )
+ ->will( $this->returnValue( $mockCacheItem ) );
+ $mockCacheItem->expects( $this->once() )
+ ->method( 'setTags' )
+ ->with( [ 'user-1', 'target-0-SomeDbKey' ] )
->will( $this->returnValue( $mockCacheItem ) );
$mockCache = $this->getMockCache();
@@ -1699,10 +1721,14 @@
$this->getFakeRow( [ 'wl_notificationtimestamp'
=> '20151212010101' ] )
) );
- $mockCacheItem = $this->getMockCacheItem( false, [ 'set' ] );
+ $mockCacheItem = $this->getMockCacheItem( false, [ 'set',
'setTags' ] );
$mockCacheItem->expects( $this->once() )
->method( 'set' )
->with( $this->isInstanceOf( WatchedItem::class ) )
+ ->will( $this->returnValue( $mockCacheItem ) );
+ $mockCacheItem->expects( $this->once() )
+ ->method( 'setTags' )
+ ->with( [ 'user-1', 'target-0-SomeDbKey' ] )
->will( $this->returnValue( $mockCacheItem ) );
$mockCache = $this->getMockCacheWithNoExpectedCalls( [
'getItem', 'save', 'deleteItem' ] );
@@ -1793,9 +1819,14 @@
]
);
+ $mockCache = $this->getMockCache();
+ $mockCache->expects( $this->once() )
+ ->method( 'clearTags' )
+ ->with( [ 'target-0-SomeDbKey' ] );
+
$store = new WatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
- $this->getMockCacheWithNoExpectedCalls()
+ $mockCache
);
$this->assertEquals(
@@ -1871,10 +1902,14 @@
$mockDb->expects( $this->once() )
->method( 'update' );
- $mockCacheItem = $this->getMockCacheItem( false, [ 'set' ] );
+ $mockCacheItem = $this->getMockCacheItem( false, [ 'set',
'setTags' ] );
$mockCacheItem->expects( $this->once() )
->method( 'set' )
->with( $this->isInstanceOf( WatchedItem::class ) )
+ ->will( $this->returnValue( $mockCacheItem ) );
+ $mockCacheItem->expects( $this->once() )
+ ->method( 'setTags' )
+ ->with( [ 'user-1', 'target-0-SomeDbKey' ] )
->will( $this->returnValue( $mockCacheItem ) );
$mockCache = $this->getMockCache();
@@ -1886,8 +1921,8 @@
->method( 'save' )
->with( $mockCacheItem );
$mockCache->expects( $this->once() )
- ->method( 'deleteItem' )
- ->with( '0|SomeDbKey|1' );
+ ->method( 'clearTags' )
+ ->with( [ 'target-0-SomeDbKey' ] );
$store = new WatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
--
To view, visit https://gerrit.wikimedia.org/r/278596
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3a775d77f59086b2206ccbf52d6a7bc2f471cf26
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Addshore <[email protected]>
Gerrit-Reviewer: Addshore <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits