mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
MDL-72837 core_cache: Use versioned cache for modinfo
Uses the new versioned cache feature for modinfo, which should make it safe as a localisable cache.
This commit is contained in:
parent
8a0f706033
commit
02bb326314
@ -884,8 +884,9 @@ class courselib_test extends advanced_testcase {
|
|||||||
$this->assertEquals($cmids[0] . ',' . $cmids[1], $sequence);
|
$this->assertEquals($cmids[0] . ',' . $cmids[1], $sequence);
|
||||||
|
|
||||||
// Check that modinfo cache was reset but not rebuilt (important for performance if calling repeatedly).
|
// Check that modinfo cache was reset but not rebuilt (important for performance if calling repeatedly).
|
||||||
$this->assertGreaterThan($coursecacherev, $DB->get_field('course', 'cacherev', array('id' => $course->id)));
|
$newcacherev = $DB->get_field('course', 'cacherev', ['id' => $course->id]);
|
||||||
$this->assertEmpty(cache::make('core', 'coursemodinfo')->get($course->id));
|
$this->assertGreaterThan($coursecacherev, $newcacherev);
|
||||||
|
$this->assertEmpty(cache::make('core', 'coursemodinfo')->get_versioned($course->id, $newcacherev));
|
||||||
|
|
||||||
// Add one to section that doesn't exist (this might rebuild modinfo).
|
// Add one to section that doesn't exist (this might rebuild modinfo).
|
||||||
course_add_cm_to_section($course, $cmids[2], 2);
|
course_add_cm_to_section($course, $cmids[2], 2);
|
||||||
|
@ -475,14 +475,14 @@ class course_modinfo {
|
|||||||
$cachecoursemodinfo = cache::make('core', 'coursemodinfo');
|
$cachecoursemodinfo = cache::make('core', 'coursemodinfo');
|
||||||
|
|
||||||
// Retrieve modinfo from cache. If not present or cacherev mismatches, call rebuild and retrieve again.
|
// Retrieve modinfo from cache. If not present or cacherev mismatches, call rebuild and retrieve again.
|
||||||
$coursemodinfo = $cachecoursemodinfo->get($course->id);
|
$coursemodinfo = $cachecoursemodinfo->get_versioned($course->id, $course->cacherev);
|
||||||
if ($coursemodinfo === false || ($course->cacherev != $coursemodinfo->cacherev)) {
|
if (!$coursemodinfo) {
|
||||||
$lock = self::get_course_cache_lock($course->id);
|
$lock = self::get_course_cache_lock($course->id);
|
||||||
try {
|
try {
|
||||||
// Only actually do the build if it's still needed after getting the lock (not if
|
// Only actually do the build if it's still needed after getting the lock (not if
|
||||||
// somebody else, who might have been holding the lock, built it already).
|
// somebody else, who might have been holding the lock, built it already).
|
||||||
$coursemodinfo = $cachecoursemodinfo->get($course->id);
|
$coursemodinfo = $cachecoursemodinfo->get_versioned($course->id, $course->cacherev);
|
||||||
if ($coursemodinfo === false || ($course->cacherev != $coursemodinfo->cacherev)) {
|
if (!$coursemodinfo) {
|
||||||
$coursemodinfo = self::inner_build_course_cache($course, $lock);
|
$coursemodinfo = self::inner_build_course_cache($course, $lock);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@ -681,17 +681,12 @@ class course_modinfo {
|
|||||||
global $DB, $CFG;
|
global $DB, $CFG;
|
||||||
require_once("{$CFG->dirroot}/course/lib.php");
|
require_once("{$CFG->dirroot}/course/lib.php");
|
||||||
|
|
||||||
// Ensure object has all necessary fields.
|
// Always reload the course object from database to ensure we have the latest possible
|
||||||
foreach (self::$cachedfields as $key) {
|
// value for cacherev.
|
||||||
if (!isset($course->$key)) {
|
$course = $DB->get_record('course', ['id' => $course->id],
|
||||||
$course = $DB->get_record('course', array('id' => $course->id),
|
implode(',', array_merge(['id'], self::$cachedfields)), MUST_EXIST);
|
||||||
implode(',', array_merge(array('id'), self::$cachedfields)), MUST_EXIST);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Retrieve all information about activities and sections.
|
// Retrieve all information about activities and sections.
|
||||||
// This may take time on large courses and it is possible that another user modifies the same course during this process.
|
|
||||||
// Field cacherev stored in both DB and cache will ensure that cached data matches the current course state.
|
|
||||||
$coursemodinfo = new stdClass();
|
$coursemodinfo = new stdClass();
|
||||||
$coursemodinfo->modinfo = get_array_of_activities($course->id);
|
$coursemodinfo->modinfo = get_array_of_activities($course->id);
|
||||||
$coursemodinfo->sectioncache = self::build_course_section_cache($course);
|
$coursemodinfo->sectioncache = self::build_course_section_cache($course);
|
||||||
@ -700,7 +695,7 @@ class course_modinfo {
|
|||||||
}
|
}
|
||||||
// Set the accumulated activities and sections information in cache, together with cacherev.
|
// Set the accumulated activities and sections information in cache, together with cacherev.
|
||||||
$cachecoursemodinfo = cache::make('core', 'coursemodinfo');
|
$cachecoursemodinfo = cache::make('core', 'coursemodinfo');
|
||||||
$cachecoursemodinfo->set($course->id, $coursemodinfo);
|
$cachecoursemodinfo->set_versioned($course->id, $course->cacherev, $coursemodinfo);
|
||||||
return $coursemodinfo;
|
return $coursemodinfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,28 +260,28 @@ class modinfolib_test extends advanced_testcase {
|
|||||||
rebuild_course_cache($course->id, true);
|
rebuild_course_cache($course->id, true);
|
||||||
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
||||||
$this->assertGreaterThan($prevcacherev, $cacherev);
|
$this->assertGreaterThan($prevcacherev, $cacherev);
|
||||||
$this->assertEmpty($cache->get($course->id));
|
$this->assertEmpty($cache->get_versioned($course->id, $prevcacherev));
|
||||||
$prevcacherev = $cacherev;
|
$prevcacherev = $cacherev;
|
||||||
|
|
||||||
// Build course cache. Cacherev should not change but cache is now not empty. Make sure cacherev is the same everywhere.
|
// Build course cache. Cacherev should not change but cache is now not empty. Make sure cacherev is the same everywhere.
|
||||||
$modinfo = get_fast_modinfo($course->id);
|
$modinfo = get_fast_modinfo($course->id);
|
||||||
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
||||||
$this->assertEquals($prevcacherev, $cacherev);
|
$this->assertEquals($prevcacherev, $cacherev);
|
||||||
$cachedvalue = $cache->get($course->id);
|
$cachedvalue = $cache->get_versioned($course->id, $cacherev);
|
||||||
$this->assertNotEmpty($cachedvalue);
|
$this->assertNotEmpty($cachedvalue);
|
||||||
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
||||||
$this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
|
$this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
|
||||||
$prevcacherev = $cacherev;
|
$prevcacherev = $cacherev;
|
||||||
|
|
||||||
// Little trick to check that cache is not rebuilt druing the next step - substitute the value in MUC and later check that it is still there.
|
// Little trick to check that cache is not rebuilt druing the next step - substitute the value in MUC and later check that it is still there.
|
||||||
$cache->set($course->id, (object)array_merge((array)$cachedvalue, array('secretfield' => 1)));
|
$cache->set_versioned($course->id, $cacherev, (object)array_merge((array)$cachedvalue, array('secretfield' => 1)));
|
||||||
|
|
||||||
// Clear static cache and call get_fast_modinfo() again (pretend we are in another request). Cache should not be rebuilt.
|
// Clear static cache and call get_fast_modinfo() again (pretend we are in another request). Cache should not be rebuilt.
|
||||||
course_modinfo::clear_instance_cache();
|
course_modinfo::clear_instance_cache();
|
||||||
$modinfo = get_fast_modinfo($course->id);
|
$modinfo = get_fast_modinfo($course->id);
|
||||||
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
||||||
$this->assertEquals($prevcacherev, $cacherev);
|
$this->assertEquals($prevcacherev, $cacherev);
|
||||||
$cachedvalue = $cache->get($course->id);
|
$cachedvalue = $cache->get_versioned($course->id, $cacherev);
|
||||||
$this->assertNotEmpty($cachedvalue);
|
$this->assertNotEmpty($cachedvalue);
|
||||||
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
||||||
$this->assertNotEmpty($cachedvalue->secretfield);
|
$this->assertNotEmpty($cachedvalue->secretfield);
|
||||||
@ -292,7 +292,7 @@ class modinfolib_test extends advanced_testcase {
|
|||||||
rebuild_course_cache($course->id);
|
rebuild_course_cache($course->id);
|
||||||
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
||||||
$this->assertGreaterThan($prevcacherev, $cacherev);
|
$this->assertGreaterThan($prevcacherev, $cacherev);
|
||||||
$cachedvalue = $cache->get($course->id);
|
$cachedvalue = $cache->get_versioned($course->id, $cacherev);
|
||||||
$this->assertNotEmpty($cachedvalue);
|
$this->assertNotEmpty($cachedvalue);
|
||||||
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
||||||
$modinfo = get_fast_modinfo($course->id);
|
$modinfo = get_fast_modinfo($course->id);
|
||||||
@ -306,7 +306,7 @@ class modinfolib_test extends advanced_testcase {
|
|||||||
$modinfo = get_fast_modinfo($course->id);
|
$modinfo = get_fast_modinfo($course->id);
|
||||||
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
||||||
$this->assertGreaterThan($prevcacherev, $cacherev);
|
$this->assertGreaterThan($prevcacherev, $cacherev);
|
||||||
$cachedvalue = $cache->get($course->id);
|
$cachedvalue = $cache->get_versioned($course->id, $cacherev);
|
||||||
$this->assertNotEmpty($cachedvalue);
|
$this->assertNotEmpty($cachedvalue);
|
||||||
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
||||||
$this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
|
$this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
|
||||||
@ -316,10 +316,10 @@ class modinfolib_test extends advanced_testcase {
|
|||||||
rebuild_course_cache(0, true);
|
rebuild_course_cache(0, true);
|
||||||
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
$cacherev = $DB->get_field('course', 'cacherev', array('id' => $course->id));
|
||||||
$this->assertGreaterThan($prevcacherev, $cacherev);
|
$this->assertGreaterThan($prevcacherev, $cacherev);
|
||||||
$this->assertEmpty($cache->get($course->id));
|
$this->assertEmpty($cache->get_versioned($course->id, $cacherev));
|
||||||
// Rebuild again.
|
// Rebuild again.
|
||||||
$modinfo = get_fast_modinfo($course->id);
|
$modinfo = get_fast_modinfo($course->id);
|
||||||
$cachedvalue = $cache->get($course->id);
|
$cachedvalue = $cache->get_versioned($course->id, $cacherev);
|
||||||
$this->assertNotEmpty($cachedvalue);
|
$this->assertNotEmpty($cachedvalue);
|
||||||
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
$this->assertEquals($cacherev, $cachedvalue->cacherev);
|
||||||
$this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
|
$this->assertEquals($cacherev, $modinfo->get_course()->cacherev);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user