Merge branch 'MDL-52346' of git://github.com/mr-russ/moodle
authorAndrew Nicols <andrew@nicols.co.uk>
Mon, 29 Feb 2016 06:12:03 +0000 (14:12 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Mon, 29 Feb 2016 06:12:03 +0000 (14:12 +0800)
cache/README.md
cache/classes/definition.php
cache/forms.php
cache/locallib.php
lang/en/cache.php
lib/db/caches.php

index 71f44f5..7676171 100644 (file)
@@ -31,6 +31,7 @@ A definition:
             'invalidationevents' => array(            // Optional
                 'contextmarkeddirty'
             ),
+            'canuselocalstore' => false               // Optional
             'sharingoptions' => null                  // Optional
             'defaultsharing' => null                  // Optional
         )
@@ -151,7 +152,7 @@ The following optional settings can also be defined:
 * invalidationevents - An array of events that should trigger this cache to invalidate.
 * sharingoptions - The sum of the possible sharing options that are applicable to the definition. An advanced setting.
 * defaultsharing - The default sharing option to use. It's highly recommended that you don't set this unless there is a very specific reason not to use the system default.
-
+* canuselocalstore - The default is to required a shared cache location for all nodes in a multi webserver environment.  If the cache uses revisions and never updates key data, administrators can use a local storage cache for this cache.
 It's important to note that internally the definition is also aware of the component. This is picked up when the definition is read, based upon the location of the caches.php file.
 
 The staticacceleration option.
@@ -269,4 +270,4 @@ There are a couple of considerations to using this method:
 
 Please be aware that if you are using Memcache or Memcached it is recommended to use dedicated Memcached servers.
 When caches get purged the memcached servers you have configured get purged, any data stored within them whether it belongs to Moodle or not will be removed.
-If you are using Memcached for sessions as well as caching/testing and caches get purged your sessions will be removed prematurely and users will be need to start again.
\ No newline at end of file
+If you are using Memcached for sessions as well as caching/testing and caches get purged your sessions will be removed prematurely and users will be need to start again.
index c658d4b..5f08b1b 100644 (file)
@@ -100,6 +100,11 @@ defined('MOODLE_INTERNAL') || die();
  *     + defaultsharing
  *          [int] The default sharing option to use. It's highly recommended that you don't set this unless there is a very
  *          specific reason not to use the system default.
+ *     + canuselocalstore
+ *          [bool] The cache is able to safely run with multiple copies on different webservers without any need for administrator
+ *                 intervention to ensure that data stays in sync across nodes.  This is usually managed by a revision
+ *                 system as seen in modinfo cache or language cache.  Requiring purge on upgrade is not sufficient as
+ *                 it requires administrator intervention on each node to make it work.
  *
  * For examples take a look at lib/db/caches.php
  *
