diff --git a/admin/settings/server.php b/admin/settings/server.php index 461f06c06ad..7b11f4e7527 100644 --- a/admin/settings/server.php +++ b/admin/settings/server.php @@ -216,6 +216,16 @@ $temp->add(new admin_setting_configselect('memcachedpconn', new lang_string('mem array( '0' => new lang_string('no'), '1' => new lang_string('yes')))); */ + +$ADMIN->add('server', new admin_category('cache', new lang_string('caching', 'cache'))); +$ADMIN->add('cache', new admin_externalpage('cacheconfig', get_string('cacheconfig', 'cache'), new moodle_url('/cache/admin.php'))); +$ADMIN->add('cache', new admin_externalpage('cachetestperformance', get_string('testperformance', 'cache'), new moodle_url('/cache/testperformance.php'))); +foreach (get_plugin_list_with_file('cache', 'settings.php') as $plugin => $path) { + $settings = new admin_settingpage('cache_'.$plugin.'_settings', new lang_string('pluginname', 'cache_'.$plugin)); + require_once($path); + $ADMIN->add('cache', $settings); +} + $ADMIN->add('server', $temp); diff --git a/lang/en/admin.php b/lang/en/admin.php index b67ce851629..6a2c0c84e40 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -1072,3 +1072,13 @@ $string['webproxyinfo'] = 'Fill in following options if your Moodle server can n $string['xmlrpcrecommended'] = 'The xmlrpc extension is needed for hub communication, and useful for web services and Moodle networking'; $string['yuicomboloading'] = 'YUI combo loading'; $string['ziprequired'] = 'The Zip PHP extension is now required by Moodle, info-ZIP binaries or PclZip library are not used anymore.'; + + +$string['caching'] = 'Caching'; +$string['cachesettings'] = 'Cache settings'; +$string['cacherequest'] = 'Request cache'; +$string['cacherequesthelp'] = 'User specific cache that expires when the request is complete. Designed to replace areas where we are using the static stores.'; +$string['cachesession'] = 'Session cache'; +$string['cachesessionhelp'] = 'User specific cache that expires when the users session ends. Designed to aleviate session bloat/strain.'; +$string['cacheapplication'] = 'Application cache'; +$string['cacheapplicationhelp'] = ' Cached items are shared amoung all users and expire by a determined ttl.'; diff --git a/lang/en/cache.php b/lang/en/cache.php new file mode 100644 index 00000000000..39ca143c063 --- /dev/null +++ b/lang/en/cache.php @@ -0,0 +1,84 @@ + array( + 'mode' => cache_store::MODE_APPLICATION, + 'mappingsonly' => true, + ), + 'string' => array( + 'mode' => cache_store::MODE_APPLICATION, + 'component' => 'core', + 'area' => 'string', + 'persistent' => true, + 'persistentmaxsize' => 3 + ), + 'databasemeta' => array( + 'mode' => cache_store::MODE_APPLICATION, + 'requireidentifiers' => array( + 'dbfamily' + ), + 'persistent' => true, + 'persistentmaxsize' => 2 + ), + 'config' => array( + 'mode' => cache_store::MODE_APPLICATION, + 'persistent' => true + ), + // Event invalidation cache + 'eventinvalidation' => array( + 'mode' => cache_store::MODE_APPLICATION, + 'persistent' => true, + 'requiredataguarantee' => true + ) +); diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 7e2eebe355c..83db6b7b5e5 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -1498,6 +1498,8 @@ function purge_all_caches() { get_string_manager()->reset_caches(); textlib::reset_caches(); + cache_helper::purge_all(); + // purge all other caches: rss, simplepie, etc. remove_dir($CFG->cachedir.'', true); @@ -7906,6 +7908,7 @@ function get_core_subsystems() { 'block' => 'blocks', 'blog' => 'blog', 'bulkusers' => NULL, + 'cache' => 'cache', 'calendar' => 'calendar', 'cohort' => 'cohort', 'condition' => NULL, @@ -8004,6 +8007,7 @@ function get_plugin_types($fullpaths=true) { 'qformat' => 'question/format', 'plagiarism' => 'plagiarism', 'tool' => $CFG->admin.'/tool', + 'cache' => 'cache/stores', 'theme' => 'theme', // this is a bit hacky, themes may be in $CFG->themedir too ); @@ -10425,6 +10429,37 @@ function get_performance_info() { $info['txt'] .= 'rcache: '. "{$rcache->hits}/{$rcache->misses} "; }*/ + + if ($stats = cache_helper::get_stats()) { + $html = ''; + $html .= 'Caches interaction by definition then store'; + $text = 'Caches used (hits/misses/sets): '; + $hits = 0; + $misses = 0; + $sets = 0; + foreach ($stats as $definition => $stores) { + $html .= ''.$definition.''; + $text .= "$definition {"; + foreach ($stores as $store => $data) { + $hits += $data['hits']; + $misses += $data['misses']; + $sets += $data['sets']; + $text .= "$store($data[hits]/$data[misses]/$data[sets]) "; + $html .= "$store: $data[hits] / $data[misses] / $data[sets]"; + } + $text .= '} '; + } + $html .= "Total Hits / Misses / Sets : $hits / $misses / $sets"; + $html .= ' '; + $info['cachesused'] = "$hits / $misses / $sets"; + $info['html'] .= $html; + $info['txt'] .= $text.'. '; + } else { + $info['cachesused'] = '0 / 0 / 0'; + $info['html'] .= 'Caches used (hits/misses/sets): 0/0/0'; + $info['txt'] .= 'Caches used (hits/misses/sets): 0/0/0 '; + } + $info['html'] = '
'.$info['html'].'
'; return $info; } diff --git a/lib/setup.php b/lib/setup.php index 54b0a971662..7914283018c 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -138,6 +138,14 @@ if (!defined('PHPUNIT_TEST')) { define('PHPUNIT_TEST', false); } +// When set to true MUC (Moodle caching) will not use any of the defined or default stores. +// The Cache API will continue to function however this will force the use of the cache_store_dummy so all requests +// will be interacting with a static property and will never go to the proper cache stores. +// Useful if you need to avoid the stores for one reason or another. +if (!defined('NO_CACHE_STORES')) { + define('NO_CACHE_STORES', false); +} + // Servers should define a default timezone in php.ini, but if they don't then make sure something is defined. // This is a quick hack. Ideally we should ask the admin for a value. See MDL-22625 for more on this. if (function_exists('date_default_timezone_set') and function_exists('date_default_timezone_get')) { @@ -468,6 +476,7 @@ require_once($CFG->libdir .'/sessionlib.php'); // All session and cookie re require_once($CFG->libdir .'/editorlib.php'); // All text editor related functions and classes require_once($CFG->libdir .'/messagelib.php'); // Messagelib functions require_once($CFG->libdir .'/modinfolib.php'); // Cached information on course-module instances +require_once($CFG->dirroot.'/cache/lib.php'); // Cache API // make sure PHP is not severly misconfigured setup_validate_php_configuration(); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index cf5e58a2a9b..d62dd73f82f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -66,6 +66,9 @@ question/tests question/type/tests + + cache/tests + diff --git a/theme/base/style/admin.css b/theme/base/style/admin.css index ceafc02e5b2..8b7b19a78c6 100644 --- a/theme/base/style/admin.css +++ b/theme/base/style/admin.css @@ -256,3 +256,11 @@ #page-admin-mnet-peers .box.deletedhosts {margin-bottom:1em;font-size:80%;} #page-admin-mnet-peers .mform .certdetails {background-color:white;} #page-admin-mnet-peers .mform .deletedhostinfo {background-color:#ffd3d9;border 2px solid #eeaaaa;padding:4px;margin-bottom:5px;} + +#core-cache-plugin-summaries table, +#core-cache-store-summaries table {width:100%;} +#core-cache-definition-summaries table, +#core-cache-mode-mappings table {margin:0 auto;} +#core-cache-store-summaries .default-store td {color:#333;font-style: italic;} +#core-cache-rescan-definitions, +#core-cache-mode-mappings .edit-link {margin-top:0.5em;text-align:center;} \ No newline at end of file diff --git a/theme/base/style/core.css b/theme/base/style/core.css index d91d8d90565..400abbb1a0d 100644 --- a/theme/base/style/core.css +++ b/theme/base/style/core.css @@ -184,6 +184,12 @@ a.skip:active {position: static;display: block;} #page-footer .validators ul {margin:0px;padding:0px;list-style-type:none;} #page-footer .validators ul li {display:inline;margin-right:10px;margin-left:10px;} +.performanceinfo .cachesused {margin-top:1em;} +.performanceinfo .cachesused .cache-stats-heading {font-weight: bold;text-decoration: underline;font-size:110%;} +.performanceinfo .cachesused .cache-definition-stats {font-weight:bold;margin-top:0.3em;} +.performanceinfo .cachesused .cache-store-stats {text-indent: 1em;} +.performanceinfo .cachesused .cache-total-stats {font-weight:bold;margin-top:0.3em;} + /** * Tabs */