From 75cde6b9ac7757d91cd3941cec75bb1c0f4aa708 Mon Sep 17 00:00:00 2001 From: Sam Hemelryk Date: Fri, 23 Nov 2012 14:22:44 +1300 Subject: [PATCH] MDL-36768 cache: replaced cache_store interface with abstract class --- cache/classes/config.php | 2 +- cache/classes/dummystore.php | 26 +--- cache/classes/interfaces.php | 221 --------------------------------- cache/classes/loaders.php | 21 ++-- cache/classes/store.php | 197 +++++++++++++++++++++++++++-- cache/locallib.php | 2 +- cache/stores/file/lib.php | 2 +- cache/stores/memcache/lib.php | 2 +- cache/stores/memcached/lib.php | 2 +- cache/stores/mongodb/lib.php | 2 +- cache/stores/session/lib.php | 2 +- cache/stores/static/lib.php | 4 +- 12 files changed, 212 insertions(+), 271 deletions(-) diff --git a/cache/classes/config.php b/cache/classes/config.php index da3b9665915..e6d3416198c 100644 --- a/cache/classes/config.php +++ b/cache/classes/config.php @@ -182,7 +182,7 @@ class cache_config { if (!class_exists($class)) { continue; } - if (!array_key_exists('cache_store', class_implements($class))) { + if (!array_key_exists('cache_store', class_parents($class))) { continue; } if (!array_key_exists('configuration', $store) || !is_array($store['configuration'])) { diff --git a/cache/classes/dummystore.php b/cache/classes/dummystore.php index d44dc8c4754..9a69d6786a1 100644 --- a/cache/classes/dummystore.php +++ b/cache/classes/dummystore.php @@ -37,7 +37,7 @@ defined('MOODLE_INTERNAL') || die(); * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class cachestore_dummy implements cache_store { +class cachestore_dummy extends cache_store { /** * The name of this store. @@ -135,30 +135,6 @@ class cachestore_dummy implements cache_store { return true; } - /** - * Returns true if this store supports data guarantee. - * @return bool - */ - public function supports_data_guarantee() { - return false; - } - - /** - * Returns true if this store supports multiple identifiers. - * @return bool - */ - public function supports_multiple_identifiers() { - return false; - } - - /** - * Returns true if this store supports a native ttl. - * @return bool - */ - public function supports_native_ttl() { - return true; - } - /** * Returns the data for the given key * @param string $key diff --git a/cache/classes/interfaces.php b/cache/classes/interfaces.php index 983bc6bd437..07abb209c97 100644 --- a/cache/classes/interfaces.php +++ b/cache/classes/interfaces.php @@ -230,227 +230,6 @@ interface cache_loader_with_locking { public function release_lock($key); } -/** - * Cache store. - * - * This interface outlines the requirements for a cache store plugin. - * It must be implemented by all such plugins and provides a reference to interacting with cache stores. - * - * Must be implemented by all cache store plugins. - * - * @package core - * @category cache - * @copyright 2012 Sam Hemelryk - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -interface cache_store { - - /**#@+ - * Constants for features a cache store can support - */ - /** - * Supports multi-part keys - */ - const SUPPORTS_MULTIPLE_IDENTIFIERS = 1; - /** - * Ensures data remains in the cache once set. - */ - const SUPPORTS_DATA_GUARANTEE = 2; - /** - * Supports a native ttl system. - */ - const SUPPORTS_NATIVE_TTL = 4; - /**#@-*/ - - /**#@+ - * Constants for the modes of a cache store - */ - /** - * Application caches. These are shared caches. - */ - const MODE_APPLICATION = 1; - /** - * Session caches. Just access to the PHP session. - */ - const MODE_SESSION = 2; - /** - * Request caches. Static caches really. - */ - const MODE_REQUEST = 4; - /**#@-*/ - - /** - * Static method to check if the store requirements are met. - * - * @return bool True if the stores software/hardware requirements have been met and it can be used. False otherwise. - */ - public static function are_requirements_met(); - - /** - * Static method to check if a store is usable with the given mode. - * - * @param int $mode One of cache_store::MODE_* - */ - public static function is_supported_mode($mode); - - /** - * Returns the supported features as a binary flag. - * - * @param array $configuration The configuration of a store to consider specifically. - * @return int The supported features. - */ - public static function get_supported_features(array $configuration = array()); - - /** - * Returns the supported modes as a binary flag. - * - * @param array $configuration The configuration of a store to consider specifically. - * @return int The supported modes. - */ - public static function get_supported_modes(array $configuration = array()); - - /** - * Returns true if this cache store instance supports multiple identifiers. - * - * @return bool - */ - public function supports_multiple_identifiers(); - - /** - * Returns true if this cache store instance promotes data guarantee. - * - * @return bool - */ - public function supports_data_guarantee(); - - /** - * Returns true if this cache store instance supports ttl natively. - * - * @return bool - */ - public function supports_native_ttl(); - - /** - * Used to control the ability to add an instance of this store through the admin interfaces. - * - * @return bool True if the user can add an instance, false otherwise. - */ - public static function can_add_instance(); - - /** - * Constructs an instance of the cache store. - * - * This method should not create connections or perform and processing, it should be used - * - * @param string $name The name of the cache store - * @param array $configuration The configuration for this store instance. - */ - public function __construct($name, array $configuration = array()); - - /** - * Returns the name of this store instance. - * @return string - */ - public function my_name(); - - /** - * Initialises a new instance of the cache store given the definition the instance is to be used for. - * - * This function should prepare any given connections etc. - * - * @param cache_definition $definition - */ - public function initialise(cache_definition $definition); - - /** - * Returns true if this cache store instance has been initialised. - * @return bool - */ - public function is_initialised(); - - /** - * Returns true if this cache store instance is ready to use. - * @return bool - */ - public function is_ready(); - - /** - * Retrieves an item from the cache store given its key. - * - * @param string $key The key to retrieve - * @return mixed The data that was associated with the key, or false if the key did not exist. - */ - public function get($key); - - /** - * Retrieves several items from the cache store in a single transaction. - * - * If not all of the items are available in the cache then the data value for those that are missing will be set to false. - * - * @param array $keys The array of keys to retrieve - * @return array An array of items from the cache. There will be an item for each key, those that were not in the store will - * be set to false. - */ - public function get_many($keys); - - /** - * Sets an item in the cache given its key and data value. - * - * @param string $key The key to use. - * @param mixed $data The data to set. - * @return bool True if the operation was a success false otherwise. - */ - public function set($key, $data); - - /** - * Sets many items in the cache in a single transaction. - * - * @param array $keyvaluearray An array of key value pairs. Each item in the array will be an associative array with two - * keys, 'key' and 'value'. - * @return int The number of items successfully set. It is up to the developer to check this matches the number of items - * sent ... if they care that is. - */ - public function set_many(array $keyvaluearray); - - /** - * Deletes an item from the cache store. - * - * @param string $key The key to delete. - * @return bool Returns true if the operation was a success, false otherwise. - */ - public function delete($key); - - /** - * Deletes several keys from the cache in a single action. - * - * @param array $keys The keys to delete - * @return int The number of items successfully deleted. - */ - public function delete_many(array $keys); - - /** - * Purges the cache deleting all items within it. - * - * @return boolean True on success. False otherwise. - */ - public function purge(); - - /** - * Performs any necessary clean up when the store instance is being deleted. - */ - public function cleanup(); - - /** - * Generates an instance of the cache store that can be used for testing. - * - * Returns an instance of the cache store, or false if one cannot be created. - * - * @param cache_definition $definition - * @return cache_store|false - */ - public static function initialise_test_instance(cache_definition $definition); -} - /** * Cache store feature: locking * diff --git a/cache/classes/loaders.php b/cache/classes/loaders.php index 433e9b76abf..74014c417b0 100644 --- a/cache/classes/loaders.php +++ b/cache/classes/loaders.php @@ -638,19 +638,22 @@ class cache implements cache_loader { public function has($key, $tryloadifpossible = false) { $parsedkey = $this->parse_key($key); if ($this->is_in_persist_cache($parsedkey)) { + // Hoorah, that was easy. It exists in the persist cache so we definitely have it. return true; } - if (($this->has_a_ttl() && !$this->store_supports_native_ttl()) || !$this->store_supports_key_awareness()) { - if ($this->store_supports_key_awareness() && !$this->store->has($parsedkey)) { - return false; - } + if ($this->has_a_ttl() && !$this->store_supports_native_ttl()) { + // The data has a TTL and the store doesn't support it natively. + // We must fetch the data and expect a ttl wrapper. $data = $this->store->get($parsedkey); - if (!$this->store_supports_native_ttl()) { - $has = ($data instanceof cache_ttl_wrapper && !$data->has_expired()); - } else { - $has = ($data !== false); - } + $has = ($data instanceof cache_ttl_wrapper && !$data->has_expired()); + } else if (!$this->store_supports_key_awareness()) { + // The store doesn't support key awareness, get the data and check it manually... puke. + // Either no TTL is set of the store supports its handling natively. + $data = $this->store->get($parsedkey); + $has = ($data !== false); } else { + // The store supports key awareness, this is easy! + // Either no TTL is set of the store supports its handling natively. $has = $this->store->has($parsedkey); } if (!$has && $tryloadifpossible) { diff --git a/cache/classes/store.php b/cache/classes/store.php index fd4d0963584..75cd8d8596f 100644 --- a/cache/classes/store.php +++ b/cache/classes/store.php @@ -29,13 +29,63 @@ defined('MOODLE_INTERNAL') || die(); /** - * Abstract cache store base class. + * Cache store interface. * - * This class implements the cache_store interface that all caches store plugins are required in implement. - * It then implements basic methods that likely won't need to be overridden by plugins. - * It will also be used to implement any API changes that come about in the future. + * This interface defines the static methods that must be implemented by every cache store plugin. + * To ensure plugins implement this class the abstract cache_store class implements this interface. * - * While it is not required that you extend this class it is highly recommended. + * @package core + * @category cache + * @copyright 2012 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +interface cache_store_interface { + /** + * Static method to check if the store requirements are met. + * + * @return bool True if the stores software/hardware requirements have been met and it can be used. False otherwise. + */ + public static function are_requirements_met(); + + /** + * Static method to check if a store is usable with the given mode. + * + * @param int $mode One of cache_store::MODE_* + */ + public static function is_supported_mode($mode); + + /** + * Returns the supported features as a binary flag. + * + * @param array $configuration The configuration of a store to consider specifically. + * @return int The supported features. + */ + public static function get_supported_features(array $configuration = array()); + + /** + * Returns the supported modes as a binary flag. + * + * @param array $configuration The configuration of a store to consider specifically. + * @return int The supported modes. + */ + public static function get_supported_modes(array $configuration = array()); + + /** + * Generates an instance of the cache store that can be used for testing. + * + * Returns an instance of the cache store, or false if one cannot be created. + * + * @param cache_definition $definition + * @return cache_store|false + */ + public static function initialise_test_instance(cache_definition $definition); +} + +/** + * Abstract cache store class. + * + * All cache store plugins must extend this base class. + * It lays down the foundation for what is required of a cache store plugin. * * @since 2.4 * @package core @@ -43,7 +93,140 @@ defined('MOODLE_INTERNAL') || die(); * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -abstract class cache_store_base implements cache_store { +abstract class cache_store implements cache_store_interface { + + // Constants for features a cache store can support + + /** + * Supports multi-part keys + */ + const SUPPORTS_MULTIPLE_IDENTIFIERS = 1; + /** + * Ensures data remains in the cache once set. + */ + const SUPPORTS_DATA_GUARANTEE = 2; + /** + * Supports a native ttl system. + */ + const SUPPORTS_NATIVE_TTL = 4; + + // Constants for the modes of a cache store + + /** + * Application caches. These are shared caches. + */ + const MODE_APPLICATION = 1; + /** + * Session caches. Just access to the PHP session. + */ + const MODE_SESSION = 2; + /** + * Request caches. Static caches really. + */ + const MODE_REQUEST = 4; + + /** + * Constructs an instance of the cache store. + * + * This method should not create connections or perform and processing, it should be used + * + * @param string $name The name of the cache store + * @param array $configuration The configuration for this store instance. + */ + abstract public function __construct($name, array $configuration = array()); + + /** + * Returns the name of this store instance. + * @return string + */ + abstract public function my_name(); + + /** + * Initialises a new instance of the cache store given the definition the instance is to be used for. + * + * This function should prepare any given connections etc. + * + * @param cache_definition $definition + */ + abstract public function initialise(cache_definition $definition); + + /** + * Returns true if this cache store instance has been initialised. + * @return bool + */ + abstract public function is_initialised(); + + /** + * Returns true if this cache store instance is ready to use. + * @return bool + */ + abstract public function is_ready(); + + /** + * Retrieves an item from the cache store given its key. + * + * @param string $key The key to retrieve + * @return mixed The data that was associated with the key, or false if the key did not exist. + */ + abstract public function get($key); + + /** + * Retrieves several items from the cache store in a single transaction. + * + * If not all of the items are available in the cache then the data value for those that are missing will be set to false. + * + * @param array $keys The array of keys to retrieve + * @return array An array of items from the cache. There will be an item for each key, those that were not in the store will + * be set to false. + */ + abstract public function get_many($keys); + + /** + * Sets an item in the cache given its key and data value. + * + * @param string $key The key to use. + * @param mixed $data The data to set. + * @return bool True if the operation was a success false otherwise. + */ + abstract public function set($key, $data); + + /** + * Sets many items in the cache in a single transaction. + * + * @param array $keyvaluearray An array of key value pairs. Each item in the array will be an associative array with two + * keys, 'key' and 'value'. + * @return int The number of items successfully set. It is up to the developer to check this matches the number of items + * sent ... if they care that is. + */ + abstract public function set_many(array $keyvaluearray); + + /** + * Deletes an item from the cache store. + * + * @param string $key The key to delete. + * @return bool Returns true if the operation was a success, false otherwise. + */ + abstract public function delete($key); + + /** + * Deletes several keys from the cache in a single action. + * + * @param array $keys The keys to delete + * @return int The number of items successfully deleted. + */ + abstract public function delete_many(array $keys); + + /** + * Purges the cache deleting all items within it. + * + * @return boolean True on success. False otherwise. + */ + abstract public function purge(); + + /** + * Performs any necessary clean up when the store instance is being deleted. + */ + abstract public function cleanup(); /** * Returns true if the user can add an instance of the store plugin. @@ -80,4 +263,4 @@ abstract class cache_store_base implements cache_store { public function supports_native_ttl() { return $this::supports_data_guarantee() & self::SUPPORTS_NATIVE_TTL; } -} \ No newline at end of file +} diff --git a/cache/locallib.php b/cache/locallib.php index e8e43a3d454..d2b8f27dfc9 100644 --- a/cache/locallib.php +++ b/cache/locallib.php @@ -137,7 +137,7 @@ class cache_config_writer extends cache_config { } } $reflection = new ReflectionClass($class); - if (!$reflection->implementsInterface('cache_store')) { + if (!$reflection->isSubclassOf('cache_store')) { throw new cache_exception('Invalid cache plugin specified. The plugin does not extend the required class.'); } if (!$class::are_requirements_met()) { diff --git a/cache/stores/file/lib.php b/cache/stores/file/lib.php index aad565b1810..af0b096c2cf 100644 --- a/cache/stores/file/lib.php +++ b/cache/stores/file/lib.php @@ -37,7 +37,7 @@ * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class cachestore_file extends cache_store_base implements cache_is_key_aware { +class cachestore_file extends cache_store implements cache_is_key_aware { /** * The name of the store. diff --git a/cache/stores/memcache/lib.php b/cache/stores/memcache/lib.php index 2c373c0af22..c1530e97d92 100644 --- a/cache/stores/memcache/lib.php +++ b/cache/stores/memcache/lib.php @@ -37,7 +37,7 @@ defined('MOODLE_INTERNAL') || die(); * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class cachestore_memcache extends cache_store_base { +class cachestore_memcache extends cache_store { /** * The name of the store diff --git a/cache/stores/memcached/lib.php b/cache/stores/memcached/lib.php index 2da37b03c61..96c4978f471 100644 --- a/cache/stores/memcached/lib.php +++ b/cache/stores/memcached/lib.php @@ -43,7 +43,7 @@ defined('MOODLE_INTERNAL') || die(); * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class cachestore_memcached extends cache_store_base { +class cachestore_memcached extends cache_store { /** * The name of the store diff --git a/cache/stores/mongodb/lib.php b/cache/stores/mongodb/lib.php index c2f2eb820e1..2253bc22577 100644 --- a/cache/stores/mongodb/lib.php +++ b/cache/stores/mongodb/lib.php @@ -37,7 +37,7 @@ defined('MOODLE_INTERNAL') || die(); * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class cachestore_mongodb extends cache_store_base { +class cachestore_mongodb extends cache_store { /** * The name of the store diff --git a/cache/stores/session/lib.php b/cache/stores/session/lib.php index e8e25ea62dc..a652f9c9b3c 100644 --- a/cache/stores/session/lib.php +++ b/cache/stores/session/lib.php @@ -351,7 +351,7 @@ class cachestore_session extends session_data_store implements cache_is_key_awar * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -abstract class session_data_store extends cache_store_base { +abstract class session_data_store extends cache_store { /** * Used for the actual storage. diff --git a/cache/stores/static/lib.php b/cache/stores/static/lib.php index 4d62a318193..03d455ab037 100644 --- a/cache/stores/static/lib.php +++ b/cache/stores/static/lib.php @@ -34,7 +34,7 @@ defined('MOODLE_INTERNAL') || die(); * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class cachestore_static extends static_data_store implements cache_store, cache_is_key_aware { +class cachestore_static extends static_data_store implements cache_is_key_aware { /** * The name of the store @@ -351,7 +351,7 @@ class cachestore_static extends static_data_store implements cache_store, cache_ * @copyright 2012 Sam Hemelryk * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -abstract class static_data_store extends cache_store_base { +abstract class static_data_store extends cache_store { /** * An array for storage.