mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
Introduce a request cache mechanism
Summary: Ref T8424. This adds a standard KeyValueCache to serve as a request cache. In particular, I need to cache Spaces (they are frequently accessed, sometimes by multiple viewers) but not have them survive longer than the scope of one request. This request cache is explicitly destroyed by each web request and each daemon request. In the very long term, building this kind of construct supports reusing PHP interpreters to run web requests (see some discussion in T2312). Test Plan: - Added and executed unit tests. - Ran every daemon. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T8424 Differential Revision: https://secure.phabricator.com/D13153
This commit is contained in:
parent
a15444aa79
commit
52a29be70d
9 changed files with 90 additions and 1 deletions
|
@ -1495,6 +1495,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCacheSpec' => 'applications/cache/spec/PhabricatorCacheSpec.php',
|
||||
'PhabricatorCacheTTLGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheTTLGarbageCollector.php',
|
||||
'PhabricatorCaches' => 'applications/cache/PhabricatorCaches.php',
|
||||
'PhabricatorCachesTestCase' => 'applications/cache/__tests__/PhabricatorCachesTestCase.php',
|
||||
'PhabricatorCalendarApplication' => 'applications/calendar/application/PhabricatorCalendarApplication.php',
|
||||
'PhabricatorCalendarController' => 'applications/calendar/controller/PhabricatorCalendarController.php',
|
||||
'PhabricatorCalendarDAO' => 'applications/calendar/storage/PhabricatorCalendarDAO.php',
|
||||
|
@ -4852,6 +4853,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorCacheSetupCheck' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorCacheSpec' => 'Phobject',
|
||||
'PhabricatorCacheTTLGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||
'PhabricatorCachesTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorCalendarApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorCalendarController' => 'PhabricatorController',
|
||||
'PhabricatorCalendarDAO' => 'PhabricatorLiskDAO',
|
||||
|
|
37
src/applications/cache/PhabricatorCaches.php
vendored
37
src/applications/cache/PhabricatorCaches.php
vendored
|
@ -1,12 +1,16 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @task request Request Cache
|
||||
* @task immutable Immutable Cache
|
||||
* @task setup Setup Cache
|
||||
* @task compress Compression
|
||||
*/
|
||||
final class PhabricatorCaches {
|
||||
|
||||
private static $requestCache;
|
||||
|
||||
public static function getNamespace() {
|
||||
return PhabricatorEnv::getEnvConfig('phabricator.cache-namespace');
|
||||
}
|
||||
|
@ -18,8 +22,39 @@ final class PhabricatorCaches {
|
|||
->setCaches($caches);
|
||||
}
|
||||
|
||||
/* -( Request Cache )------------------------------------------------------ */
|
||||
|
||||
/* -( Local Cache )-------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get a request cache stack.
|
||||
*
|
||||
* This cache stack is destroyed after each logical request. In particular,
|
||||
* it is destroyed periodically by the daemons, while `static` caches are
|
||||
* not.
|
||||
*
|
||||
* @return PhutilKeyValueCacheStack Request cache stack.
|
||||
*/
|
||||
public static function getRequestCache() {
|
||||
if (!self::$requestCache) {
|
||||
self::$requestCache = new PhutilInRequestKeyValueCache();
|
||||
}
|
||||
return self::$requestCache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy the request cache.
|
||||
*
|
||||
* This is called at the beginning of each logical request.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function destroyRequestCache() {
|
||||
self::$requestCache = null;
|
||||
}
|
||||
|
||||
|
||||
/* -( Immutable Cache )---------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
|
|
41
src/applications/cache/__tests__/PhabricatorCachesTestCase.php
vendored
Normal file
41
src/applications/cache/__tests__/PhabricatorCachesTestCase.php
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorCachesTestCase
|
||||
extends PhabricatorTestCase {
|
||||
|
||||
public function testRequestCache() {
|
||||
$cache = PhabricatorCaches::getRequestCache();
|
||||
|
||||
$test_key = 'unit.'.Filesystem::readRandomCharacters(8);
|
||||
|
||||
$default_value = pht('Default');
|
||||
$new_value = pht('New Value');
|
||||
|
||||
$this->assertEqual(
|
||||
$default_value,
|
||||
$cache->getKey($test_key, $default_value));
|
||||
|
||||
// Set a key, verify it persists.
|
||||
$cache = PhabricatorCaches::getRequestCache();
|
||||
$cache->setKey($test_key, $new_value);
|
||||
$this->assertEqual(
|
||||
$new_value,
|
||||
$cache->getKey($test_key, $default_value));
|
||||
|
||||
// Refetch the cache, verify it's really a cache.
|
||||
$cache = PhabricatorCaches::getRequestCache();
|
||||
$this->assertEqual(
|
||||
$new_value,
|
||||
$cache->getKey($test_key, $default_value));
|
||||
|
||||
// Destroy the cache.
|
||||
PhabricatorCaches::destroyRequestCache();
|
||||
|
||||
// Now, the value should be missing again.
|
||||
$cache = PhabricatorCaches::getRequestCache();
|
||||
$this->assertEqual(
|
||||
$default_value,
|
||||
$cache->getKey($test_key, $default_value));
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,8 @@ final class PhabricatorFactDaemon extends PhabricatorDaemon {
|
|||
protected function run() {
|
||||
$this->setEngines(PhabricatorFactEngine::loadAllEngines());
|
||||
while (!$this->shouldExit()) {
|
||||
PhabricatorCaches::destroyRequestCache();
|
||||
|
||||
$iterators = $this->getAllApplicationIterators();
|
||||
foreach ($iterators as $iterator_name => $iterator) {
|
||||
$this->processIteratorWithCursor($iterator_name, $iterator);
|
||||
|
|
|
@ -73,6 +73,7 @@ final class PhabricatorRepositoryPullLocalDaemon
|
|||
$queue = array();
|
||||
|
||||
while (!$this->shouldExit()) {
|
||||
PhabricatorCaches::destroyRequestCache();
|
||||
$pullable = $this->loadPullableRepositories($include, $exclude);
|
||||
|
||||
// If any repositories have the NEEDS_UPDATE flag set, pull them
|
||||
|
|
|
@ -106,6 +106,8 @@ final class PhabricatorBot extends PhabricatorDaemon {
|
|||
|
||||
private function runLoop() {
|
||||
do {
|
||||
PhabricatorCaches::destroyRequestCache();
|
||||
|
||||
$this->stillWorking();
|
||||
|
||||
$messages = $this->protocolAdapter->getNextMessages($this->pollFrequency);
|
||||
|
|
|
@ -4,6 +4,8 @@ final class PhabricatorTaskmasterDaemon extends PhabricatorDaemon {
|
|||
|
||||
protected function run() {
|
||||
do {
|
||||
PhabricatorCaches::destroyRequestCache();
|
||||
|
||||
$tasks = id(new PhabricatorWorkerLeaseQuery())
|
||||
->setLimit(1)
|
||||
->execute();
|
||||
|
|
|
@ -65,6 +65,8 @@ final class PhabricatorTriggerDaemon
|
|||
$this->nextCollection = PhabricatorTime::getNow();
|
||||
|
||||
do {
|
||||
PhabricatorCaches::destroyRequestCache();
|
||||
|
||||
$lock = PhabricatorGlobalLock::newLock('trigger');
|
||||
|
||||
try {
|
||||
|
|
|
@ -13,6 +13,8 @@ PhabricatorStartup::didStartup();
|
|||
|
||||
try {
|
||||
PhabricatorStartup::loadCoreLibraries();
|
||||
PhabricatorCaches::destroyRequestCache();
|
||||
|
||||
$sink = new AphrontPHPHTTPSink();
|
||||
|
||||
try {
|
||||
|
|
Loading…
Reference in a new issue