Something went wrong. Try again.
@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
Something went wrong. Try again.
3.5 kB · 130 lines
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131<?php
final class PhabricatorDataCacheSpec extends PhabricatorCacheSpec {
private $cacheSummary;
public function setCacheSummary(array $cache_summary) { $this->cacheSummary = $cache_summary; return $this; }
public function getCacheSummary() { return $this->cacheSummary; }
public static function getActiveCacheSpec() { $spec = new PhabricatorDataCacheSpec();
if (extension_loaded('apcu')) { $spec->initAPCuSpec(); } else { $spec->initNoneSpec(); }
return $spec; }
private function initAPCuSpec() { $this ->setName(pht('APCu')) ->setVersion(phpversion('apcu'));
if (ini_get('apc.enabled')) { if (function_exists('apcu_clear_cache')) { $clear_callback = 'apcu_clear_cache'; }
$this ->setIsEnabled(true) ->setClearCacheCallback($clear_callback); $this->initAPCCommonSpec(); } else { $this->setIsEnabled(false); $this->raiseEnableAPCIssue(); } }
private function initNoneSpec() { $message = pht( 'Installing the "APCu" PHP extension will improve performance. '. 'This extension is strongly recommended. Without it, this software '. 'must rely on a very inefficient disk-based cache.');
$this ->newIssue('extension.apcu') ->setShortName(pht('APCu')) ->setName(pht('PHP Extension "APCu" Not Installed')) ->setMessage($message) ->addPHPExtension('apcu'); }
private function initAPCCommonSpec() { $state = array();
if (function_exists('apcu_sma_info')) { $mem = apcu_sma_info(); $info = apcu_cache_info(); } else { $mem = null; }
if ($mem) { $this->setTotalMemory($mem['num_seg'] * $mem['seg_size']);
$this->setUsedMemory($info['mem_size']); $this->setEntryCount(count($info['cache_list']));
$cache = $info['cache_list']; $state = array(); foreach ($cache as $item) { // Some older versions of APCu report the cachekey as "key", while // newer APCu report it as "info". Just check both indexes for // compatibility. See T13164 for details.
$info = idx($item, 'info'); if ($info === null) { $info = idx($item, 'key'); }
if ($info === null) { $key = '<unknown-key>'; } else { $key = self::getKeyPattern($info); }
if (empty($state[$key])) { $state[$key] = array( 'max' => 0, 'total' => 0, 'count' => 0, ); } $state[$key]['max'] = max($state[$key]['max'], $item['mem_size']); $state[$key]['total'] += $item['mem_size']; $state[$key]['count']++; } }
$this->setCacheSummary($state); }
private static function getKeyPattern($key) { // If this key isn't in the current cache namespace, don't reveal any // information about it. $namespace = PhabricatorEnv::getEnvConfig('phabricator.cache-namespace'); if (strncmp($key, $namespace.':', strlen($namespace) + 1)) { return '<other-namespace>'; }
$key = preg_replace('/(?<![a-zA-Z])\d+(?![a-zA-Z])/', 'N', $key); $key = preg_replace('/PHID-[A-Z]{4}-[a-z0-9]{20}/', 'PHID', $key);
// TODO: We should probably standardize how digests get embedded into cache // keys to make this rule more generic. $key = preg_replace('/:celerity:.*$/', ':celerity:X', $key); $key = preg_replace('/:pkcs8:.*$/', ':pkcs8:X', $key);
return $key; }}