Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'wip-MDL-36322-m24' of https://github.com/samhemelryk/mo…

…odle into MOODLE_24_STABLE
  • Loading branch information...
commit 7298cf7db35ca0f1484f8c446fa843a199d84fe3 2 parents 50890e0 + 3fbba4b
@danpoltawski danpoltawski authored
View
10 cache/classes/factory.php
@@ -263,7 +263,13 @@ public function create_store_from_config($name, array $details, cache_definition
if (!$store->is_ready() || !$store->is_supported_mode($definition->get_mode())) {
return false;
}
- $store = clone($this->stores[$name]);
+ // We always create a clone of the original store.
+ // If we were to clone a store that had already been initialised with a definition then
+ // we'd run into a myriad of issues.
+ // We use a method of the store to create a clone rather than just creating it ourselves
+ // so that if any store out there doesn't handle cloning they can override this method in
+ // order to address the issues.
+ $store = $this->stores[$name]->create_clone($details);
$store->initialise($definition);
return $store;
}
@@ -550,4 +556,4 @@ public static function disable_stores() {
$factory = self::instance();
$factory->set_state(self::STATE_STORES_DISABLED);
}
-}
+}
View
36 cache/classes/store.php
@@ -128,7 +128,16 @@ public static function initialise_test_instance(cache_definition $definition);
/**
* Constructs an instance of the cache store.
*
- * This method should not create connections or perform and processing, it should be used
+ * The constructor should be responsible for creating anything needed by the store that is not
+ * specific to a definition.
+ * Tasks such as opening a connection to check it is available are best done here.
+ * Tasks that are definition specific such as creating a storage area for the definition data
+ * or creating key tables and indexs are best done within the initialise method.
+ *
+ * Once a store has been constructed the cache API will check it is ready to be intialised with
+ * a definition by called $this->is_ready().
+ * If the setup of the store failed (connection could not be established for example) then
+ * that method should return false so that the store instance is not selected for use.
*
* @param string $name The name of the cache store
* @param array $configuration The configuration for this store instance.
@@ -144,7 +153,12 @@ public static function initialise_test_instance(cache_definition $definition);
/**
* 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.
+ * This function should be used to run any definition specific setup the store instance requires.
+ * Tasks such as creating storage areas, or creating indexes are best done here.
+ *
+ * Its important to note that the initialise method is expected to always succeed.
+ * If there are setup tasks that may fail they should be done within the __construct method
+ * and should they fail is_ready should return false.
*
* @param cache_definition $definition
*/
@@ -292,4 +306,22 @@ public function supports_multiple_identifiers() {
public function supports_native_ttl() {
return $this::get_supported_features() & self::SUPPORTS_NATIVE_TTL;
}
+
+ /**
+ * Creates a clone of this store instance ready to be initialised.
+ *
+ * This method is used so that a cache store needs only be constructed once.
+ * Future requests for an instance of the store will be given a cloned instance.
+ *
+ * If you are writing a cache store that isn't compatible with the clone operation
+ * you can override this method to handle any situations you want before cloning.
+ *
+ * @param array $details An array containing the details of the store from the cache config.
+ * @return cache_store
+ */
+ public function create_clone(array $details = array()) {
+ // By default we just run clone.
+ // Any stores that have an issue with this will need to override the create_clone method.
+ return clone($this);
+ }
}
View
25 cache/stores/memcache/lib.php
@@ -70,6 +70,12 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
protected $isready = false;
/**
+ * Set to true once this store instance has been initialised.
+ * @var bool
+ */
+ protected $isinitialised = false;
+
+ /**
* The cache definition this store was initialised for.
* @var cache_definition
*/
@@ -106,7 +112,12 @@ public function __construct($name, array $configuration = array()) {
$this->servers[] = $server;
}
- $this->isready = true;
+ $this->connection = new Memcache;
+ foreach ($this->servers as $server) {
+ $this->connection->addServer($server[0], $server[1], true, $server[2]);
+ // Test the connection to this server.
+ $this->isready = @$this->connection->set("ping", 'ping', MEMCACHE_COMPRESSED, 1);
+ }
}
/**
@@ -121,10 +132,7 @@ public function initialise(cache_definition $definition) {
throw new coding_exception('This memcache instance has already been initialised.');
}
$this->definition = $definition;
- $this->connection = new Memcache;
- foreach ($this->servers as $server) {
- $this->connection->addServer($server[0], $server[1], true, $server[2]);
- }
+ $this->isinitialised = true;
}
/**
@@ -133,7 +141,7 @@ public function initialise(cache_definition $definition) {
* @return bool
*/
public function is_initialised() {
- return ($this->connection !== null);
+ return ($this->isinitialised);
}
/**
@@ -276,7 +284,10 @@ public function delete_many(array $keys) {
* @return boolean True on success. False otherwise.
*/
public function purge() {
- $this->connection->flush();
+ if ($this->isready) {
+ $this->connection->flush();
+ }
+
return true;
}
View
32 cache/stores/memcached/lib.php
@@ -75,6 +75,12 @@ class cachestore_memcached extends cache_store implements cache_is_configurable
protected $isready = false;
/**
+ * Set to true when this store instance has been initialised.
+ * @var bool
+ */
+ protected $isinitialised = false;
+
+ /**
* The cache definition this store was initialised with.
* @var cache_definition
*/
@@ -127,7 +133,15 @@ public function __construct($name, array $configuration = array()) {
$this->options[Memcached::OPT_HASH] = $hashmethod;
$this->options[Memcached::OPT_BUFFER_WRITES] = $bufferwrites;
- $this->isready = true;
+ $this->connection = new Memcached(crc32($this->name));
+ $servers = $this->connection->getServerList();
+ if (empty($servers)) {
+ foreach ($this->options as $key => $value) {
+ $this->connection->setOption($key, $value);
+ }
+ $this->connection->addServers($this->servers);
+ $this->isready = @$this->connection->set("ping", 'ping', 1);
+ }
}
/**
@@ -142,14 +156,7 @@ public function initialise(cache_definition $definition) {
throw new coding_exception('This memcached instance has already been initialised.');
}
$this->definition = $definition;
- $this->connection = new Memcached(crc32($this->name));
- $servers = $this->connection->getServerList();
- if (empty($servers)) {
- foreach ($this->options as $key => $value) {
- $this->connection->setOption($key, $value);
- }
- $this->connection->addServers($this->servers);
- }
+ $this->isinitialised = true;
}
/**
@@ -158,7 +165,7 @@ public function initialise(cache_definition $definition) {
* @return bool
*/
public function is_initialised() {
- return ($this->connection !== null);
+ return ($this->isinitialised);
}
/**
@@ -302,7 +309,10 @@ public function delete_many(array $keys) {
* @return boolean True on success. False otherwise.
*/
public function purge() {
- $this->connection->flush();
+ if ($this->isready) {
+ $this->connection->flush();
+ }
+
return true;
}
View
32 cache/stores/mongodb/lib.php
@@ -100,7 +100,17 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
protected $definitionhash = null;
/**
- * Constructs a new instance of the Mongo store but does not connect to it.
+ * Set to true once this store is ready to be initialised and used.
+ * @var bool
+ */
+ protected $isready = false;
+
+ /**
+ * Constructs a new instance of the Mongo store.
+ *
+ * Noting that this function is not an initialisation. It is used to prepare the store for use.
+ * The store will be initialised when required and will be provided with a cache_definition at that time.
+ *
* @param string $name
* @param array $configuration
*/
@@ -130,7 +140,12 @@ public function __construct($name, array $configuration = array()) {
$this->extendedmode = $configuration['extendedmode'];
}
- $this->isready = self::are_requirements_met();
+ try {
+ $this->connection = new Mongo($this->server, $this->options);
+ $this->isready = true;
+ } catch (MongoConnectionException $e) {
+ // We only want to catch MongoConnectionExceptions here.
+ }
}
/**
@@ -166,7 +181,7 @@ public static function get_supported_modes(array $configuration = array()) {
/**
* Initialises the store instance for use.
*
- * This function is reponsible for making the connection.
+ * Once this has been done the cache is all set to be used.
*
* @param cache_definition $definition
* @throws coding_exception
@@ -175,9 +190,8 @@ public function initialise(cache_definition $definition) {
if ($this->is_initialised()) {
throw new coding_exception('This mongodb instance has already been initialised.');
}
- $this->definitionhash = $definition->generate_definition_hash();
- $this->connection = new Mongo($this->server, $this->options);
$this->database = $this->connection->selectDB($this->databasename);
+ $this->definitionhash = $definition->generate_definition_hash();
$this->collection = $this->database->selectCollection($this->definitionhash);
$this->collection->ensureIndex(array('key' => 1), array(
'safe' => $this->usesafe,
@@ -366,8 +380,12 @@ public function delete_many(array $keys) {
* @return boolean True on success. False otherwise.
*/
public function purge() {
- $this->collection->drop();
- $this->collection = $this->database->selectCollection($this->definitionhash);
+ if ($this->isready) {
+ $this->collection->drop();
+ $this->collection = $this->database->selectCollection($this->definitionhash);
+ }
+
+ return true;
}
/**
View
1  cache/stores/session/lib.php
@@ -361,6 +361,7 @@ public function delete_many(array $keys) {
*/
public function purge() {
$this->store = array();
+ return true;
}
/**
View
1  cache/stores/static/lib.php
@@ -358,6 +358,7 @@ public function delete_many(array $keys) {
public function purge() {
$this->flush_store_by_id($this->storeid);
$this->store = &self::register_store_id($this->storeid);
+ return true;
}
/**
Please sign in to comment.
Something went wrong with that request. Please try again.