Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MBS-8702: Improve caching #93

Merged
merged 13 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion amd/build/placestore.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion amd/build/placestore.min.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions amd/src/placestore.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
let placestore = {
version: 2024012601,
version: 2024021901,
id: 0,
places: [],
paths: [],
Expand Down Expand Up @@ -36,7 +36,7 @@ let placestore = {
// eslint-disable-next-line no-empty
} catch { }
// Update version (only relevant if learning map is saved)
this.version = 2024012601;
this.version = 2024021901;
},
/**
* Returns placestore as a JSON string ()
Expand Down
4 changes: 2 additions & 2 deletions backup/moodle2/restore_learningmap_activity_task.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ public function after_restore(): void {
$item->intro = str_replace('learningmap-svgmap-' . $oldmapid, 'learningmap-svgmap-' . $newmapid, $item->intro);
$placestore->mapid = $newmapid;

if (!isset($placestore->version) || $placestore->version < 2024012601) {
$placestore->version = 2024012601;
if (!isset($placestore->version) || $placestore->version < 2024021901) {
$placestore->version = 2024021901;
// Needs 1 as default value (otherwise all place strokes would be hidden).
if (!isset($placestore->strokeopacity)) {
$placestore->strokeopacity = 1;
Expand Down
10 changes: 3 additions & 7 deletions classes/autoupdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public static function update_from_delete_event(\core\event\base $event): void {
foreach ($placestore->places as $p) {
if ($p->linkedActivity == $data['objectid']) {
$p->linkedActivity = null;
cachemanager::remove_cmid($data['objectid']);
PhMemmel marked this conversation as resolved.
Show resolved Hide resolved
$changed = true;
}
}
Expand All @@ -104,14 +105,9 @@ public static function update_from_delete_event(\core\event\base $event): void {
* @return void
*/
public static function reset_backlink_cache(\core\event\base $event): void {
$data = $event->get_data();
if (isset($data['courseid']) && $data['courseid'] > 0) {
$course = $data['courseid'];
$cache = \cache::make('mod_learningmap', 'backlinks');
$modinfo = get_fast_modinfo($course);
$cms = $modinfo->get_cms();
foreach ($cms as $cm) {
$cache->delete($cm->id);
}
cachemanager::reset_backlink_cache($data['courseid']);
}
}
}
101 changes: 101 additions & 0 deletions classes/cachemanager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace mod_learningmap;

/**
* Cache manager class for mod_learningmap
*
* @package mod_learningmap
* @copyright 2021-2024, ISB Bayern
* @author Stefan Hanauska <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cachemanager {
/**
* Reset the backlink cache for a course (includes rebuilding it) or the whole instance (if $courseid is 0).
*
* @param int $courseid The id of the course (defaults to 0).
* @return void
*/
public static function reset_backlink_cache(int $courseid = 0): void {
$cache = \cache::make('mod_learningmap', 'backlinks');
if (empty($courseid)) {
$cache->purge();
sh-csg marked this conversation as resolved.
Show resolved Hide resolved
} else {
$modinfo = get_fast_modinfo($courseid);
$cms = $modinfo->get_cms();
$cache->delete_many(array_keys($cms));
}
self::build_backlink_cache($courseid);
}

/**
* Builds the backlink cache for a course or for the whole instance (e.g. after purging the cache).
sh-csg marked this conversation as resolved.
Show resolved Hide resolved
* Building the cache for a course should only be used as a fallback if the cache is not filled for the whole instance.
*
* @param int $courseid Id of the course, if 0 the cache will be built for the whole instance.
* @return void
*/
public static function build_backlink_cache(int $courseid = 0) {
global $DB;
$backlinks = [];
$cache = \cache::make('mod_learningmap', 'backlinks');

$conditions = ['backlink' => 1];
if (!empty($courseid)) {
$conditions['course'] = $courseid;
}

$records = $DB->get_recordset('learningmap', $conditions, '', 'id, placestore, backlink, course');
foreach ($records as $record) {
$modinfo = get_fast_modinfo($record->course);
$module = $modinfo->instances['learningmap'][$record->id];
$placestore = json_decode($record->placestore);
$coursepageurl = course_get_format($module->course)->get_view_url($module->sectionnum);
sh-csg marked this conversation as resolved.
Show resolved Hide resolved
$coursepageurl->set_anchor('module-' . $module->id);
foreach ($placestore->places as $place) {
$url = !empty($module->showdescription) ?
$coursepageurl->out() :
new \moodle_url('/mod/learningmap/view.php', ['id' => $module->id]);
$backlinks[$place->linkedActivity][$module->id] = [
'url' => $url,
'name' => $module->name,
'cmid' => $module->id,
];
}
}

foreach ($backlinks as $cmid => $backlink) {
$cache->set($cmid, $backlink);
}

if (empty($courseid)) {
$cache->set('fillstate', time());
sh-csg marked this conversation as resolved.
Show resolved Hide resolved
}
}

/**
* Removes a cmid from the backlink cache (e.g. when the course module was deleted).
*
* @param int $cmid Course module id
* @return void
*/
public static function remove_cmid(int $cmid) {
$cache = \cache::make('mod_learningmap', 'backlinks');
$cache->delete($cmid);
}
}
57 changes: 57 additions & 0 deletions classes/task/fill_backlink_cache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

namespace mod_learningmap\task;

use mod_learningmap\cachemanager;
sh-csg marked this conversation as resolved.
Show resolved Hide resolved

/**
* Task to fill backlink cache.
*
* @package mod_learningmap
* @copyright 2021-2024, ISB Bayern
* @author Stefan Hanauska
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class fill_backlink_cache extends \core\task\scheduled_task {
/**
* Get a descriptive name for this task (shown to admins).
*
* @return string
*/
public function get_name() {
return get_string('fill_backlink_cache_task', 'mod_learningmap');
}

/**
* Fill backlink cache.
*/
public function execute() {
$cache = \cache::make('mod_learningmap', 'backlinks');

$fillstate = $cache->get('fillstate');

// If the cache is filled within the last 24 hours, do nothing.
if (!empty($fillstate) && $fillstate < time() - 60 * 60 * 24) {
sh-csg marked this conversation as resolved.
Show resolved Hide resolved
mtrace('Backlink cache is already filled within the last 24 hours. Exiting.');
return;
}

mtrace('Building backlink cache started...');
cachemanager::build_backlink_cache();
sh-csg marked this conversation as resolved.
Show resolved Hide resolved
mtrace('Building backlink cache finished.');
}
}
4 changes: 4 additions & 0 deletions db/events.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@
'eventname' => '\core\event\course_module_updated',
'callback' => '\mod_learningmap\autoupdate::reset_backlink_cache',
],
[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment that this is needed in case the course format changed. Maybe it would also be nice to make a separate callback function handling this event because it should be possible to extract if the event actually was caused by a course format change?

Currently the cache is rebuilt on every course update, right?

'eventname' => '\core\event\course_updated',
'callback' => '\mod_learningmap\autoupdate::reset_backlink_cache',
],
];
39 changes: 39 additions & 0 deletions db/tasks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Scheduled task definitions for mod_learningmap
*
* @package mod_learningmap
* @copyright 2021-2024, ISB Bayern
* @author Stefan Hanauska
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

$tasks = [
[
'classname' => 'mod_learningmap\task\fill_backlink_cache',
'blocking' => 1,
'minute' => '*/5',
'hour' => '*',
'day' => '*',
'month' => '*',
'dayofweek' => '*',
'faildelay' => 1,
],
];
Loading
Loading