mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-40475 add alternative component cache location and other improvements
Improvements include: * Alternative location might be useful when server administrator wants to maintain a local copy of component cache instead of using shared $CFG->cachedir. * Component caching is now enabled in behat tests which should improve performance. * Standardised ignoring of component caching. * Fixed debug mode in ABORT_AFTER_CONFIG scripts. * General documentation improvements.
This commit is contained in:
parent
07bbbcf174
commit
d7245e3400
111
admin/cli/alternative_component_cache.php
Normal file
111
admin/cli/alternative_component_cache.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* This hack is intended for clustered sites that do not want
|
||||
* to use shared cachedir for component cache.
|
||||
*
|
||||
* This file needs to be called after any change in PHP files in dataroot,
|
||||
* that is before upgrade and install.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2013 Petr Skoda (skodak) {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
define('CLI_SCRIPT', true);
|
||||
define('ABORT_AFTER_CONFIG', true); // We need just the values from config.php.
|
||||
define('CACHE_DISABLE_ALL', true); // This prevents reading of existing caches.
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
require(__DIR__.'/../../config.php');
|
||||
require_once($CFG->libdir.'/clilib.php');
|
||||
|
||||
// Now get cli options.
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
array(
|
||||
'file' => false,
|
||||
'rebuild' => false,
|
||||
'print' => false,
|
||||
'help' => false
|
||||
),
|
||||
array(
|
||||
'h' => 'help'
|
||||
)
|
||||
);
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized), 2);
|
||||
}
|
||||
|
||||
if (!$options['rebuild'] and !$options['file'] and !$options['print']) {
|
||||
$help =
|
||||
"Create alternative component cache file
|
||||
|
||||
Options:
|
||||
-h, --help Print out this help
|
||||
--rebuild Rebuild \$CFG->alternative_component_cache file
|
||||
--file=filepath Save component cache to file
|
||||
--print Print component cache file content
|
||||
|
||||
Example:
|
||||
\$ php admin/cli/rebuild_alternative_component_cache.php --rebuild
|
||||
";
|
||||
|
||||
echo $help;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$content = core_component::get_cache_content();
|
||||
|
||||
if ($options['print']) {
|
||||
echo $content;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($options['rebuild']) {
|
||||
if (empty($CFG->alternative_component_cache)) {
|
||||
fwrite(STDERR, 'config.php does not contain $CFG->alternative_component_cache setting');
|
||||
fwrite(STDERR, "\n");
|
||||
exit(2);
|
||||
}
|
||||
$target = $CFG->alternative_component_cache;
|
||||
} else {
|
||||
$target = $options['file'];
|
||||
}
|
||||
|
||||
if (!$target) {
|
||||
fwrite(STDERR, "Invalid target file $target");
|
||||
fwrite(STDERR, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$bytes = file_put_contents($target, $content);
|
||||
|
||||
if (!$bytes) {
|
||||
fwrite(STDERR, "Error writing to $target");
|
||||
fwrite(STDERR, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Success.
|
||||
echo "File $target was updated\n";
|
||||
exit(0);
|
@ -139,6 +139,8 @@ define('CACHE_DISABLE_ALL', true);
|
||||
|
||||
define('PHPUNIT_TEST', false);
|
||||
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
// Check that PHP is of a sufficient version
|
||||
if (version_compare(phpversion(), "5.3.3") < 0) {
|
||||
$phpversion = phpversion();
|
||||
|
@ -34,6 +34,7 @@ if (function_exists('opcache_reset')) {
|
||||
|
||||
// Is not really necessary but adding it as is a CLI_SCRIPT.
|
||||
define('CLI_SCRIPT', true);
|
||||
define('CACHE_DISABLE_ALL', true);
|
||||
|
||||
// Basic functions.
|
||||
require_once(__DIR__ . '/../../../../lib/clilib.php');
|
||||
|
@ -84,6 +84,7 @@ define('BEHAT_UTIL', true);
|
||||
define('CLI_SCRIPT', true);
|
||||
define('ABORT_AFTER_CONFIG', true);
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
ini_set('display_errors', '1');
|
||||
|
@ -32,6 +32,8 @@ if (function_exists('opcache_reset')) {
|
||||
opcache_reset();
|
||||
}
|
||||
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
require_once(__DIR__.'/../../../../lib/clilib.php');
|
||||
require_once(__DIR__.'/../../../../lib/phpunit/bootstraplib.php');
|
||||
require_once(__DIR__.'/../../../../lib/testing/lib.php');
|
||||
|
@ -28,6 +28,8 @@ if (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
die; // no access from web!
|
||||
}
|
||||
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
require_once(__DIR__.'/../../../../lib/clilib.php');
|
||||
require_once(__DIR__.'/../../../../lib/phpunit/bootstraplib.php');
|
||||
require_once(__DIR__.'/../../../../lib/testing/lib.php');
|
||||
|
@ -47,6 +47,7 @@ define('CLI_SCRIPT', false); // prevents some warnings later
|
||||
define('AJAX_SCRIPT', false); // prevents some warnings later
|
||||
define('CACHE_DISABLE_ALL', true); // Disables caching.. just in case.
|
||||
define('PHPUNIT_TEST', false);
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
|
||||
// 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.
|
||||
|
@ -79,20 +79,44 @@ class core_component {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PHPUNIT_TEST or !empty($CFG->early_install_lang) or
|
||||
(defined('BEHAT_UTIL') and BEHAT_UTIL) or
|
||||
(defined('BEHAT_TEST') and BEHAT_TEST)) {
|
||||
// 1/ Do not bother storing the file for unit tests,
|
||||
// we need fresh copy for each execution and
|
||||
// later we keep it in memory.
|
||||
// 2/ We can not write to dataroot in installer yet.
|
||||
if (defined('IGNORE_COMPONENT_CACHE') and IGNORE_COMPONENT_CACHE) {
|
||||
self::fill_all_caches();
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: cachedir MUST be shared by all servers in a cluster, sorry guys...
|
||||
// MUC should use classloading, we can not depend on it here.
|
||||
$cachefile = "$CFG->cachedir/core_component.php";
|
||||
if (!empty($CFG->alternative_component_cache)) {
|
||||
// Hack for heavily clustered sites that want to manage component cache invalidation manually.
|
||||
$cachefile = $CFG->alternative_component_cache;
|
||||
|
||||
if (file_exists($cachefile)) {
|
||||
if (CACHE_DISABLE_ALL) {
|
||||
// Verify the cache state only on upgrade pages.
|
||||
$content = self::get_cache_content();
|
||||
if (sha1_file($cachefile) !== sha1($content)) {
|
||||
die('Outdated component cache file defined in $CFG->alternative_component_cache, can not continue');
|
||||
}
|
||||
return;
|
||||
}
|
||||
$cache = array();
|
||||
include($cachefile);
|
||||
self::$plugintypes = $cache['plugintypes'];
|
||||
self::$plugins = $cache['plugins'];
|
||||
self::$subsystems = $cache['subsystems'];
|
||||
self::$classmap = $cache['classmap'];
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_writable(dirname($cachefile))) {
|
||||
die('Can not create alternative component cache file defined in $CFG->alternative_component_cache, can not continue');
|
||||
}
|
||||
|
||||
// Lets try to create the file, it might be in some writable directory or a local cache dir.
|
||||
|
||||
} else {
|
||||
// Note: $CFG->cachedir MUST be shared by all servers in a cluster,
|
||||
// use $CFG->alternative_component_cache if you do not like it.
|
||||
$cachefile = "$CFG->cachedir/core_component.php";
|
||||
}
|
||||
|
||||
if (!CACHE_DISABLE_ALL and !self::is_developer()) {
|
||||
// 1/ Use the cache only outside of install and upgrade.
|
||||
@ -105,7 +129,7 @@ class core_component {
|
||||
} else if (!isset($cache['plugintypes']) or !isset($cache['plugins']) or !isset($cache['subsystems']) or !isset($cache['classmap'])) {
|
||||
// Something is very wrong.
|
||||
} else if ($cache['plugintypes']['mod'] !== "$CFG->dirroot/mod") {
|
||||
// Dirroot was changed.
|
||||
// $CFG->dirroot was changed.
|
||||
} else {
|
||||
// The cache looks ok, let's use it.
|
||||
self::$plugintypes = $cache['plugintypes'];
|
||||
@ -114,17 +138,12 @@ class core_component {
|
||||
self::$classmap = $cache['classmap'];
|
||||
return;
|
||||
}
|
||||
// Note: we do not verify $CFG->admin here intentionally,
|
||||
// they must visit admin/index.php after any change.
|
||||
}
|
||||
}
|
||||
|
||||
$cachedir = dirname($cachefile);
|
||||
if (!is_dir($cachedir)) {
|
||||
mkdir($cachedir, $CFG->directorypermissions, true);
|
||||
}
|
||||
|
||||
if (!isset(self::$plugintypes)) {
|
||||
self::fill_all_caches();
|
||||
|
||||
// This needs to be atomic and self-fixing as much as possible.
|
||||
|
||||
$content = self::get_cache_content();
|
||||
@ -132,9 +151,15 @@ class core_component {
|
||||
if (sha1_file($cachefile) === sha1($content)) {
|
||||
return;
|
||||
}
|
||||
// Stale cache detected!
|
||||
unlink($cachefile);
|
||||
}
|
||||
|
||||
$cachedir = dirname($cachefile);
|
||||
if (!is_dir($cachedir)) {
|
||||
mkdir($cachedir, $CFG->directorypermissions, true);
|
||||
}
|
||||
|
||||
if ($fp = @fopen($cachefile.'.tmp', 'xb')) {
|
||||
fwrite($fp, $content);
|
||||
fclose($fp);
|
||||
@ -157,11 +182,16 @@ class core_component {
|
||||
protected static function is_developer() {
|
||||
global $CFG;
|
||||
|
||||
if (!isset($CFG->config_php_settings['debug'])) {
|
||||
if (isset($CFG->config_php_settings['debug'])) {
|
||||
// Standard moodle script.
|
||||
$debug = (int)$CFG->config_php_settings['debug'];
|
||||
} else if (isset($CFG->debug)) {
|
||||
// Usually script with ABORT_AFTER_CONFIG.
|
||||
$debug = (int)$CFG->debug;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$debug = (int)$CFG->config_php_settings['debug'];
|
||||
if ($debug & E_ALL and $debug & E_STRICT) {
|
||||
return true;
|
||||
}
|
||||
@ -172,9 +202,15 @@ class core_component {
|
||||
/**
|
||||
* Create cache file content.
|
||||
*
|
||||
* @private this is intended for $CFG->alternative_component_cache only.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function get_cache_content() {
|
||||
public static function get_cache_content() {
|
||||
if (!isset(self::$plugintypes)) {
|
||||
self::fill_all_caches();
|
||||
}
|
||||
|
||||
$cache = array(
|
||||
'subsystems' => self::$subsystems,
|
||||
'plugintypes' => self::$plugintypes,
|
||||
|
@ -40,6 +40,10 @@ if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined('IGNORE_COMPONENT_CACHE')) {
|
||||
define('IGNORE_COMPONENT_CACHE', true);
|
||||
}
|
||||
|
||||
require_once(__DIR__.'/bootstraplib.php');
|
||||
require_once(__DIR__.'/../testing/lib.php');
|
||||
require_once(__DIR__.'/classes/autoloader.php');
|
||||
|
Loading…
x
Reference in New Issue
Block a user