diff --git a/lib/moodlelib.php b/lib/moodlelib.php index c3c1f4471a4..b0570456557 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -1262,6 +1262,9 @@ function purge_other_caches() { remove_dir($CFG->localcachedir, true); set_config('localcachedirpurged', time()); make_localcache_directory('', true); + + // Rewarm the bootstrap.php files so the siteid is always present after a purge. + initialise_local_config_cache(); \core\task\manager::clear_static_caches(); } diff --git a/lib/setup.php b/lib/setup.php index 9c3fb46124e..20ecc835364 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -711,19 +711,29 @@ if (PHPUNIT_TEST and !PHPUNIT_UTIL) { } // Load any immutable bootstrap config from local cache. -$bootstrapcachefile = $CFG->localcachedir . '/bootstrap.php'; -if (is_readable($bootstrapcachefile)) { +$bootstraplocalfile = $CFG->localcachedir . '/bootstrap.php'; +$bootstrapsharedfile = $CFG->cachedir . '/bootstrap.php'; + +if (!is_readable($bootstraplocalfile) && is_readable($bootstrapsharedfile)) { + // If we don't have a local cache but do have a shared cache then clone it, + // for example when scaling up new front ends. + make_localcache_directory('', true); + copy($bootstrapsharedfile, $bootstraplocalfile); +} +if (is_readable($bootstraplocalfile)) { try { - require_once($bootstrapcachefile); + require_once($bootstraplocalfile); // Verify the file is not stale. if (!isset($CFG->bootstraphash) || $CFG->bootstraphash !== hash_local_config_cache()) { // Something has changed, the bootstrap.php file is stale. unset($CFG->siteidentifier); - @unlink($bootstrapcachefile); + @unlink($bootstraplocalfile); + @unlink($bootstrapsharedfile); } } catch (Throwable $e) { // If it is corrupted then attempt to delete it and it will be rebuilt. - @unlink($bootstrapcachefile); + @unlink($bootstraplocalfile); + @unlink($bootstrapsharedfile); } } diff --git a/lib/setuplib.php b/lib/setuplib.php index 470a15a924e..a9f01fb245a 100644 --- a/lib/setuplib.php +++ b/lib/setuplib.php @@ -584,9 +584,17 @@ function initialise_cfg() { function initialise_local_config_cache() { global $CFG; - $bootstrapcachefile = $CFG->localcachedir . '/bootstrap.php'; + $bootstraplocalfile = $CFG->localcachedir . '/bootstrap.php'; + $bootstrapsharedfile = $CFG->cachedir . '/bootstrap.php'; - if (!empty($CFG->siteidentifier) && !file_exists($bootstrapcachefile)) { + if (!is_readable($bootstraplocalfile) && is_readable($bootstrapsharedfile)) { + // If we don't have a local cache but do have a shared cache then clone it, + // for example when scaling up new front ends. + make_localcache_directory('', true); + copy($bootstrapsharedfile, $bootstraplocalfile); + } + + if (!empty($CFG->siteidentifier) && !file_exists($bootstrapsharedfile) && defined('SYSCONTEXTID')) { $contents = "siteidentifier = " . var_export($CFG->siteidentifier, true) . "; @@ -597,10 +605,15 @@ if (\$CFG->bootstraphash === hash_local_config_cache() && !defined('SYSCONTEXTID } "; - $temp = $bootstrapcachefile . '.tmp' . uniqid(); + // Create the central bootstrap first. + $temp = $bootstrapsharedfile . '.tmp' . uniqid(); file_put_contents($temp, $contents); @chmod($temp, $CFG->filepermissions); - rename($temp, $bootstrapcachefile); + rename($temp, $bootstrapsharedfile); + + // Then prewarm the local cache as well. + make_localcache_directory('', true); + copy($bootstrapsharedfile, $bootstraplocalfile); } } @@ -1593,6 +1606,9 @@ function make_localcache_directory($directory, $exceptiononerror = true) { touch($timestampfile); @chmod($timestampfile, $CFG->filepermissions); clearstatcache(); + + // Then prewarm the local boostrap.php file as well. + initialise_local_config_cache(); } if ($directory === '') {