From: sam_marshall Date: Mon, 6 Apr 2009 09:48:39 +0000 (+0000) Subject: MDL-18768: Limited size of context and modinfo caches to avoid memory problems with... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=4d10247fdb2027fb80782262c16838b55217ec7a;p=moodle.git MDL-18768: Limited size of context and modinfo caches to avoid memory problems with code that loops through many courses, also changed forum role_assign to use recordset for all-courses loops --- diff --git a/course/lib.php b/course/lib.php index 2d906cf150..1810a5a18d 100644 --- a/course/lib.php +++ b/course/lib.php @@ -22,6 +22,9 @@ define('FIRSTUSEDEXCELROW', 3); define('MOD_CLASS_ACTIVITY', 0); define('MOD_CLASS_RESOURCE', 1); +if (!defined('MAX_MODINFO_CACHE_SIZE')) { + define('MAX_MODINFO_CACHE_SIZE', 10); +} function make_log_url($module, $url) { switch ($module) { @@ -1254,6 +1257,11 @@ function &get_fast_modinfo(&$course, $userid=0) { unset($cache[$course->id]); // prevent potential reference problems when switching users $cache[$course->id] = $modinfo; + // Ensure cache does not use too much RAM + if (count($cache) > MAX_MODINFO_CACHE_SIZE) { + array_shift($cache); + } + return $cache[$course->id]; } diff --git a/lib/accesslib.php b/lib/accesslib.php index 53019e47ee..17b37cb4e4 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -161,6 +161,11 @@ define('ROLENAME_BOTH', 2); // Both, like this: Role alias (Original) define('ROLENAME_ORIGINALANDSHORT', 3); // the name as defined in the role definition and the shortname in brackets define('ROLENAME_ALIAS_RAW', 4); // the name as defined by a role alias, in raw form suitable for editing +// size limit for context cache +if (!defined('MAX_CONTEXT_CACHE_SIZE')) { + define('MAX_CONTEXT_CACHE_SIZE', 5000); +} + // Although this looks like a global variable, it isn't really. It is just a private // implementation detail to accesslib that MUST NOT be used elsewhere. It is used to // cache various bits of data between function calls for performance reasons. Sadly, @@ -205,6 +210,14 @@ function accesslib_clear_all_caches_for_unit_testing() { */ function cache_context($context) { global $ACCESSLIB_PRIVATE; + + // If there are too many items in the cache already, remove items until + // there is space + while (count($ACCESSLIB_PRIVATE->contextsbyid) >= MAX_CONTEXT_CACHE_SIZE) { + $first = array_shift($ACCESSLIB_PRIVATE->contextsbyid); + unset($ACCESSLIB_PRIVATE->contexts[$first->contextlevel][$first->instanceid]); + } + $ACCESSLIB_PRIVATE->contexts[$context->contextlevel][$context->instanceid] = $context; $ACCESSLIB_PRIVATE->contextsbyid[$context->id] = $context; } diff --git a/mod/forum/lib.php b/mod/forum/lib.php index ebf30f3799..255f0b90f1 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -5782,21 +5782,21 @@ function forum_add_user_default_subscriptions($userid, $context) { switch ($context->contextlevel) { case CONTEXT_SYSTEM: // For the whole site - if ($courses = $DB->get_records('course')) { - foreach ($courses as $course) { - $subcontext = get_context_instance(CONTEXT_COURSE, $course->id); - forum_add_user_default_subscriptions($userid, $subcontext); - } + $rs = $DB->get_recordset('course',null,'','id'); + foreach ($rs as $course) { + $subcontext = get_context_instance(CONTEXT_COURSE, $course->id); + forum_add_user_default_subscriptions($userid, $subcontext); } + $rs->close(); break; case CONTEXT_COURSECAT: // For a whole category - if ($courses = $DB->get_records('course', array('category' => $context->instanceid))) { - foreach ($courses as $course) { - $subcontext = get_context_instance(CONTEXT_COURSE, $course->id); - forum_add_user_default_subscriptions($userid, $subcontext); - } + $rs = $DB->get_recordset('course', array('category' => $context->instanceid),'','id'); + foreach ($rs as $course) { + $subcontext = get_context_instance(CONTEXT_COURSE, $course->id); + forum_add_user_default_subscriptions($userid, $subcontext); } + $rs->close(); if ($categories = $DB->get_records('course_categories', array('parent' => $context->instanceid))) { foreach ($categories as $category) { $subcontext = get_context_instance(CONTEXT_COURSECAT, $category->id);