Addshore has uploaded a new change for review.
https://gerrit.wikimedia.org/r/282121
Change subject: PSR-6 WANObjectCache wrapper
......................................................................
PSR-6 WANObjectCache wrapper
Change-Id: Ia2dd8b62deebf72901ba7676455fcf2394803116
---
M includes/libs/objectcache/BagOStuffPsrCache.php
R includes/libs/objectcache/MediaWikiPsrCacheInvalidArgumentException.php
R includes/libs/objectcache/MediaWikiPsrCacheItem.php
R includes/libs/objectcache/MediawikiPsrCacheException.php
A includes/libs/objectcache/WANObjectPsrCache.php
M tests/phpunit/includes/libs/objectcache/BagOStuffPsrCacheTest.php
A tests/phpunit/includes/libs/objectcache/WANObjectPsrCacheTest.php
7 files changed, 331 insertions(+), 14 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/21/282121/1
diff --git a/includes/libs/objectcache/BagOStuffPsrCache.php
b/includes/libs/objectcache/BagOStuffPsrCache.php
index aa8723a..0e39202 100644
--- a/includes/libs/objectcache/BagOStuffPsrCache.php
+++ b/includes/libs/objectcache/BagOStuffPsrCache.php
@@ -66,20 +66,20 @@
/**
* @param mixed $key
*
- * @throws BagOStuffPsrCacheInvalidArgumentException
+ * @throws MediaWikiPsrCacheInvalidArgumentException
*/
private function throwExceptionOnBadKey( $key ) {
if ( !is_string( $key ) ) {
- throw new BagOStuffPsrCacheInvalidArgumentException(
'$key must be a string' );
+ throw new MediaWikiPsrCacheInvalidArgumentException(
'$key must be a string' );
}
// Make sure nothing uses the same key as our key list
if ( $key === $this->getKeyListKey() ) {
- throw new BagOStuffPsrCacheInvalidArgumentException(
'$key value is reserved' );
+ throw new MediaWikiPsrCacheInvalidArgumentException(
'$key value is reserved' );
}
// Valid key according to PSR-6 rules
$invalid = preg_quote( static::INVALID_KEY_CHARACTERS, '/' );
if ( preg_match( '/[' . $invalid . ']/', $key ) ) {
- throw new BagOStuffPsrCacheInvalidArgumentException(
+ throw new MediaWikiPsrCacheInvalidArgumentException(
'Invalid key: ' . $key . '. Contains (a)
character(s) reserved ' .
'for future extension: ' .
static::INVALID_KEY_CHARACTERS
);
@@ -107,10 +107,10 @@
$item = $this->bagOStuff->get( $key );
if ( $item === false ) {
- return new BagOStuffPsrCacheItem( $key, null, false );
+ return new MediaWikiPsrCacheItem( $key, null, false );
}
- return new BagOStuffPsrCacheItem( $key, $item, true );
+ return new MediaWikiPsrCacheItem( $key, $item, true );
}
/**
@@ -226,17 +226,17 @@
*
* @return bool True if the item was successfully persisted. False if
there was an error.
* True if the item was successfully persisted. False if there was an
error.
- * @throws BagOStuffPsrCacheException as BagOStuffs can not
differentiate between a false
+ * @throws MediaWikiPsrCacheException as BagOStuffs can not
differentiate between a false
* value and an un-cached value
*/
public function save( CacheItemInterface $item ) {
- if ( !$item instanceof BagOStuffPsrCacheItem ) {
- throw new BagOStuffPsrCacheInvalidArgumentException(
+ if ( !$item instanceof MediaWikiPsrCacheItem ) {
+ throw new MediaWikiPsrCacheInvalidArgumentException(
__CLASS__ . ' can only save
BagOStuffPsrCacheItem objects'
);
}
if ( $item->get() === false ) {
- throw new BagOStuffPsrCacheException( __CLASS__ . ' can
not cache false' );
+ throw new MediaWikiPsrCacheException( __CLASS__ . ' can
not cache false' );
}
$exptime = 0;
diff --git
a/includes/libs/objectcache/BagOStuffPsrCacheInvalidArgumentException.php
b/includes/libs/objectcache/MediaWikiPsrCacheInvalidArgumentException.php
similarity index 65%
rename from
includes/libs/objectcache/BagOStuffPsrCacheInvalidArgumentException.php
rename to
includes/libs/objectcache/MediaWikiPsrCacheInvalidArgumentException.php
index c623bd0..f26d48a 100644
--- a/includes/libs/objectcache/BagOStuffPsrCacheInvalidArgumentException.php
+++ b/includes/libs/objectcache/MediaWikiPsrCacheInvalidArgumentException.php
@@ -9,7 +9,7 @@
*
* @since 1.27
*/
-class BagOStuffPsrCacheInvalidArgumentException extends
BagOStuffPsrCacheException
+class MediaWikiPsrCacheInvalidArgumentException extends
MediaWikiPsrCacheException
implements InvalidArgumentException {
}
diff --git a/includes/libs/objectcache/BagOStuffPsrCacheItem.php
b/includes/libs/objectcache/MediaWikiPsrCacheItem.php
similarity index 98%
rename from includes/libs/objectcache/BagOStuffPsrCacheItem.php
rename to includes/libs/objectcache/MediaWikiPsrCacheItem.php
index cf57311..85524ac 100644
--- a/includes/libs/objectcache/BagOStuffPsrCacheItem.php
+++ b/includes/libs/objectcache/MediaWikiPsrCacheItem.php
@@ -9,7 +9,7 @@
*
* @since 1.27
*/
-class BagOStuffPsrCacheItem implements CacheItemInterface {
+class MediaWikiPsrCacheItem implements CacheItemInterface {
/**
* @var string
diff --git a/includes/libs/objectcache/BagOStuffPsrCacheException.php
b/includes/libs/objectcache/MediawikiPsrCacheException.php
similarity index 65%
rename from includes/libs/objectcache/BagOStuffPsrCacheException.php
rename to includes/libs/objectcache/MediawikiPsrCacheException.php
index e4b8b54..b914093 100644
--- a/includes/libs/objectcache/BagOStuffPsrCacheException.php
+++ b/includes/libs/objectcache/MediawikiPsrCacheException.php
@@ -9,6 +9,6 @@
*
* @since 1.27
*/
-class BagOStuffPsrCacheException extends Exception implements CacheException {
+class MediaWikiPsrCacheException extends Exception implements CacheException {
}
diff --git a/includes/libs/objectcache/WANObjectPsrCache.php
b/includes/libs/objectcache/WANObjectPsrCache.php
new file mode 100644
index 0000000..a99a269
--- /dev/null
+++ b/includes/libs/objectcache/WANObjectPsrCache.php
@@ -0,0 +1,286 @@
+<?php
+
+use Psr\Cache\CacheItemInterface;
+use Psr\Cache\CacheItemPoolInterface;
+
+/**
+ * @author Addshore
+ *
+ * @ingroup Cache
+ *
+ * @since 1.27
+ */
+class WANObjectPsrCache implements CacheItemPoolInterface {
+
+ /**
+ * List of invalid (or reserved) key characters.
+ *
+ * @var string
+ */
+ const INVALID_KEY_CHARACTERS = '{}()/\@:';
+
+ /**
+ * @var WANObjectCache
+ */
+ private $objectCache;
+
+ public function __construct( WANObjectCache $objectCache ) {
+ $this->objectCache = $objectCache;
+ }
+
+ /**
+ * @return string The cache key used to store a list of all cached keys
+ */
+ private function getKeyListKey() {
+ return $this->objectCache->makeKey( __CLASS__, 'keylist' );
+ }
+
+ /**
+ * @return array Keys stored in this cache
+ */
+ private function getKeyList() {
+ $value = $this->objectCache->get( $this->getKeyListKey() );
+ if ( !$value ) {
+ return [];
+ }
+
+ return $value;
+ }
+
+ /**
+ * @param string $key Adds a key to the list of stored keys
+ */
+ private function addToKeyList( $key ) {
+ $storedKeys = $this->getKeyList();
+ $storedKeys[$key] = $key;
+ $this->objectCache->set( $this->getKeyListKey(), $storedKeys );
+ }
+
+ /**
+ * Clears all stored keys from the list
+ */
+ private function clearKeyList() {
+ $this->objectCache->delete( $this->getKeyListKey() );
+ }
+
+ /**
+ * @param mixed $key
+ *
+ * @throws MediaWikiPsrCacheInvalidArgumentException
+ */
+ private function throwExceptionOnBadKey( $key ) {
+ if ( !is_string( $key ) ) {
+ throw new MediaWikiPsrCacheInvalidArgumentException(
'$key must be a string' );
+ }
+ // Make sure nothing uses the same key as our key list
+ if ( $key === $this->getKeyListKey() ) {
+ throw new MediaWikiPsrCacheInvalidArgumentException(
'$key value is reserved' );
+ }
+ // Valid key according to PSR-6 rules
+ $invalid = preg_quote( static::INVALID_KEY_CHARACTERS, '/' );
+ if ( preg_match( '/[' . $invalid . ']/', $key ) ) {
+ throw new MediaWikiPsrCacheInvalidArgumentException(
+ 'Invalid key: ' . $key . '. Contains (a)
character(s) reserved ' .
+ 'for future extension: ' .
static::INVALID_KEY_CHARACTERS
+ );
+ }
+ }
+
+ /**
+ * Returns a Cache Item representing the specified key.
+ *
+ * This method must always return a CacheItemInterface object, even in
case of
+ * a cache miss. It MUST NOT return null.
+ *
+ * @param string $key
+ * The key for which to return the corresponding Cache Item.
+ *
+ * @throws \Psr\Cache\InvalidArgumentException
+ * If the $key string is not a legal value a
\Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return CacheItemInterface
+ * The corresponding Cache Item.
+ */
+ public function getItem( $key ) {
+ $this->throwExceptionOnBadKey( $key );
+
+ $item = $this->objectCache->get( $key );
+ if ( $item === false ) {
+ return new MediaWikiPsrCacheItem( $key, null, false );
+ }
+
+ return new MediaWikiPsrCacheItem( $key, $item, true );
+ }
+
+ /**
+ * Returns a traversable set of cache items.
+ *
+ * @param array $keys
+ * An indexed array of keys of items to retrieve.
+ *
+ * @throws \Psr\Cache\InvalidArgumentException
+ * If any of the keys in $keys are not a legal value a
\Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return array|\Traversable
+ * A traversable collection of Cache Items keyed by the cache keys of
+ * each item. A Cache item will be returned for each key, even if that
+ * key is not found. However, if no keys are specified then an empty
+ * traversable MUST be returned instead.
+ */
+ public function getItems( array $keys = [] ) {
+ $items = [];
+ foreach ( $keys as $key ) {
+ $items[$key] = $this->getItem( $key );
+ }
+
+ return $items;
+ }
+
+ /**
+ * Confirms if the cache contains specified cache item.
+ *
+ * Note: This method MAY avoid retrieving the cached value for
performance reasons.
+ * This could result in a race condition with
CacheItemInterface::get(). To avoid
+ * such situation use CacheItemInterface::isHit() instead.
+ *
+ * @param string $key
+ * The key for which to check existence.
+ *
+ * @throws \Psr\Cache\InvalidArgumentException
+ * If the $key string is not a legal value a
\Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return bool
+ * True if item exists in the cache, false otherwise.
+ */
+ public function hasItem( $key ) {
+ $this->throwExceptionOnBadKey( $key );
+
+ return $this->objectCache->get( $key ) !== false;
+ }
+
+ /**
+ * Deletes all items in the pool.
+ *
+ * @return bool
+ * True if the pool was successfully cleared. False if there was an
error.
+ */
+ public function clear() {
+ $this->deleteItems( $this->getKeyList() );
+ $this->clearKeyList();
+
+ return true;
+ }
+
+ /**
+ * Removes the item from the pool.
+ *
+ * @param string $key
+ * The key for which to delete
+ *
+ * @throws \Psr\Cache\InvalidArgumentException
+ * If the $key string is not a legal value a
\Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return bool
+ * True if the item was successfully removed. False if there was an
error.
+ */
+ public function deleteItem( $key ) {
+ $this->throwExceptionOnBadKey( $key );
+
+ return $this->objectCache->delete( $key );
+ }
+
+ /**
+ * Removes multiple items from the pool.
+ *
+ * @param array $keys
+ * An array of keys that should be removed from the pool.
+ *
+ * @throws \Psr\Cache\InvalidArgumentException
+ * If any of the keys in $keys are not a legal value a
\Psr\Cache\InvalidArgumentException
+ * MUST be thrown.
+ *
+ * @return bool
+ * True if the items were successfully removed. False if there was an
error.
+ */
+ public function deleteItems( array $keys ) {
+ $totalReturn = true;
+ foreach ( $keys as $key ) {
+ $innerReturn = $this->deleteItem( $key );
+ if ( !$innerReturn ) {
+ $totalReturn = false;
+ }
+ }
+
+ return $totalReturn;
+ }
+
+ /**
+ * Persists a cache item immediately.
+ *
+ * @param CacheItemInterface $item
+ * The cache item to save.
+ *
+ * @return bool True if the item was successfully persisted. False if
there was an error.
+ * True if the item was successfully persisted. False if there was an
error.
+ * @throws MediaWikiPsrCacheException as BagOStuffs can not
differentiate between a false
+ * value and an un-cached value
+ */
+ public function save( CacheItemInterface $item ) {
+ if ( !$item instanceof MediaWikiPsrCacheItem ) {
+ throw new MediaWikiPsrCacheInvalidArgumentException(
+ __CLASS__ . ' can only save
BagOStuffPsrCacheItem objects'
+ );
+ }
+ if ( $item->get() === false ) {
+ throw new MediaWikiPsrCacheException( __CLASS__ . ' can
not cache false' );
+ }
+
+ $exptime = 0;
+ $itemExpiration = $item->getExpiration();
+ if ( $itemExpiration instanceof DateTimeInterface ) {
+ $exptime = date_timestamp_get( $itemExpiration );
+ }
+
+ $storeSuccess = $this->objectCache->set(
+ $item->getKey(),
+ $item->get(),
+ $exptime
+ );
+
+ if ( $storeSuccess ) {
+ $this->addToKeyList( $item->getKey() );
+ }
+
+ return $storeSuccess;
+ }
+
+ /**
+ * Sets a cache item to be persisted later.
+ *
+ * @param CacheItemInterface $item
+ * The cache item to save.
+ *
+ * @return bool
+ * False if the item could not be queued or if a commit was attempted
and failed. True
+ * otherwise.
+ */
+ public function saveDeferred( CacheItemInterface $item ) {
+ return $this->save( $item );
+ }
+
+ /**
+ * Persists any deferred cache items.
+ *
+ * @return bool
+ * True if all not-yet-saved items were successfully saved or there
were none. False
+ * otherwise.
+ */
+ public function commit() {
+ return true;
+ }
+
+}
diff --git a/tests/phpunit/includes/libs/objectcache/BagOStuffPsrCacheTest.php
b/tests/phpunit/includes/libs/objectcache/BagOStuffPsrCacheTest.php
index d542e09..615b695 100644
--- a/tests/phpunit/includes/libs/objectcache/BagOStuffPsrCacheTest.php
+++ b/tests/phpunit/includes/libs/objectcache/BagOStuffPsrCacheTest.php
@@ -2,7 +2,7 @@
use Cache\IntegrationTests\CachePoolTest;
-require_once __DIR__ .
'/../../../../../vendor/cache/integration-tests/src/CachePoolTest.php';
+require __DIR__ .
'/../../../../../vendor/cache/integration-tests/src/CachePoolTest.php';
/**
* @covers BagOStuffPsrCache
diff --git a/tests/phpunit/includes/libs/objectcache/WANObjectPsrCacheTest.php
b/tests/phpunit/includes/libs/objectcache/WANObjectPsrCacheTest.php
new file mode 100644
index 0000000..f9d5e30
--- /dev/null
+++ b/tests/phpunit/includes/libs/objectcache/WANObjectPsrCacheTest.php
@@ -0,0 +1,31 @@
+<?php
+
+use Cache\IntegrationTests\CachePoolTest;
+
+require __DIR__ .
'/../../../../../vendor/cache/integration-tests/src/CachePoolTest.php';
+
+/**
+ * @covers WANObjectPsrCache
+ *
+ * @author Addshore
+ */
+class WANObjectPsrCacheTest extends CachePoolTest {
+
+ private $objectCache;
+
+ public function setUp() {
+ $this->objectCache = new WANObjectCache(
+ [
+ 'cache' => new HashBagOStuff(),
+ 'pool' => __METHOD__,
+ ]
+ );
+
+ parent::setUp();
+ }
+
+ public function createCachePool() {
+ return new BagOStuffPsrCache( $this->objectCache );
+ }
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/282121
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia2dd8b62deebf72901ba7676455fcf2394803116
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Addshore <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits