2015-04-07 23:38:03 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class PhabricatorOpcodeCacheSpec extends PhabricatorCacheSpec {
|
|
|
|
|
|
|
|
public static function getActiveCacheSpec() {
|
|
|
|
$spec = new PhabricatorOpcodeCacheSpec();
|
2015-04-08 20:31:01 +02:00
|
|
|
|
2015-04-07 23:38:03 +02:00
|
|
|
// NOTE: If APCu is installed, it reports that APC is installed.
|
|
|
|
if (extension_loaded('apc') && !extension_loaded('apcu')) {
|
2015-04-08 20:31:01 +02:00
|
|
|
$spec->initAPCSpec();
|
2015-04-07 23:38:03 +02:00
|
|
|
} else if (extension_loaded('Zend OPcache')) {
|
2015-04-08 20:31:01 +02:00
|
|
|
$spec->initOpcacheSpec();
|
2015-04-07 23:38:03 +02:00
|
|
|
} else {
|
2015-04-08 20:31:01 +02:00
|
|
|
$spec->initNoneSpec();
|
2015-04-07 23:38:03 +02:00
|
|
|
}
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
return $spec;
|
2015-04-07 23:38:03 +02:00
|
|
|
}
|
|
|
|
|
2015-04-08 20:31:01 +02:00
|
|
|
private function initAPCSpec() {
|
|
|
|
$this
|
2015-04-07 23:38:03 +02:00
|
|
|
->setName(pht('APC'))
|
|
|
|
->setVersion(phpversion('apc'));
|
|
|
|
|
|
|
|
if (ini_get('apc.enabled')) {
|
2015-09-10 23:18:52 +02:00
|
|
|
$this
|
|
|
|
->setIsEnabled(true)
|
|
|
|
->setClearCacheCallback('apc_clear_cache');
|
2015-04-08 00:08:47 +02:00
|
|
|
|
|
|
|
$mem = apc_sma_info();
|
2015-04-08 20:31:01 +02:00
|
|
|
$this->setTotalMemory($mem['num_seg'] * $mem['seg_size']);
|
2015-04-08 00:08:47 +02:00
|
|
|
|
|
|
|
$info = apc_cache_info();
|
2015-04-08 20:31:01 +02:00
|
|
|
$this->setUsedMemory($info['mem_size']);
|
|
|
|
|
2015-04-08 20:31:19 +02:00
|
|
|
$write_lock = ini_get('apc.write_lock');
|
|
|
|
$slam_defense = ini_get('apc.slam_defense');
|
|
|
|
|
|
|
|
if (!$write_lock || $slam_defense) {
|
2015-05-22 09:27:56 +02:00
|
|
|
$summary = pht('Adjust APC settings to quiet unnecessary errors.');
|
2015-04-08 20:31:19 +02:00
|
|
|
|
|
|
|
$message = pht(
|
|
|
|
'Some versions of APC may emit unnecessary errors into the '.
|
|
|
|
'error log under the current APC settings. To resolve this, '.
|
2015-05-22 09:27:56 +02:00
|
|
|
'enable "%s" and disable "%s" in your PHP configuration.',
|
|
|
|
'apc.write_lock',
|
|
|
|
'apc.slam_defense');
|
2015-04-08 20:31:19 +02:00
|
|
|
|
|
|
|
$this
|
|
|
|
->newIssue('extension.apc.write-lock')
|
|
|
|
->setShortName(pht('Noisy APC'))
|
|
|
|
->setName(pht('APC Has Noisy Configuration'))
|
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig('apc.write_lock')
|
|
|
|
->addPHPConfig('apc.slam_defense');
|
|
|
|
}
|
|
|
|
|
2015-04-08 20:31:01 +02:00
|
|
|
$is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
|
|
|
|
$is_stat_enabled = ini_get('apc.stat');
|
|
|
|
if ($is_stat_enabled && !$is_dev) {
|
|
|
|
$summary = pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
'"%s" is currently enabled, but should probably be disabled.',
|
|
|
|
'apc.stat');
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
$message = pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
'The "%s" setting is currently enabled in your PHP configuration. '.
|
|
|
|
'In production mode, "%s" should be disabled. '.
|
|
|
|
'This will improve performance slightly.',
|
|
|
|
'apc.stat',
|
|
|
|
'apc.stat');
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
$this
|
|
|
|
->newIssue('extension.apc.stat-enabled')
|
2015-05-22 09:27:56 +02:00
|
|
|
->setShortName(pht('"%s" Enabled', 'apc.stat'))
|
|
|
|
->setName(pht('"%s" Enabled in Production', 'apc.stat'))
|
2015-04-08 20:31:01 +02:00
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig('apc.stat')
|
|
|
|
->addPhabricatorConfig('phabricator.developer-mode');
|
|
|
|
} else if (!$is_stat_enabled && $is_dev) {
|
|
|
|
$summary = pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
'"%s" is currently disabled, but should probably be enabled.',
|
|
|
|
'apc.stat');
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
$message = pht(
|
2015-05-22 09:27:56 +02:00
|
|
|
'The "%s" setting is currently disabled in your PHP configuration, '.
|
|
|
|
'but Phabricator is running in development mode. This option should '.
|
|
|
|
'normally be enabled in development so you do not need to restart '.
|
|
|
|
'your webserver after making changes to the code.',
|
|
|
|
'apc.stat');
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
$this
|
|
|
|
->newIssue('extension.apc.stat-disabled')
|
2015-05-22 09:27:56 +02:00
|
|
|
->setShortName(pht('"%s" Disabled', 'apc.stat'))
|
|
|
|
->setName(pht('"%s" Disabled in Development', 'apc.stat'))
|
2015-04-08 20:31:01 +02:00
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig('apc.stat')
|
|
|
|
->addPhabricatorConfig('phabricator.developer-mode');
|
|
|
|
}
|
2015-04-07 23:38:03 +02:00
|
|
|
} else {
|
2015-04-08 20:31:01 +02:00
|
|
|
$this->setIsEnabled(false);
|
|
|
|
$this->raiseEnableAPCIssue();
|
2015-04-07 23:38:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-08 20:31:01 +02:00
|
|
|
private function initOpcacheSpec() {
|
|
|
|
$this
|
2015-04-07 23:38:03 +02:00
|
|
|
->setName(pht('Zend OPcache'))
|
|
|
|
->setVersion(phpversion('Zend OPcache'));
|
|
|
|
|
|
|
|
if (ini_get('opcache.enable')) {
|
2015-09-10 23:18:52 +02:00
|
|
|
$this
|
|
|
|
->setIsEnabled(true)
|
|
|
|
->setClearCacheCallback('opcache_reset');
|
2015-04-08 00:08:47 +02:00
|
|
|
|
|
|
|
$status = opcache_get_status();
|
|
|
|
$memory = $status['memory_usage'];
|
|
|
|
|
|
|
|
$mem_used = $memory['used_memory'];
|
|
|
|
$mem_free = $memory['free_memory'];
|
|
|
|
$mem_junk = $memory['wasted_memory'];
|
2015-04-08 20:31:01 +02:00
|
|
|
$this->setUsedMemory($mem_used + $mem_junk);
|
|
|
|
$this->setTotalMemory($mem_used + $mem_junk + $mem_free);
|
|
|
|
$this->setEntryCount($status['opcache_statistics']['num_cached_keys']);
|
|
|
|
|
|
|
|
$is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
|
|
|
|
|
|
|
|
$validate = ini_get('opcache.validate_timestamps');
|
|
|
|
$freq = ini_get('opcache.revalidate_freq');
|
|
|
|
if ($is_dev && (!$validate || $freq)) {
|
|
|
|
$summary = pht(
|
|
|
|
'OPcache is not configured properly for development.');
|
|
|
|
|
|
|
|
$message = pht(
|
|
|
|
'In development, OPcache should be configured to always reload '.
|
|
|
|
'code so the webserver does not need to be restarted after making '.
|
2015-05-22 09:27:56 +02:00
|
|
|
'changes. To do this, enable "%s" and set "%s" to 0.',
|
|
|
|
'opcache.validate_timestamps',
|
|
|
|
'opcache.revalidate_freq');
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
$this
|
|
|
|
->newIssue('extension.opcache.devmode')
|
|
|
|
->setShortName(pht('OPcache Config'))
|
|
|
|
->setName(pht('OPCache Not Configured for Development'))
|
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig('opcache.validate_timestamps')
|
|
|
|
->addPHPConfig('opcache.revalidate_freq')
|
|
|
|
->addPhabricatorConfig('phabricator.developer-mode');
|
|
|
|
} else if (!$is_dev && $validate) {
|
2015-05-22 09:27:56 +02:00
|
|
|
$summary = pht('OPcache is not configured ideally for production.');
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
$message = pht(
|
|
|
|
'In production, OPcache should be configured to never '.
|
|
|
|
'revalidate code. This will slightly improve performance. '.
|
2015-05-22 09:27:56 +02:00
|
|
|
'To do this, disable "%s" in your PHP configuration.',
|
|
|
|
'opcache.validate_timestamps');
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
$this
|
|
|
|
->newIssue('extension.opcache.production')
|
|
|
|
->setShortName(pht('OPcache Config'))
|
|
|
|
->setName(pht('OPcache Not Configured for Production'))
|
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig('opcache.validate_timestamps')
|
|
|
|
->addPhabricatorConfig('phabricator.developer-mode');
|
|
|
|
}
|
2015-04-07 23:38:03 +02:00
|
|
|
} else {
|
2015-04-08 20:31:01 +02:00
|
|
|
$this->setIsEnabled(false);
|
2015-04-07 23:38:03 +02:00
|
|
|
|
2015-04-08 20:31:01 +02:00
|
|
|
$summary = pht('Enabling OPcache will dramatically improve performance.');
|
|
|
|
$message = pht(
|
|
|
|
'The PHP "Zend OPcache" extension is installed, but not enabled in '.
|
|
|
|
'your PHP configuration. Enabling it will dramatically improve '.
|
2015-05-22 09:27:56 +02:00
|
|
|
'Phabricator performance. Edit the "%s" setting to '.
|
|
|
|
'enable the extension.',
|
|
|
|
'opcache.enable');
|
2015-04-08 20:31:01 +02:00
|
|
|
|
|
|
|
$this->newIssue('extension.opcache.enable')
|
|
|
|
->setShortName(pht('OPcache Disabled'))
|
|
|
|
->setName(pht('Zend OPcache Not Enabled'))
|
|
|
|
->setSummary($summary)
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPConfig('opcache.enable');
|
|
|
|
}
|
2015-04-07 23:38:03 +02:00
|
|
|
}
|
|
|
|
|
2015-04-08 20:31:01 +02:00
|
|
|
private function initNoneSpec() {
|
2015-04-07 23:38:03 +02:00
|
|
|
if (version_compare(phpversion(), '5.5', '>=')) {
|
2015-04-08 20:31:01 +02:00
|
|
|
$message = pht(
|
|
|
|
'Installing the "Zend OPcache" extension will dramatically improve '.
|
|
|
|
'performance.');
|
|
|
|
|
|
|
|
$this
|
|
|
|
->newIssue('extension.opcache')
|
|
|
|
->setShortName(pht('OPcache'))
|
|
|
|
->setName(pht('Zend OPcache Not Installed'))
|
|
|
|
->setMessage($message)
|
|
|
|
->addPHPExtension('Zend OPcache');
|
2015-04-07 23:38:03 +02:00
|
|
|
} else {
|
2015-04-08 20:31:01 +02:00
|
|
|
$this->raiseInstallAPCIssue();
|
2015-04-07 23:38:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|