Skip to content

Commit

Permalink
MDL-67674 Cache: Lock rebuilding of the course category tree cache
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Johnson authored and stronk7 committed Jan 14, 2020
1 parent 383b0f9 commit 96e4404
Showing 1 changed file with 38 additions and 7 deletions.
45 changes: 38 additions & 7 deletions course/classes/category.php
Original file line number Diff line number Diff line change
Expand Up @@ -717,13 +717,49 @@ public function get_db_record() {
* @return mixed
*/
protected static function get_tree($id) {
global $DB;
$coursecattreecache = cache::make('core', 'coursecattree');
$rv = $coursecattreecache->get($id);
if ($rv !== false) {
return $rv;
}
// Might need to rebuild the tree. Put a lock in place to ensure other requests don't try and do this in parallel.
$lockfactory = \core\lock\lock_config::get_lock_factory('core_coursecattree');
$lock = $lockfactory->get_lock('core_coursecattree_cache',
course_modinfo::COURSE_CACHE_LOCK_WAIT, course_modinfo::COURSE_CACHE_LOCK_EXPIRY);
if ($lock === false) {
// Couldn't get a lock to rebuild the tree.
return [];
}
$rv = $coursecattreecache->get($id);
if ($rv !== false) {
// Tree was built while we were waiting for the lock.
$lock->release();
return $rv;
}
// Re-build the tree.
try {
$all = self::rebuild_coursecattree_cache_contents();
$coursecattreecache->set_many($all);
} finally {
$lock->release();
}
if (array_key_exists($id, $all)) {
return $all[$id];
}
// Requested non-existing category.
return array();
}

/**
* Rebuild the course category tree as an array, including an extra "countall" field.
*
* @return array
* @throws coding_exception
* @throws dml_exception
* @throws moodle_exception
*/
private static function rebuild_coursecattree_cache_contents() : array {
global $DB;
$sql = "SELECT cc.id, cc.parent, cc.visible
FROM {course_categories} cc
ORDER BY cc.sortorder";
Expand Down Expand Up @@ -760,12 +796,7 @@ protected static function get_tree($id) {
}
// We must add countall to all in case it was the requested ID.
$all['countall'] = $count;
$coursecattreecache->set_many($all);
if (array_key_exists($id, $all)) {
return $all[$id];
}
// Requested non-existing category.
return array();
return $all;
}

/**
Expand Down

0 comments on commit 96e4404

Please sign in to comment.