@@ -308,6 +313,11 @@ class cache_definition {
      */
     protected $sharingoptions;
 
+    /**
+     * Whether this cache supports local storages.
+     * @var bool
+     */
+    protected $canuselocalstore = false;
     /**
      * The selected sharing option.
      * @var int One of self::SHARING_*
@@ -367,6 +377,7 @@ class cache_definition {
         $sharingoptions = self::SHARING_DEFAULT;
         $selectedsharingoption = self::SHARING_DEFAULT;
         $userinputsharingkey = '';
+        $canuselocalstore = false;
 
         if (array_key_exists('simplekeys', $definition)) {
             $simplekeys = (bool)$definition['simplekeys'];
@@ -453,6 +464,9 @@ class cache_definition {
                 $selectedsharingoption = self::SHARING_ALL;
             }
         }
+        if (array_key_exists('canuselocalstore', $definition)) {
+            $canuselocalstore = (bool)$definition['canuselocalstore'];
+        }
 
         if (array_key_exists('userinputsharingkey', $definition) && !empty($definition['userinputsharingkey'])) {
             $userinputsharingkey = (string)$definition['userinputsharingkey'];
@@ -529,6 +543,7 @@ class cache_definition {
         $cachedefinition->sharingoptions = $sharingoptions;
         $cachedefinition->selectedsharingoption = $selectedsharingoption;
         $cachedefinition->userinputsharingkey = $userinputsharingkey;
+        $cachedefinition->canuselocalstore = $canuselocalstore;
 
         return $cachedefinition;
     }
@@ -732,6 +747,15 @@ class cache_definition {
         return $this->requirelockingwrite;
     }
 
+    /**
+     * Returns true if this definition allows local storage to be used for caching.
+     * @since Moodle 3.1.0
+     * @return bool
+     */
+    public function can_use_localstore() {
+        return $this->canuselocalstore;
+    }
+
     /**
      * Returns true if this definition requires a searchable cache.
      * @since Moodle 2.4.4
index 5a2ef3b..e482702 100644 (file)
@@ -132,6 +132,8 @@ class cache_definition_mappings_form extends moodleform {
      * The definition of the form
      */
     protected final function definition() {
+        global $OUTPUT;
+
         $definition = $this->_customdata['definition'];
         $form = $this->_form;
 
@@ -139,6 +141,14 @@ class cache_definition_mappings_form extends moodleform {
         list($currentstores, $storeoptions, $defaults) =
                 cache_administration_helper::get_definition_store_options($component, $area);
 
+        $storedata = cache_administration_helper::get_definition_summaries();
+        if ($storedata[$definition]['mode'] != cache_store::MODE_REQUEST) {
+            if (isset($storedata[$definition]['canuselocalstore']) && $storedata[$definition]['canuselocalstore']) {
+                $form->addElement('html', $OUTPUT->notification(get_string('localstorenotification', 'cache'), 'notifymessage'));
+            } else {
+                $form->addElement('html', $OUTPUT->notification(get_string('sharedstorenotification', 'cache'), 'notifymessage'));
+            }
+        }
         $form->addElement('hidden', 'definition', $definition);
         $form->setType('definition', PARAM_SAFEPATH);
         $form->addElement('hidden', 'action', 'editdefinitionmapping');
index 58dcdd8..2e6813e 100644 (file)
@@ -806,6 +806,7 @@ abstract class cache_administration_helper extends cache_helper {
                 'component' => $definition->get_component(),
                 'area' => $definition->get_area(),
                 'mappings' => $mappings,
+                'canuselocalstore' => $definition->can_use_localstore(),
                 'sharingoptions' => self::get_definition_sharing_options($definition->get_sharing_options(), false),
                 'selectedsharingoption' => self::get_definition_sharing_options($definition->get_selected_sharing_option(), true),
                 'userinputsharingkey' => $definition->get_user_input_sharing_key()
index 6f6cfd8..6c34d47 100644 (file)
@@ -102,6 +102,7 @@ $string['inadequatestoreformapping'] = 'This store doesn\'t meet the requirement
 $string['invalidlock'] = 'Invalid lock';
 $string['invalidplugin'] = 'Invalid plugin';
 $string['invalidstore'] = 'Invalid cache store provided';
+$string['localstorenotification'] = 'This cache can be safely mapped to a store that is local to each webserver';
 $string['lockdefault'] = 'Default';
 $string['locking'] = 'Locking';
 $string['locking_help'] = 'Locking is a mechanism that restricts access to cached data to one process at a time to prevent the data from being overwritten. The locking method determines how the lock is acquired and checked.';
@@ -131,6 +132,7 @@ $string['requestcount'] = 'Test with {$a} requests';
 $string['rescandefinitions'] = 'Rescan definitions';
 $string['result'] = 'Result';
 $string['set'] = 'Set';
+$string['sharedstorenotification'] = 'This cache must be mapped to a store that is shared to all webservers';
 $string['sharing'] = 'Sharing';
 $string['sharing_all'] = 'Everyone.';
 $string['sharing_input'] = 'Custom key (entered below)';
index 2c3835f..b5022cb 100644 (file)
@@ -31,22 +31,22 @@ $definitions = array(
     // Used to store processed lang files.
     // The keys used are the revision, lang and component of the string file.
     // The static acceleration size has been based upon student access of the site.
-    // NOTE: this data may be safely stored in local caches on cluster nodes.
     'string' => array(
         'mode' => cache_store::MODE_APPLICATION,
         'simplekeys' => true,
         'simpledata' => true,
         'staticacceleration' => true,
-        'staticaccelerationsize' => 30
+        'staticaccelerationsize' => 30,
+        'canuselocalstore' => true
     ),
 
     // Used to store cache of all available translations.
-    // NOTE: this data may be safely stored in local caches on cluster nodes.
     'langmenu' => array(
         'mode' => cache_store::MODE_APPLICATION,
         'simplekeys' => true,
         'simpledata' => true,
         'staticacceleration' => true,
+        'canuselocalstore' => true
     ),
 
     // Used to store database meta information.
@@ -91,9 +91,9 @@ $definitions = array(
     // This caches the html purifier cleaned text. This is done because the text is usually cleaned once for every user
     // and context combo. Text caching handles caching for the combination, this cache is responsible for caching the
     // cleaned text which is shareable.
-    // NOTE: this data may be safely stored in local caches on cluster nodes.
     'htmlpurifier' => array(
         'mode' => cache_store::MODE_APPLICATION,
+        'canuselocalstore' => true
     ),
 
     // Used to store data from the config + config_plugins table in the database.
@@ -206,6 +206,7 @@ $definitions = array(
     'coursemodinfo' => array(
         'mode' => cache_store::MODE_APPLICATION,
         'simplekeys' => true,
+        'canuselocalstore' => true
     ),
     // This is the session user selections cache.
     // It's a special cache that is used to record user selections that should persist for the lifetime of the session.