MDL-83185 core_courseformat: Allow global state cache invalidation

This commit is contained in:
ferran 2024-10-30 15:10:59 +01:00 committed by Laurent David
parent 2b337b49f9
commit 1f7faa941b
5 changed files with 104 additions and 1 deletions

View File

@ -0,0 +1,8 @@
issueNumber: MDL-83185
notes:
core_courseformat:
- message: >-
Add core_courseformat\base::invalidate_all_session_caches to reset course editor cache for all users when course is changed.
This method can be used as an alternative to core_courseformat\base::session_cache_reset for resetting the cache for the current user
in case the change in the course should be reflected for all users.
type: improved

View File

@ -283,6 +283,20 @@ abstract class base {
return self::session_cache_reset($course);
}
/**
* Prune a course state cache for all open sessions.
*
* Most course edits does not require to invalidate the cache for all users
* because the cache relies on the course cacherev value. However, there are
* actions like editing the groups that do not change the course cacherev.
*
* @param \stdClass $course
* @return void
*/
public static function invalidate_all_session_caches_for_course(stdClass $course): void {
\cache_helper::invalidate_by_event('changesincoursestate', [$course->id]);
}
/**
* Returns the format name used by this course
*

View File

@ -996,6 +996,84 @@ class base_test extends advanced_testcase {
$this->assertFalse($format->is_section_visible($modinfostudent->get_section_info(1)));
$this->assertFalse($format->is_section_visible($modinfostudent->get_section_info(2)));
}
/**
* Test can_sections_be_removed_from_navigation().
*
* @covers ::session_cache
* @covers ::session_cache_reset
* @covers ::session_cache_reset_all
* @covers ::invalidate_all_session_caches_for_course
*/
public function test_session_caches_methods(): void {
global $DB;
$this->resetAfterTest();
$generator = $this->getDataGenerator();
$course1 = $generator->create_course(['format' => 'topics']);
$course2 = $generator->create_course(['format' => 'topics']);
// Force some cacherev to the course.
$course1->cacherev = 12345;
$course2->cacherev = 67890;
$DB->set_field('course', 'cacherev', $course1->cacherev, ['id' => $course1->id]);
$DB->set_field('course', 'cacherev', $course2->cacherev, ['id' => $course2->id]);
$teacher = $generator->create_and_enrol($course1, 'editingteacher');
$generator->enrol_user($teacher->id, $course2->id, 'editingteacher');
$this->setUser($teacher);
// The cache key uses time() as hash. To not wait a second between calls we fake an initial value.
$statecache = cache::make('core', 'courseeditorstate');
$statecache->set($course1->id, $course1->cacherev . '_11111');
$statecache->set($course2->id, $course2->cacherev . '_22222');
$course1cachekey = \core_courseformat\base::session_cache($course1);
// Validate the method returns the same value when called twice.
$course1cachekeyagain = \core_courseformat\base::session_cache($course1);
$this->assertEquals($course1cachekey, $course1cachekeyagain);
// Validate other course has a diferent cache key.
$course2cachekey = \core_courseformat\base::session_cache($course2);
$this->assertNotEquals($course1cachekey, $course2cachekey);
// Reset the specific course cache.
\core_courseformat\base::session_cache_reset($course1);
$resetcachekey = \core_courseformat\base::session_cache($course1);
$this->assertNotEquals($course1cachekey, $resetcachekey);
$reset2cachekey = \core_courseformat\base::session_cache($course2);
$this->assertEquals($course2cachekey, $reset2cachekey);
// Return to the initial value.
$statecache->set($course1->id, $course1->cacherev . '_11111');
$statecache->set($course2->id, $course2->cacherev . '_22222');
// Reset all user course caches.
\core_courseformat\base::session_cache_reset_all();
$resetallcachekey = \core_courseformat\base::session_cache($course1);
$this->assertNotEquals($course1cachekey, $resetallcachekey);
$resetall2cachekey = \core_courseformat\base::session_cache($course2);
$this->assertNotEquals($course2cachekey, $resetall2cachekey);
// Return to the initial value.
$statecache->set($course1->id, $course1->cacherev . '_11111');
$statecache->set($course2->id, $course2->cacherev . '_22222');
// Invalidate cache on course 1.
\core_courseformat\base::invalidate_all_session_caches_for_course($course1);
$invalidatecachekey = \core_courseformat\base::session_cache($course1);
$this->assertNotEquals($course1cachekey, $invalidatecachekey);
$invalidate2cachekey = \core_courseformat\base::session_cache($course2);
$this->assertEquals($course2cachekey, $invalidate2cachekey);
}
}
/**

View File

@ -239,6 +239,9 @@ $definitions = array(
'mode' => cache_store::MODE_SESSION,
'simplekeys' => true,
'simpledata' => true,
'invalidationevents' => [
'changesincoursestate',
],
],
// Course actions instances cache.
'courseactionsinstances' => [

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2024110800.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2024110800.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '5.0dev (Build: 20241108)'; // Human-friendly version name