Generate file attachment transactions for explicit Remarkup attachments on common...
[phabricator.git] / src / applications / cache / spec / PhabricatorDataCacheSpec.php
blob0c0c449c5325d455a2d034423af6e9221dfde488
1 <?php
3 final class PhabricatorDataCacheSpec extends PhabricatorCacheSpec {
5 private $cacheSummary;
7 public function setCacheSummary(array $cache_summary) {
8 $this->cacheSummary = $cache_summary;
9 return $this;
12 public function getCacheSummary() {
13 return $this->cacheSummary;
16 public static function getActiveCacheSpec() {
17 $spec = new PhabricatorDataCacheSpec();
19 // NOTE: If APCu is installed, it reports that APC is installed.
20 if (extension_loaded('apc') && !extension_loaded('apcu')) {
21 $spec->initAPCSpec();
22 } else if (extension_loaded('apcu')) {
23 $spec->initAPCuSpec();
24 } else {
25 $spec->initNoneSpec();
28 return $spec;
31 private function initAPCSpec() {
32 $this
33 ->setName(pht('APC User Cache'))
34 ->setVersion(phpversion('apc'));
36 if (ini_get('apc.enabled')) {
37 $this
38 ->setIsEnabled(true)
39 ->setClearCacheCallback('apc_clear_cache');
40 $this->initAPCCommonSpec();
41 } else {
42 $this->setIsEnabled(false);
43 $this->raiseEnableAPCIssue();
47 private function initAPCuSpec() {
48 $this
49 ->setName(pht('APCu'))
50 ->setVersion(phpversion('apcu'));
52 if (ini_get('apc.enabled')) {
53 if (function_exists('apcu_clear_cache')) {
54 $clear_callback = 'apcu_clear_cache';
55 } else {
56 $clear_callback = 'apc_clear_cache';
59 $this
60 ->setIsEnabled(true)
61 ->setClearCacheCallback($clear_callback);
62 $this->initAPCCommonSpec();
63 } else {
64 $this->setIsEnabled(false);
65 $this->raiseEnableAPCIssue();
69 private function initNoneSpec() {
70 if (version_compare(phpversion(), '5.5', '>=')) {
71 $message = pht(
72 'Installing the "APCu" PHP extension will improve performance. '.
73 'This extension is strongly recommended. Without it, this software '.
74 'must rely on a very inefficient disk-based cache.');
76 $this
77 ->newIssue('extension.apcu')
78 ->setShortName(pht('APCu'))
79 ->setName(pht('PHP Extension "APCu" Not Installed'))
80 ->setMessage($message)
81 ->addPHPExtension('apcu');
82 } else {
83 $this->raiseInstallAPCIssue();
87 private function initAPCCommonSpec() {
88 $state = array();
90 if (function_exists('apcu_sma_info')) {
91 $mem = apcu_sma_info();
92 $info = apcu_cache_info();
93 } else if (function_exists('apc_sma_info')) {
94 $mem = apc_sma_info();
95 $info = apc_cache_info('user');
96 } else {
97 $mem = null;
100 if ($mem) {
101 $this->setTotalMemory($mem['num_seg'] * $mem['seg_size']);
103 $this->setUsedMemory($info['mem_size']);
104 $this->setEntryCount(count($info['cache_list']));
106 $cache = $info['cache_list'];
107 $state = array();
108 foreach ($cache as $item) {
109 // Some older versions of APCu report the cachekey as "key", while
110 // newer APCu and APC report it as "info". Just check both indexes
111 // for commpatibility. See T13164 for details.
113 $info = idx($item, 'info');
114 if ($info === null) {
115 $info = idx($item, 'key');
118 if ($info === null) {
119 $key = '<unknown-key>';
120 } else {
121 $key = self::getKeyPattern($info);
124 if (empty($state[$key])) {
125 $state[$key] = array(
126 'max' => 0,
127 'total' => 0,
128 'count' => 0,
131 $state[$key]['max'] = max($state[$key]['max'], $item['mem_size']);
132 $state[$key]['total'] += $item['mem_size'];
133 $state[$key]['count']++;
137 $this->setCacheSummary($state);
140 private static function getKeyPattern($key) {
141 // If this key isn't in the current cache namespace, don't reveal any
142 // information about it.
143 $namespace = PhabricatorEnv::getEnvConfig('phabricator.cache-namespace');
144 if (strncmp($key, $namespace.':', strlen($namespace) + 1)) {
145 return '<other-namespace>';
148 $key = preg_replace('/(?<![a-zA-Z])\d+(?![a-zA-Z])/', 'N', $key);
149 $key = preg_replace('/PHID-[A-Z]{4}-[a-z0-9]{20}/', 'PHID', $key);
151 // TODO: We should probably standardize how digests get embedded into cache
152 // keys to make this rule more generic.
153 $key = preg_replace('/:celerity:.*$/', ':celerity:X', $key);
154 $key = preg_replace('/:pkcs8:.*$/', ':pkcs8:X', $key);
156 return $key;