MDL-25290 cache: Added UI to view the cache lock setups and tidied up a couple of things

This commit is contained in:
Sam Hemelryk 2012-09-18 13:34:56 +12:00
parent 34c84c723a
commit 167ad91e86
8 changed files with 176 additions and 49 deletions

14
cache/admin.php vendored
View File

@ -39,6 +39,7 @@ $stores = cache_administration_helper::get_store_summaries();
$plugins = cache_administration_helper::get_plugin_summaries();
$definitions = cache_administration_helper::get_definition_summaries();
$defaultmodestores = cache_administration_helper::get_default_mode_stores();
$locks = cache_administration_helper::get_lock_summaries();
$title = new lang_string('cacheadmin', 'cache');
$mform = null;
@ -60,6 +61,12 @@ if (!empty($action) && confirm_sesskey()) {
} else if ($data = $mform->get_data()) {
$config = cache_administration_helper::get_store_configuration_from_data($data);
$writer = cache_config_writer::instance();
unset($config['lock']);
foreach ($writer->get_locks() as $lock => $lockconfig) {
if ($lock == $data->lock) {
$config['lock'] = $data->lock;
}
}
$writer->add_plugin_instance($data->name, $data->plugin, $config);
redirect($PAGE->url, get_string('addstoresuccess', 'cache', $plugins[$plugin]['name']), 5);
}
@ -74,6 +81,12 @@ if (!empty($action) && confirm_sesskey()) {
} else if ($data = $mform->get_data()) {
$config = cache_administration_helper::get_store_configuration_from_data($data);
$writer = cache_config_writer::instance();
unset($config['lock']);
foreach ($writer->get_locks() as $lock => $lockconfig) {
if ($lock == $data->lock) {
$config['lock'] = $data->lock;
}
}
$writer->edit_plugin_instance($data->name, $data->plugin, $config);
redirect($PAGE->url, get_string('editstoresuccess', 'cache', $plugins[$plugin]['name']), 5);
}
@ -172,6 +185,7 @@ if ($mform instanceof moodleform) {
echo $renderer->plugin_summaries($plugins);
echo $renderer->store_summariers($stores, $plugins);
echo $renderer->definition_summaries($definitions, cache_administration_helper::get_definition_actions($context));
echo $renderer->lock_summaries($locks);
$applicationstore = join(', ', $defaultmodestores[cache_store::MODE_APPLICATION]);
$sessionstore = join(', ', $defaultmodestores[cache_store::MODE_SESSION]);

View File

@ -141,7 +141,8 @@ class cache_config {
debugging('Duplicate cache lock detected. This should never happen.', DEBUG_DEVELOPER);
continue;
}
if ($defaultlock === null || !empty($this->configlocks['default'])) {
$conf['default'] = (!empty($conf['default']));
if ($defaultlock === null || $conf['default']) {
$defaultlock = $name;
}
$this->configlocks[$name] = $conf;
@ -175,13 +176,9 @@ class cache_config {
if (!array_key_exists('configuration', $store) || !is_array($store['configuration'])) {
$store['configuration'] = array();
}
if (!empty($store['useforlocking'])) {
// The site has a specified cache for locking.
unset($this->configstores['default_locking']);
}
$store['class'] = $class;
$store['default'] = !empty($store['default']);
if (!array_key_exists('lock', $store) || !array_key_exists($this->configlocks, $store['lock'])) {
if (!array_key_exists('lock', $store) || !array_key_exists($store['lock'], $this->configlocks)) {
$store['lock'] = $defaultlock;
}
@ -434,7 +431,7 @@ class cache_config {
/**
* Returns an array of the configured locks.
* @return array
* @return array Array of name => config
*/
public function get_locks() {
return $this->configlocks;

9
cache/forms.php vendored
View File

@ -46,6 +46,7 @@ class cachestore_addinstance_form extends moodleform {
$form = $this->_form;
$store = $this->_customdata['store'];
$plugin = $this->_customdata['plugin'];
$locks = $this->_customdata['locks'];
$form->addElement('hidden', 'plugin', $plugin);
$form->addElement('hidden', 'editing', !empty($this->_customdata['store']));
@ -60,6 +61,14 @@ class cachestore_addinstance_form extends moodleform {
$form->addElement('static', 'name-value', get_string('storename', 'cache'), $store);
}
if (is_array($locks)) {
$form->addElement('select', 'lock', get_string('lockmethod', 'cache'), $locks);
$form->addHelpButton('lock', 'lockmethod', 'cache');
$form->setType('lock', PARAM_TEXT);
} else {
$form->addElement('hidden', 'lock', '');
$form->addElement('static', 'lock-value', get_string('lockmethod', 'cache'), '<em>'.get_string('nativelocking', 'cache').'</em>');
}
if (method_exists($this, 'configuration_definition')) {
$form->addElement('header', 'storeconfiguration', get_string('storeconfiguration', 'cache'));

99
cache/locallib.php vendored
View File

@ -137,10 +137,12 @@ class cache_config_writer extends cache_config {
'configuration' => $configuration,
'features' => $class::get_supported_features($configuration),
'modes' => $class::get_supported_modes($configuration),
'mappingsonly' => !empty($configuration['mappingsonly']),
'useforlocking' => !empty($configuration['useforlocking'])
'mappingsonly' => !empty($configuration['mappingsonly'])
);
if (array_key_exists('lock', $configuration)) {
$this->configstores[$name]['lock'] = $configuration['lock'];
unset($this->configstores[$name]['configuration']['lock']);
}
$this->config_save();
return true;
}
@ -228,9 +230,12 @@ class cache_config_writer extends cache_config {
'configuration' => $configuration,
'features' => $class::get_supported_features($configuration),
'modes' => $class::get_supported_modes($configuration),
'mappingsonly' => !empty($configuration['mappingsonly']),
'useforlocking' => !empty($configuration['useforlocking'])
'mappingsonly' => !empty($configuration['mappingsonly'])
);
if (array_key_exists('lock', $configuration)) {
$this->configstores[$name]['lock'] = $configuration['lock'];
unset($this->configstores[$name]['configuration']['lock']);
}
$this->config_save();
return true;
}
@ -285,17 +290,6 @@ class cache_config_writer extends cache_config {
$writer = new self;
$writer->configstores = array(
'default_locking' => array(
'name' => 'default_locking',
'plugin' => 'file',
'configuration' => array(),
'features' => cachestore_file::get_supported_features(),
'modes' => cache_store::MODE_APPLICATION,
'useforlocking' => true,
'mappingsonly' => true,
'default' => true,
//'class' => 'cachestore_file'
),
'default_application' => array(
'name' => 'default_application',
'plugin' => 'file',
@ -342,18 +336,12 @@ class cache_config_writer extends cache_config {
'sort' => -1
)
);
$writer->configdefinitionmappings = array(
array(
'store' => 'default_locking',
'definition' => 'core/locking',
'sort' => -1
)
);
$writer->configlocks = array(
'default_file_lock' => array(
'name' => 'default_file_lock',
'name' => 'cachelock_file_default',
'type' => 'cachelock_file',
'dir' => 'filelocks'
'dir' => 'filelocks',
'default' => true
)
);
$writer->config_save();
@ -740,8 +728,33 @@ abstract class cache_administration_helper extends cache_helper {
}
}
$supportsnativelocking = false;
if (file_exists($plugindir.'/lib.php')) {
require_once($plugindir.'/lib.php');
$pluginclass = 'cachestore_'.$plugin;
if (class_exists($pluginclass)) {
$supportsnativelocking = array_key_exists('cache_is_lockable', class_implements($pluginclass));
}
}
if (!$supportsnativelocking) {
$config = cache_config::instance();
$locks = array();
foreach ($config->get_locks() as $lock => $conf) {
debug($conf);
if (!empty($conf['default'])) {
$name = get_string($lock, 'cache');
} else {
$name = $lock;
}
$locks[$lock] = $name;
}
} else {
$locks = false;
}
$url = new moodle_url('/cache/admin.php', array('action' => 'addstore'));
return new $class($url, array('plugin' => $plugin, 'store' => null));
return new $class($url, array('plugin' => $plugin, 'store' => null, 'locks' => $locks));
}
/**
@ -821,9 +834,7 @@ abstract class cache_administration_helper extends cache_helper {
}
}
foreach ($possiblestores as $key => $store) {
if ($key === 'default_locking') {
unset($possiblestores[$key]);
} else if ($store['default']) {
if ($store['default']) {
unset($possiblestores[$key]);
$possiblestores[$key] = $store;
}
@ -863,4 +874,34 @@ abstract class cache_administration_helper extends cache_helper {
}
return $modemappings;
}
/**
* Returns an array summarising the locks available in the system
*/
public static function get_lock_summaries() {
$locks = array();
$instance = cache_config::instance();
$stores = $instance->get_all_stores();
foreach ($instance->get_locks() as $lock) {
$default = !empty($lock['default']);
if ($default) {
$name = new lang_string($lock['name'], 'cache');
} else {
$name = $lock['name'];
}
$uses = 0;
foreach ($stores as $store) {
if (!empty($store['lock']) && $store['lock'] === $lock['name']) {
$uses++;
}
}
$lockdata = array(
'name' => $name,
'default' => $default,
'uses' => $uses
);
$locks[] = $lockdata;
}
return $locks;
}
}

45
cache/renderer.php vendored
View File

@ -282,4 +282,49 @@ class core_cache_renderer extends plugin_renderer_base {
$html .= html_writer::end_tag('div');
return $html;
}
/**
* Display basic information about lock instances.
*
* @todo Add some actions so that people can configure lock instances.
*
* @param array $locks
* @return string
*/
public function lock_summaries(array $locks) {
$table = new html_table();
$table->colclasses = array(
'name',
'default',
'uses',
// 'actions'
);
$table->rowclasses = array(
'lock_name',
'lock_default',
'lock_uses',
// 'lock_actions',
);
$table->head = array(
get_string('lockname', 'cache'),
get_string('lockdefault', 'cache'),
get_string('lockuses', 'cache'),
// get_string('actions', 'cache')
);
$table->data = array();
$tick = $this->output->pix_icon('i/tick_green_big', '');
foreach ($locks as $lock) {
$table->data[] = new html_table_row(array(
new html_table_cell($lock['name']),
new html_table_cell($lock['default'] ? $tick : ''),
new html_table_cell($lock['uses']),
));
}
$html = html_writer::start_tag('div', array('id' => 'core-cache-lock-summary'));
$html .= $this->output->heading(get_string('locksummary', 'cache'), 3);
$html .= html_writer::table($table);
$html .= html_writer::end_tag('div');
return $html;
}
}

View File

@ -102,21 +102,15 @@ class cache_phpunit_tests extends advanced_testcase {
}
$definitions = $instance->get_definitions();
// The default locking definition is required for the cache API and must be there.
$this->assertArrayHasKey('core/locking', $definitions);
// The event invalidation definition is required for the cache API and must be there.
$this->assertArrayHasKey('core/eventinvalidation', $definitions);
$definitionmappings = $instance->get_definition_mappings();
// There should be a mapping for default locking to default_locking
$found = false;
foreach ($definitionmappings as $mapping) {
// Required attributes = definition + store
$this->assertArrayHasKey('definition', $mapping);
$this->assertArrayHasKey('store', $mapping);
if ($mapping['store'] == 'default_locking' && $mapping['definition'] == 'core/locking') {
$found = true;
}
}
$this->assertTrue($found, 'The expected mapping for default locking definition to the default locking store was not found.');
}

View File

@ -13,6 +13,7 @@ $string['cachedef_databasemeta'] = 'Database meta information';
$string['cachedef_eventinvalidation'] = 'Event invalidation';
$string['cachedef_locking'] = 'Locking';
$string['cachedef_string'] = 'Language string cache';
$string['cachelock_file_default'] = 'Default file locking';
$string['cachestores'] = 'Cache stores';
$string['component'] = 'Component';
$string['confirmstoredeletion'] = 'Confirm store deletion';
@ -20,7 +21,6 @@ $string['defaultmappings'] = 'Default mappings';
$string['defaultmappings_help'] = 'These are the default stores that will be used if you don\'t map one or more stores to the cache definition.';
$string['defaultstoreactions'] = 'Default stores cannot be modified';
$string['default_application'] = 'Default application store';
$string['default_locking'] = 'Default store for locking';
$string['default_request'] = 'Default request store';
$string['default_session'] = 'Default session store';
$string['definition'] = 'Definition';
@ -41,6 +41,12 @@ $string['gethit'] = 'Get - Hit';
$string['getmiss'] = 'Get - Miss';
$string['invalidplugin'] = 'Invalid plugin';
$string['invalidstore'] = 'Invalid cache store provided';
$string['lockdefault'] = 'Default';
$string['lockmethod'] = 'Lock method';
$string['lockmethod_help'] = 'This is the method used for locking when required of this store.';
$string['lockname'] = 'Name';
$string['locksummary'] = 'Summary of cache lock instances.';
$string['lockuses'] = 'Uses';
$string['mappings'] = 'Store mappings';
$string['mappingdefault'] = '(default)';
$string['mappingprimary'] = 'Primary store';
@ -50,6 +56,7 @@ $string['modes'] = 'Modes';
$string['mode_1'] = 'Application';
$string['mode_2'] = 'Session';
$string['mode_4'] = 'Request';
$string['nativelocking'] = 'This plugin handles its own locking.';
$string['none'] = 'None';
$string['plugin'] = 'Plugin';
$string['pluginsummaries'] = 'Plugin summaries';
@ -70,7 +77,6 @@ $string['storeresults_request'] = 'Store requests when used as a request cache.'
$string['storeresults_session'] = 'Store requests when used as a session cache.';
$string['stores'] = 'Stores';
$string['store_default_application'] = 'Default file store for application caches';
$string['store_default_locking'] = 'Default file store for locking';
$string['store_default_request'] = 'Default static store for request caches';
$string['store_default_session'] = 'Default session store for session caches';
$string['storesummaries'] = 'Store summaries';

View File

@ -1,11 +1,32 @@
<?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/>.
/**
* Core cache definitions.
*
* This file is part of Moodle's cache API, affectionately called MUC.
* It contains the components that are requried in order to use caching.
*
* @package core
* @category cache
* @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$definitions = array(
// Default cache for locking
'locking' => array(
'mode' => cache_store::MODE_APPLICATION,
'mappingsonly' => true,
),
'string' => array(
'mode' => cache_store::MODE_APPLICATION,
'component' => 'core',