1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 22:10:55 +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:
epriestley 2015-06-04 17:27:31 -07:00
parent a15444aa79
commit 52a29be70d
9 changed files with 90 additions and 1 deletions

View file

@ -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',

View file

@ -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 )---------------------------------------------------- */
/**

View 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));
}
}

View file

@ -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);

View file

@ -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

View file

@ -106,6 +106,8 @@ final class PhabricatorBot extends PhabricatorDaemon {
private function runLoop() {
do {
PhabricatorCaches::destroyRequestCache();
$this->stillWorking();
$messages = $this->protocolAdapter->getNextMessages($this->pollFrequency);

View file

@ -4,6 +4,8 @@ final class PhabricatorTaskmasterDaemon extends PhabricatorDaemon {
protected function run() {
do {
PhabricatorCaches::destroyRequestCache();
$tasks = id(new PhabricatorWorkerLeaseQuery())
->setLimit(1)
->execute();

View file

@ -65,6 +65,8 @@ final class PhabricatorTriggerDaemon
$this->nextCollection = PhabricatorTime::getNow();
do {
PhabricatorCaches::destroyRequestCache();
$lock = PhabricatorGlobalLock::newLock('trigger');
try {

View file

@ -13,6 +13,8 @@ PhabricatorStartup::didStartup();
try {
PhabricatorStartup::loadCoreLibraries();
PhabricatorCaches::destroyRequestCache();
$sink = new AphrontPHPHTTPSink();
try {