mirror of
https://github.com/moodle/moodle.git
synced 2025-08-09 10:56:56 +02:00
Merge branch 'MDL-80985-add-purge-course-caches-option-main' of https://github.com/jwcatau/moodle
This commit is contained in:
commit
5c16854483
4 changed files with 204 additions and 1 deletions
|
@ -31,6 +31,7 @@ require_once($CFG->libdir.'/clilib.php');
|
||||||
$longoptions = [
|
$longoptions = [
|
||||||
'help' => false,
|
'help' => false,
|
||||||
'muc' => false,
|
'muc' => false,
|
||||||
|
'courses' => false,
|
||||||
'theme' => false,
|
'theme' => false,
|
||||||
'lang' => false,
|
'lang' => false,
|
||||||
'js' => false,
|
'js' => false,
|
||||||
|
@ -55,6 +56,8 @@ all caches will be purged.
|
||||||
Options:
|
Options:
|
||||||
-h, --help Print out this help
|
-h, --help Print out this help
|
||||||
--muc Purge all MUC caches (includes lang cache)
|
--muc Purge all MUC caches (includes lang cache)
|
||||||
|
--courses Purge all course caches (or only those specified by a comma-separated list).
|
||||||
|
e.g. --courses=4,67,145
|
||||||
--theme Purge theme cache
|
--theme Purge theme cache
|
||||||
--lang Purge language string cache
|
--lang Purge language string cache
|
||||||
--js Purge JavaScript cache
|
--js Purge JavaScript cache
|
||||||
|
|
|
@ -850,6 +850,39 @@ class course_modinfo {
|
||||||
self::purge_course_modules_cache($courseid, [$cmid]);
|
self::purge_course_modules_cache($courseid, [$cmid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purges the coursemodinfo caches stored in MUC.
|
||||||
|
*
|
||||||
|
* @param int[] $courseids Array of course ids to purge the course caches
|
||||||
|
* for (or all courses if empty array).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static function purge_course_caches(array $courseids = []): void {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
// Purging might purge all course caches, so use a recordset and close it.
|
||||||
|
$select = '';
|
||||||
|
$params = null;
|
||||||
|
if (!empty($courseids)) {
|
||||||
|
[$sql, $params] = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
|
||||||
|
$select = 'id ' . $sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
$courses = $DB->get_recordset_select(
|
||||||
|
table: 'course',
|
||||||
|
select: $select,
|
||||||
|
params: $params,
|
||||||
|
fields: 'id',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Purge each course's cache to make sure cache is recalculated next time
|
||||||
|
// the course is viewed.
|
||||||
|
foreach ($courses as $course) {
|
||||||
|
self::purge_course_cache($course->id);
|
||||||
|
}
|
||||||
|
$courses->close();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Purge the cache of multiple course modules.
|
* Purge the cache of multiple course modules.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1191,7 +1191,7 @@ function purge_all_caches() {
|
||||||
* 'other' Purge all other caches?
|
* 'other' Purge all other caches?
|
||||||
*/
|
*/
|
||||||
function purge_caches($options = []) {
|
function purge_caches($options = []) {
|
||||||
$defaults = array_fill_keys(['muc', 'theme', 'lang', 'js', 'template', 'filter', 'other'], false);
|
$defaults = array_fill_keys(['muc', 'courses', 'theme', 'lang', 'js', 'template', 'filter', 'other'], false);
|
||||||
if (empty(array_filter($options))) {
|
if (empty(array_filter($options))) {
|
||||||
$options = array_fill_keys(array_keys($defaults), true); // Set all options to true.
|
$options = array_fill_keys(array_keys($defaults), true); // Set all options to true.
|
||||||
} else {
|
} else {
|
||||||
|
@ -1200,6 +1200,14 @@ function purge_caches($options = []) {
|
||||||
if ($options['muc']) {
|
if ($options['muc']) {
|
||||||
cache_helper::purge_all();
|
cache_helper::purge_all();
|
||||||
}
|
}
|
||||||
|
if ($options['courses']) {
|
||||||
|
if ($options['courses'] === true) {
|
||||||
|
$courseids = [];
|
||||||
|
} else {
|
||||||
|
$courseids = preg_split('/\s*,\s*/', $options['courses'], -1, PREG_SPLIT_NO_EMPTY);
|
||||||
|
}
|
||||||
|
course_modinfo::purge_course_caches($courseids);
|
||||||
|
}
|
||||||
if ($options['theme']) {
|
if ($options['theme']) {
|
||||||
theme_reset_all_caches();
|
theme_reset_all_caches();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1572,4 +1572,163 @@ class modinfolib_test extends advanced_testcase {
|
||||||
$this->assertFalse($sectioninfos[1]->is_delegated());
|
$this->assertFalse($sectioninfos[1]->is_delegated());
|
||||||
$this->assertTrue($sectioninfos[2]->is_delegated());
|
$this->assertTrue($sectioninfos[2]->is_delegated());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the course_modinfo::purge_course_caches() function with a
|
||||||
|
* one-course array, a two-course array, and an empty array, and ensure
|
||||||
|
* that only the courses specified have their course cache version
|
||||||
|
* incremented (or all course caches if none specified).
|
||||||
|
*
|
||||||
|
* @covers \course_modinfo
|
||||||
|
*/
|
||||||
|
public function test_multiple_modinfo_cache_purge(): void {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$this->resetAfterTest();
|
||||||
|
$this->setAdminUser();
|
||||||
|
$cache = cache::make('core', 'coursemodinfo');
|
||||||
|
|
||||||
|
// Generate two courses and pre-requisite modules for targeted course
|
||||||
|
// cache tests.
|
||||||
|
$courseone = $this->getDataGenerator()->create_course(
|
||||||
|
[
|
||||||
|
'format' => 'topics',
|
||||||
|
'numsections' => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'createsections' => true,
|
||||||
|
]);
|
||||||
|
$coursetwo = $this->getDataGenerator()->create_course(
|
||||||
|
[
|
||||||
|
'format' => 'topics',
|
||||||
|
'numsections' => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'createsections' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$coursethree = $this->getDataGenerator()->create_course(
|
||||||
|
[
|
||||||
|
'format' => 'topics',
|
||||||
|
'numsections' => 3,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'createsections' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Make sure the cacherev is set for all three.
|
||||||
|
$cacherevone = $DB->get_field('course', 'cacherev', ['id' => $courseone->id]);
|
||||||
|
$this->assertGreaterThan(0, $cacherevone);
|
||||||
|
$prevcacherevone = $cacherevone;
|
||||||
|
|
||||||
|
$cacherevtwo = $DB->get_field('course', 'cacherev', ['id' => $coursetwo->id]);
|
||||||
|
$this->assertGreaterThan(0, $cacherevtwo);
|
||||||
|
$prevcacherevtwo = $cacherevtwo;
|
||||||
|
|
||||||
|
$cacherevthree = $DB->get_field('course', 'cacherev', ['id' => $coursethree->id]);
|
||||||
|
$this->assertGreaterThan(0, $cacherevthree);
|
||||||
|
$prevcacherevthree = $cacherevthree;
|
||||||
|
|
||||||
|
// Reset course caches and make sure cacherev is bumped up but cache is empty.
|
||||||
|
rebuild_course_cache($courseone->id, true);
|
||||||
|
$cacherevone = $DB->get_field('course', 'cacherev', ['id' => $courseone->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevone, $cacherevone);
|
||||||
|
$this->assertEmpty($cache->get_versioned($courseone->id, $prevcacherevone));
|
||||||
|
$prevcacherevone = $cacherevone;
|
||||||
|
|
||||||
|
rebuild_course_cache($coursetwo->id, true);
|
||||||
|
$cacherevtwo = $DB->get_field('course', 'cacherev', ['id' => $coursetwo->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevtwo, $cacherevtwo);
|
||||||
|
$this->assertEmpty($cache->get_versioned($coursetwo->id, $prevcacherevtwo));
|
||||||
|
$prevcacherevtwo = $cacherevtwo;
|
||||||
|
|
||||||
|
rebuild_course_cache($coursethree->id, true);
|
||||||
|
$cacherevthree = $DB->get_field('course', 'cacherev', ['id' => $coursethree->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevthree, $cacherevthree);
|
||||||
|
$this->assertEmpty($cache->get_versioned($coursethree->id, $prevcacherevthree));
|
||||||
|
$prevcacherevthree = $cacherevthree;
|
||||||
|
|
||||||
|
// Build course caches. Cacherev should not change but caches are now not empty. Make sure cacherev is the same everywhere.
|
||||||
|
$modinfoone = get_fast_modinfo($courseone->id);
|
||||||
|
$cacherevone = $DB->get_field('course', 'cacherev', ['id' => $courseone->id]);
|
||||||
|
$this->assertEquals($prevcacherevone, $cacherevone);
|
||||||
|
$cachedvalueone = $cache->get_versioned($courseone->id, $cacherevone);
|
||||||
|
$this->assertNotEmpty($cachedvalueone);
|
||||||
|
$this->assertEquals($cacherevone, $cachedvalueone->cacherev);
|
||||||
|
$this->assertEquals($cacherevone, $modinfoone->get_course()->cacherev);
|
||||||
|
$prevcacherevone = $cacherevone;
|
||||||
|
|
||||||
|
$modinfotwo = get_fast_modinfo($coursetwo->id);
|
||||||
|
$cacherevtwo = $DB->get_field('course', 'cacherev', ['id' => $coursetwo->id]);
|
||||||
|
$this->assertEquals($prevcacherevtwo, $cacherevtwo);
|
||||||
|
$cachedvaluetwo = $cache->get_versioned($coursetwo->id, $cacherevtwo);
|
||||||
|
$this->assertNotEmpty($cachedvaluetwo);
|
||||||
|
$this->assertEquals($cacherevtwo, $cachedvaluetwo->cacherev);
|
||||||
|
$this->assertEquals($cacherevtwo, $modinfotwo->get_course()->cacherev);
|
||||||
|
$prevcacherevtwo = $cacherevtwo;
|
||||||
|
|
||||||
|
$modinfothree = get_fast_modinfo($coursethree->id);
|
||||||
|
$cacherevthree = $DB->get_field('course', 'cacherev', ['id' => $coursethree->id]);
|
||||||
|
$this->assertEquals($prevcacherevthree, $cacherevthree);
|
||||||
|
$cachedvaluethree = $cache->get_versioned($coursethree->id, $cacherevthree);
|
||||||
|
$this->assertNotEmpty($cachedvaluethree);
|
||||||
|
$this->assertEquals($cacherevthree, $cachedvaluethree->cacherev);
|
||||||
|
$this->assertEquals($cacherevthree, $modinfothree->get_course()->cacherev);
|
||||||
|
$prevcacherevthree = $cacherevthree;
|
||||||
|
|
||||||
|
// Purge course one's cache. Cacherev must be incremented (but only for
|
||||||
|
// course one, check course two and three in next step).
|
||||||
|
course_modinfo::purge_course_caches([$courseone->id]);
|
||||||
|
|
||||||
|
get_fast_modinfo($courseone->id);
|
||||||
|
$cacherevone = $DB->get_field('course', 'cacherev', ['id' => $courseone->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevone, $cacherevone);
|
||||||
|
$prevcacherevone = $cacherevone;
|
||||||
|
|
||||||
|
// Confirm course two and three's cache shouldn't have been affected.
|
||||||
|
get_fast_modinfo($coursetwo->id);
|
||||||
|
$cacherevtwo = $DB->get_field('course', 'cacherev', ['id' => $coursetwo->id]);
|
||||||
|
$this->assertEquals($prevcacherevtwo, $cacherevtwo);
|
||||||
|
$prevcacherevtwo = $cacherevtwo;
|
||||||
|
|
||||||
|
get_fast_modinfo($coursethree->id);
|
||||||
|
$cacherevthree = $DB->get_field('course', 'cacherev', ['id' => $coursethree->id]);
|
||||||
|
$this->assertEquals($prevcacherevthree, $cacherevthree);
|
||||||
|
$prevcacherevthree = $cacherevthree;
|
||||||
|
|
||||||
|
// Purge course two and three's cache. Cacherev must be incremented (but only for
|
||||||
|
// course two and three, then check course one hasn't changed in next step).
|
||||||
|
course_modinfo::purge_course_caches([$coursetwo->id, $coursethree->id]);
|
||||||
|
|
||||||
|
get_fast_modinfo($coursetwo->id);
|
||||||
|
$cacherevtwo = $DB->get_field('course', 'cacherev', ['id' => $coursetwo->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevtwo, $cacherevtwo);
|
||||||
|
$prevcacherevtwo = $cacherevtwo;
|
||||||
|
|
||||||
|
get_fast_modinfo($coursethree->id);
|
||||||
|
$cacherevthree = $DB->get_field('course', 'cacherev', ['id' => $coursethree->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevthree, $cacherevthree);
|
||||||
|
$prevcacherevthree = $cacherevthree;
|
||||||
|
|
||||||
|
// Confirm course one's cache shouldn't have been affected.
|
||||||
|
get_fast_modinfo($courseone->id);
|
||||||
|
$cacherevone = $DB->get_field('course', 'cacherev', ['id' => $courseone->id]);
|
||||||
|
$this->assertEquals($prevcacherevone, $cacherevone);
|
||||||
|
$prevcacherevone = $cacherevone;
|
||||||
|
|
||||||
|
// Purge all course caches. Cacherev must be incremented for all three courses.
|
||||||
|
course_modinfo::purge_course_caches();
|
||||||
|
get_fast_modinfo($courseone->id);
|
||||||
|
$cacherevone = $DB->get_field('course', 'cacherev', ['id' => $courseone->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevone, $cacherevone);
|
||||||
|
|
||||||
|
get_fast_modinfo($coursetwo->id);
|
||||||
|
$cacherevtwo = $DB->get_field('course', 'cacherev', ['id' => $coursetwo->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevtwo, $cacherevtwo);
|
||||||
|
|
||||||
|
get_fast_modinfo($coursethree->id);
|
||||||
|
$cacherevthree = $DB->get_field('course', 'cacherev', ['id' => $coursethree->id]);
|
||||||
|
$this->assertGreaterThan($prevcacherevthree, $cacherevthree);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue