MDL-76791 core_cache: Locking breaks for multiple-identifiers store

Cache locking fails if the cache store supports multiple identifiers
(in core, the only two which do are cachestore_static and
cachestore_mongodb, so this is unlikely to cause severe problems).
This commit is contained in:
sam marshall 2023-01-04 12:02:37 +00:00
parent 0780e87f06
commit 3353aecc8b
2 changed files with 27 additions and 3 deletions

View File

@ -1679,7 +1679,7 @@ class cache_application extends cache implements cache_loader_with_locking {
if ($this->get_loader() !== false) {
$this->get_loader()->acquire_lock($key);
}
$key = $this->parse_key($key);
$key = cache_helper::hash_key($key, $this->get_definition());
$before = microtime(true);
if ($this->nativelocking) {
$lock = $this->get_store()->acquire_lock($key, $this->get_identifier());
@ -1706,7 +1706,7 @@ class cache_application extends cache implements cache_loader_with_locking {
* someone else has the lock.
*/
public function check_lock_state($key) {
$key = $this->parse_key($key);
$key = cache_helper::hash_key($key, $this->get_definition());
if (!empty($this->locks[$key])) {
return true; // Shortcut to save having to make a call to the cache store if the lock is held by this process.
}
@ -1726,7 +1726,7 @@ class cache_application extends cache implements cache_loader_with_locking {
*/
public function release_lock($key) {
$loaderkey = $key;
$key = $this->parse_key($key);
$key = cache_helper::hash_key($key, $this->get_definition());
if ($this->nativelocking) {
$released = $this->get_store()->release_lock($key, $this->get_identifier());
} else {

View File

@ -2111,6 +2111,30 @@ class cache_test extends \advanced_testcase {
$this->assertFalse($cache->has('a'));
}
/**
* The application locking feature should work with caches that support multiple identifiers
* (static cache and MongoDB with a specific setting).
*
* @covers \cache_application
*/
public function test_application_locking_multiple_identifier_cache() {
// Get an arbitrary definition (modinfo).
$instance = cache_config_testing::instance(true);
$definitions = $instance->get_definitions();
$definition = \cache_definition::load('phpunit', $definitions['core/coursemodinfo']);
// Set up a static cache using that definition, wrapped in cache_application so we can do
// locking.
$store = new \cachestore_static('test');
$store->initialise($definition);
$cache = new cache_application($definition, $store);
// Test the three locking functions.
$cache->acquire_lock('frog');
$this->assertTrue($cache->check_lock_state('frog'));
$cache->release_lock('frog');
}
/**
* Test requiring a lock before attempting to set a key.
*