Skip to content

Commit 52a29be

Browse files
author
epriestley
committedJun 5, 2015
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
1 parent a15444a commit 52a29be

9 files changed

+90
-1
lines changed
 

‎src/__phutil_library_map__.php

+2
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,7 @@
14951495
'PhabricatorCacheSpec' => 'applications/cache/spec/PhabricatorCacheSpec.php',
14961496
'PhabricatorCacheTTLGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheTTLGarbageCollector.php',
14971497
'PhabricatorCaches' => 'applications/cache/PhabricatorCaches.php',
1498+
'PhabricatorCachesTestCase' => 'applications/cache/__tests__/PhabricatorCachesTestCase.php',
14981499
'PhabricatorCalendarApplication' => 'applications/calendar/application/PhabricatorCalendarApplication.php',
14991500
'PhabricatorCalendarController' => 'applications/calendar/controller/PhabricatorCalendarController.php',
15001501
'PhabricatorCalendarDAO' => 'applications/calendar/storage/PhabricatorCalendarDAO.php',
@@ -4852,6 +4853,7 @@
48524853
'PhabricatorCacheSetupCheck' => 'PhabricatorSetupCheck',
48534854
'PhabricatorCacheSpec' => 'Phobject',
48544855
'PhabricatorCacheTTLGarbageCollector' => 'PhabricatorGarbageCollector',
4856+
'PhabricatorCachesTestCase' => 'PhabricatorTestCase',
48554857
'PhabricatorCalendarApplication' => 'PhabricatorApplication',
48564858
'PhabricatorCalendarController' => 'PhabricatorController',
48574859
'PhabricatorCalendarDAO' => 'PhabricatorLiskDAO',

‎src/applications/cache/PhabricatorCaches.php

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
<?php
22

33
/**
4+
*
5+
* @task request Request Cache
46
* @task immutable Immutable Cache
57
* @task setup Setup Cache
68
* @task compress Compression
79
*/
810
final class PhabricatorCaches {
911

12+
private static $requestCache;
13+
1014
public static function getNamespace() {
1115
return PhabricatorEnv::getEnvConfig('phabricator.cache-namespace');
1216
}
@@ -18,8 +22,39 @@ private static function newStackFromCaches(array $caches) {
1822
->setCaches($caches);
1923
}
2024

25+
/* -( Request Cache )------------------------------------------------------ */
26+
27+
28+
/**
29+
* Get a request cache stack.
30+
*
31+
* This cache stack is destroyed after each logical request. In particular,
32+
* it is destroyed periodically by the daemons, while `static` caches are
33+
* not.
34+
*
35+
* @return PhutilKeyValueCacheStack Request cache stack.
36+
*/
37+
public static function getRequestCache() {
38+
if (!self::$requestCache) {
39+
self::$requestCache = new PhutilInRequestKeyValueCache();
40+
}
41+
return self::$requestCache;
42+
}
43+
44+
45+
/**
46+
* Destroy the request cache.
47+
*
48+
* This is called at the beginning of each logical request.
49+
*
50+
* @return void
51+
*/
52+
public static function destroyRequestCache() {
53+
self::$requestCache = null;
54+
}
55+
2156

22-
/* -( Local Cache )-------------------------------------------------------- */
57+
/* -( Immutable Cache )---------------------------------------------------- */
2358

2459

2560
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
final class PhabricatorCachesTestCase
4+
extends PhabricatorTestCase {
5+
6+
public function testRequestCache() {
7+
$cache = PhabricatorCaches::getRequestCache();
8+
9+
$test_key = 'unit.'.Filesystem::readRandomCharacters(8);
10+
11+
$default_value = pht('Default');
12+
$new_value = pht('New Value');
13+
14+
$this->assertEqual(
15+
$default_value,
16+
$cache->getKey($test_key, $default_value));
17+
18+
// Set a key, verify it persists.
19+
$cache = PhabricatorCaches::getRequestCache();
20+
$cache->setKey($test_key, $new_value);
21+
$this->assertEqual(
22+
$new_value,
23+
$cache->getKey($test_key, $default_value));
24+
25+
// Refetch the cache, verify it's really a cache.
26+
$cache = PhabricatorCaches::getRequestCache();
27+
$this->assertEqual(
28+
$new_value,
29+
$cache->getKey($test_key, $default_value));
30+
31+
// Destroy the cache.
32+
PhabricatorCaches::destroyRequestCache();
33+
34+
// Now, the value should be missing again.
35+
$cache = PhabricatorCaches::getRequestCache();
36+
$this->assertEqual(
37+
$default_value,
38+
$cache->getKey($test_key, $default_value));
39+
}
40+
41+
}

‎src/applications/fact/daemon/PhabricatorFactDaemon.php

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ final class PhabricatorFactDaemon extends PhabricatorDaemon {
99
protected function run() {
1010
$this->setEngines(PhabricatorFactEngine::loadAllEngines());
1111
while (!$this->shouldExit()) {
12+
PhabricatorCaches::destroyRequestCache();
13+
1214
$iterators = $this->getAllApplicationIterators();
1315
foreach ($iterators as $iterator_name => $iterator) {
1416
$this->processIteratorWithCursor($iterator_name, $iterator);

‎src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ protected function run() {
7373
$queue = array();
7474

7575
while (!$this->shouldExit()) {
76+
PhabricatorCaches::destroyRequestCache();
7677
$pullable = $this->loadPullableRepositories($include, $exclude);
7778

7879
// If any repositories have the NEEDS_UPDATE flag set, pull them

‎src/infrastructure/daemon/bot/PhabricatorBot.php

+2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ public function getConfig($key, $default = null) {
106106

107107
private function runLoop() {
108108
do {
109+
PhabricatorCaches::destroyRequestCache();
110+
109111
$this->stillWorking();
110112

111113
$messages = $this->protocolAdapter->getNextMessages($this->pollFrequency);

‎src/infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ final class PhabricatorTaskmasterDaemon extends PhabricatorDaemon {
44

55
protected function run() {
66
do {
7+
PhabricatorCaches::destroyRequestCache();
8+
79
$tasks = id(new PhabricatorWorkerLeaseQuery())
810
->setLimit(1)
911
->execute();

‎src/infrastructure/daemon/workers/PhabricatorTriggerDaemon.php

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ protected function run() {
6565
$this->nextCollection = PhabricatorTime::getNow();
6666

6767
do {
68+
PhabricatorCaches::destroyRequestCache();
69+
6870
$lock = PhabricatorGlobalLock::newLock('trigger');
6971

7072
try {

‎webroot/index.php

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
try {
1515
PhabricatorStartup::loadCoreLibraries();
16+
PhabricatorCaches::destroyRequestCache();
17+
1618
$sink = new AphrontPHPHTTPSink();
1719

1820
try {

0 commit comments

Comments
 (0)
Failed to load comments.