mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-19 03:50:54 +01:00
Add a specialized cache for storing "has setup ever worked?"
Summary: Ref T11613. In D16503/T11598 I refined the setup flow to improve messaging for early-stage setup issues, but failed to fully untangle things. We sometimes still try to access a cache which uses configuration before we build configuration, which causes an error. Instead, store "are we in flight / has setup ever worked?" in a separate cache which doesn't use the cache namespace. This stops us from trying to read config before building config. Test Plan: Hit bad extension error with a fake extension, got a proper setup help page: {F1812803} Solved the error, reloaded, broke things again, got a "friendly" page: {F1812805} Reviewers: chad Reviewed By: chad Maniphest Tasks: T11613 Differential Revision: https://secure.phabricator.com/D16542
This commit is contained in:
parent
b822ceb6d5
commit
1ee426e4ac
3 changed files with 51 additions and 14 deletions
43
src/applications/cache/PhabricatorCaches.php
vendored
43
src/applications/cache/PhabricatorCaches.php
vendored
|
@ -143,6 +143,39 @@ final class PhabricatorCaches extends Phobject {
|
|||
}
|
||||
|
||||
|
||||
/* -( Server State Cache )------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Highly specialized cache for storing server process state.
|
||||
*
|
||||
* We use this cache to track initial steps in the setup phase, before
|
||||
* configuration is loaded.
|
||||
*
|
||||
* This cache does NOT use the cache namespace (it must be accessed before
|
||||
* we build configuration), and is global across all instances on the host.
|
||||
*
|
||||
* @return PhutilKeyValueCacheStack Best available server state cache stack.
|
||||
* @task setup
|
||||
*/
|
||||
public static function getServerStateCache() {
|
||||
static $cache;
|
||||
if (!$cache) {
|
||||
$caches = self::buildSetupCaches('phabricator-server');
|
||||
|
||||
// NOTE: We are NOT adding a cache namespace here! This cache is shared
|
||||
// across all instances on the host.
|
||||
|
||||
$caches = self::addProfilerToCaches($caches);
|
||||
$cache = id(new PhutilKeyValueCacheStack())
|
||||
->setCaches($caches);
|
||||
|
||||
}
|
||||
return $cache;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -( Setup Cache )-------------------------------------------------------- */
|
||||
|
||||
|
||||
|
@ -163,7 +196,7 @@ final class PhabricatorCaches extends Phobject {
|
|||
public static function getSetupCache() {
|
||||
static $cache;
|
||||
if (!$cache) {
|
||||
$caches = self::buildSetupCaches();
|
||||
$caches = self::buildSetupCaches('phabricator-setup');
|
||||
$cache = self::newStackFromCaches($caches);
|
||||
}
|
||||
return $cache;
|
||||
|
@ -173,7 +206,7 @@ final class PhabricatorCaches extends Phobject {
|
|||
/**
|
||||
* @task setup
|
||||
*/
|
||||
private static function buildSetupCaches() {
|
||||
private static function buildSetupCaches($cache_name) {
|
||||
// If this is the CLI, just build a setup cache.
|
||||
if (php_sapi_name() == 'cli') {
|
||||
return array();
|
||||
|
@ -188,7 +221,7 @@ final class PhabricatorCaches extends Phobject {
|
|||
|
||||
// If we don't have APC, build a poor approximation on disk. This is still
|
||||
// much better than nothing; some setup steps are quite slow.
|
||||
$disk_path = self::getSetupCacheDiskCachePath();
|
||||
$disk_path = self::getSetupCacheDiskCachePath($cache_name);
|
||||
if ($disk_path) {
|
||||
$disk = new PhutilOnDiskKeyValueCache();
|
||||
$disk->setCacheFile($disk_path);
|
||||
|
@ -205,7 +238,7 @@ final class PhabricatorCaches extends Phobject {
|
|||
/**
|
||||
* @task setup
|
||||
*/
|
||||
private static function getSetupCacheDiskCachePath() {
|
||||
private static function getSetupCacheDiskCachePath($name) {
|
||||
// The difficulty here is in choosing a path which will change on server
|
||||
// restart (we MUST have this property), but as rarely as possible
|
||||
// otherwise (we desire this property to give the cache the best hit rate
|
||||
|
@ -230,7 +263,7 @@ final class PhabricatorCaches extends Phobject {
|
|||
|
||||
$tmp_dir = sys_get_temp_dir();
|
||||
|
||||
$tmp_path = $tmp_dir.DIRECTORY_SEPARATOR.'phabricator-setup';
|
||||
$tmp_path = $tmp_dir.DIRECTORY_SEPARATOR.$name;
|
||||
if (!file_exists($tmp_path)) {
|
||||
@mkdir($tmp_path);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,9 @@ abstract class PhabricatorSetupCheck extends Phobject {
|
|||
$cache = PhabricatorCaches::getSetupCache();
|
||||
$cache->setKey('phabricator.setup.issue-keys', $keys);
|
||||
|
||||
$server_cache = PhabricatorCaches::getServerStateCache();
|
||||
$server_cache->setKey('phabricator.in-flight', 1);
|
||||
|
||||
if ($update_database) {
|
||||
$db_cache = new PhabricatorKeyValueDatabaseCache();
|
||||
try {
|
||||
|
@ -204,7 +207,8 @@ abstract class PhabricatorSetupCheck extends Phobject {
|
|||
* @return bool True if we've made it through setup since the last restart.
|
||||
*/
|
||||
final public static function isInFlight() {
|
||||
return (self::getOpenSetupIssueKeys() !== null);
|
||||
$cache = PhabricatorCaches::getServerStateCache();
|
||||
return (bool)$cache->getKey('phabricator.in-flight');
|
||||
}
|
||||
|
||||
final public static function loadAllChecks() {
|
||||
|
|
16
src/infrastructure/env/PhabricatorEnv.php
vendored
16
src/infrastructure/env/PhabricatorEnv.php
vendored
|
@ -315,14 +315,6 @@ final class PhabricatorEnv extends Phobject {
|
|||
* @task read
|
||||
*/
|
||||
public static function getEnvConfig($key) {
|
||||
if (isset(self::$cache[$key])) {
|
||||
return self::$cache[$key];
|
||||
}
|
||||
|
||||
if (array_key_exists($key, self::$cache)) {
|
||||
return self::$cache[$key];
|
||||
}
|
||||
|
||||
if (!self::$sourceStack) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
|
@ -331,6 +323,14 @@ final class PhabricatorEnv extends Phobject {
|
|||
$key));
|
||||
}
|
||||
|
||||
if (isset(self::$cache[$key])) {
|
||||
return self::$cache[$key];
|
||||
}
|
||||
|
||||
if (array_key_exists($key, self::$cache)) {
|
||||
return self::$cache[$key];
|
||||
}
|
||||
|
||||
$result = self::$sourceStack->getKeys(array($key));
|
||||
if (array_key_exists($key, $result)) {
|
||||
self::$cache[$key] = $result[$key];
|
||||
|
|
Loading…
Reference in a new issue