MDL-78109 core_cache: Remove harmful requirelockingwrite/read options

These cache options are not used in core and would cause a performance
cost without any benefit if ever used. Also they don't work properly.
This commit is contained in:
sam marshall
2023-07-12 15:33:15 +01:00
parent ef93325f27
commit 8df2ac4e98
5 changed files with 21 additions and 249 deletions
+3 -149
View File
@@ -1596,18 +1596,6 @@ class cache_application extends cache implements cache_loader_with_locking {
*/
protected $requirelocking = false;
/**
* Gets set to true if the cache must use read locking (get|has).
* @var bool
*/
protected $requirelockingread = false;
/**
* Gets set to true if the cache must use write locking (set|delete)
* @var bool
*/
protected $requirelockingwrite = false;
/**
* Gets set to true if the cache writes (set|delete) must have a manual lock created first
* @var bool
@@ -1640,8 +1628,6 @@ class cache_application extends cache implements cache_loader_with_locking {
$this->nativelocking = $this->store_supports_native_locking();
if ($definition->require_locking()) {
$this->requirelocking = true;
$this->requirelockingread = $definition->require_locking_read();
$this->requirelockingwrite = $definition->require_locking_write();
$this->requirelockingbeforewrite = $definition->require_locking_before_write();
}
@@ -1785,20 +1771,14 @@ class cache_application extends cache implements cache_loader_with_locking {
* @param mixed $data The data to set against the key.
* @param bool $setparents If true, sets all parent loaders, otherwise only this one
* @return bool True on success, false otherwise.
* @throws coding_exception If a required lock has not beeen acquired
*/
protected function set_implementation($key, int $version, $data, bool $setparents = true): bool {
if ($this->requirelockingbeforewrite && !$this->check_lock_state($key)) {
throw new coding_exception('Attempted to set cache key "' . $key . '" without a lock. '
. 'Locking before writes is required for ' . $this->get_definition()->get_id());
}
if ($this->requirelockingwrite && !$this->acquire_lock($key)) {
return false;
}
$result = parent::set_implementation($key, $version, $data, $setparents);
if ($this->requirelockingwrite && !$this->release_lock($key)) {
debugging('Failed to release cache lock on set operation... this should not happen.', DEBUG_DEVELOPER);
}
return $result;
return parent::set_implementation($key, $version, $data, $setparents);
}
/**
@@ -1834,133 +1814,7 @@ class cache_application extends cache implements cache_loader_with_locking {
}
}
}
if ($this->requirelockingwrite) {
$locks = array();
foreach ($keyvaluearray as $id => $pair) {
$key = $pair['key'];
if ($this->acquire_lock($key)) {
$locks[] = $key;
} else {
unset($keyvaluearray[$id]);
}
}
}
$result = parent::set_many($keyvaluearray);
if ($this->requirelockingwrite) {
foreach ($locks as $key) {
if ($this->release_lock($key)) {
debugging('Failed to release cache lock on set_many operation... this should not happen.', DEBUG_DEVELOPER);
}
}
}
return $result;
}
/**
* Retrieves the value for the given key from the cache.
*
* @param string|int $key The key for the data being requested.
* @param int $requiredversion Minimum required version of the data or cache::VERSION_NONE
* @param int $strictness One of IGNORE_MISSING | MUST_EXIST
* @param mixed &$actualversion If specified, will be set to the actual version number retrieved
* @return mixed|false The data from the cache or false if the key did not exist within the cache.
*/
protected function get_implementation($key, int $requiredversion, int $strictness, &$actualversion = null) {
if ($this->requirelockingread && $this->check_lock_state($key) === false) {
// Read locking required and someone else has the read lock.
return false;
}
return parent::get_implementation($key, $requiredversion, $strictness, $actualversion);
}
/**
* Retrieves an array of values for an array of keys.
*
* Using this function comes with potential performance implications.
* Not all cache stores will support get_many/set_many operations and in order to replicate this functionality will call
* the equivalent singular method for each item provided.
* This should not deter you from using this function as there is a performance benefit in situations where the cache store
* does support it, but you should be aware of this fact.
*
* @param array $keys The keys of the data being requested.
* @param int $strictness One of IGNORE_MISSING or MUST_EXIST.
* @return array An array of key value pairs for the items that could be retrieved from the cache.
* If MUST_EXIST was used and not all keys existed within the cache then an exception will be thrown.
* Otherwise any key that did not exist will have a data value of false within the results.
* @throws coding_exception
*/
public function get_many(array $keys, $strictness = IGNORE_MISSING) {
$locks = [];
if ($this->requirelockingread) {
foreach ($keys as $id => $key) {
$locks[$key] = $this->acquire_lock($key);
if (!$locks[$key]) {
if ($strictness === MUST_EXIST) {
throw new coding_exception('Could not acquire read locks for all of the items being requested.');
} else {
// Can't return this as we couldn't get a read lock.
unset($keys[$id]);
}
}
}
}
$result = parent::get_many($keys, $strictness);
if ($this->requirelockingread) {
foreach ($locks as $key => $lock) {
$this->release_lock($key);
}
}
return $result;
}
/**
* Delete the given key from the cache.
*
* @param string|int $key The key to delete.
* @param bool $recurse When set to true the key will also be deleted from all stacked cache loaders and their stores.
* This happens by default and ensure that all the caches are consistent. It is NOT recommended to change this.
* @return bool True of success, false otherwise.
*/
public function delete($key, $recurse = true) {
if ($this->requirelockingwrite && !$this->acquire_lock($key)) {
return false;
}
$result = parent::delete($key, $recurse);
if ($this->requirelockingwrite && !$this->release_lock($key)) {
debugging('Failed to release cache lock on delete operation... this should not happen.', DEBUG_DEVELOPER);
}
return $result;
}
/**
* Delete all of the given keys from the cache.
*
* @param array $keys The key to delete.
* @param bool $recurse When set to true the key will also be deleted from all stacked cache loaders and their stores.
* This happens by default and ensure that all the caches are consistent. It is NOT recommended to change this.
* @return int The number of items successfully deleted.
*/
public function delete_many(array $keys, $recurse = true) {
if ($this->requirelockingwrite) {
$locks = array();
foreach ($keys as $id => $key) {
if ($this->acquire_lock($key)) {
$locks[] = $key;
} else {
unset($keys[$id]);
}
}
}
$result = parent::delete_many($keys, $recurse);
if ($this->requirelockingwrite) {
foreach ($locks as $key) {
if ($this->release_lock($key)) {
debugging('Failed to release cache lock on delete_many operation... this should not happen.', DEBUG_DEVELOPER);
}
}
}
return $result;
return parent::set_many($keyvaluearray);
}
}