Skip to content

Commit 6c6956c

Browse files
authored
Merge pull request #755 from Geolim4/master
Added deactivatable static item caching support #754
2 parents 943dcea + 1e8eb32 commit 6c6956c

File tree

8 files changed

+151
-17
lines changed

8 files changed

+151
-17
lines changed

docs/OPTIONS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ PhpFastCache has some options that you may want to know before using them, here'
2323
* **defaultFileNameHashFunction** _| string (default: 'md5')_ `[>=V7]` This option will allow you to define a custom hash function for every I/O method that ends up to write an hashed filename on the disk.
2424
* **preventCacheSlams** _| bool (default: false)_ `[>=V6]` This option will allow you to prevent cache slams when making use of heavy cache items
2525
* **cacheSlamsTimeout** _| int (default: 15)_ `[>=V6]` This option defines the cache slams timeout in seconds
26+
* **useStaticItemCaching** _| bool(default: true)_ `[>=V8.0.3]` This option will allow you to disable the internal static storage of cache items. Can be used for cron script that loop indefinitely on cache items to avoid calling `detachAllItems()`/`detachItem($item)` from the cache pool.
2627

2728
### Host/Authenticating options *
2829
* **host** _| string (default: null)_ The hostname

lib/Phpfastcache/Config/ConfigurationOption.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ class ConfigurationOption extends ArrayObject implements ConfigurationOptionInte
8484
*/
8585
protected $cacheSlamsTimeout = 15;
8686

87+
/**
88+
* @var bool
89+
*/
90+
protected $useStaticItemCaching = true;
8791

8892
/**
8993
* @param $args
@@ -364,4 +368,22 @@ public function setCacheSlamsTimeout(int $cacheSlamsTimeout): self
364368
$this->cacheSlamsTimeout = $cacheSlamsTimeout;
365369
return $this;
366370
}
371+
372+
/**
373+
* @return bool
374+
*/
375+
public function isUseStaticItemCaching(): bool
376+
{
377+
return $this->useStaticItemCaching;
378+
}
379+
380+
/**
381+
* @param bool $useStaticItemCaching
382+
* @return ConfigurationOption
383+
*/
384+
public function setUseStaticItemCaching(bool $useStaticItemCaching): self
385+
{
386+
$this->useStaticItemCaching = $useStaticItemCaching;
387+
return $this;
388+
}
367389
}

lib/Phpfastcache/Core/Item/ItemExtendedTrait.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ public function __construct(ExtendedCacheItemPoolInterface $driver, $key)
6666
if (\is_string($key)) {
6767
$this->key = $key;
6868
$this->driver = $driver;
69-
$this->driver->setItem($this);
69+
if($driver->getConfig()->isUseStaticItemCaching()){
70+
$this->driver->setItem($this);
71+
}
7072
$this->expirationDate = new DateTime();
7173
if ($this->driver->getConfig()->isItemDetailedDate()) {
7274
$this->creationDate = new DateTime();

lib/Phpfastcache/Core/Pool/CacheItemPoolTrait.php

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ trait CacheItemPoolTrait
6666
public function setItem(CacheItemInterface $item)
6767
{
6868
if ($this->getClassNamespace() . '\\Item' === \get_class($item)) {
69+
if(!$this->getConfig()->isUseStaticItemCaching()){
70+
throw new PhpfastcacheLogicException(
71+
'The static item caching option (useStaticItemCaching) is disabled so you cannot attach an item.'
72+
);
73+
}
74+
6975
$this->itemInstances[$item->getKey()] = $item;
7076

7177
return $this;
@@ -106,12 +112,14 @@ public function getItems(array $keys = [])
106112
public function getItem($key)
107113
{
108114
if (\is_string($key)) {
115+
$item = null;
116+
109117
/**
110118
* Replace array_key_exists by isset
111119
* due to performance issue on huge
112120
* loop dispatching operations
113121
*/
114-
if (!isset($this->itemInstances[$key])) {
122+
if (!isset($this->itemInstances[$key]) || !$this->getConfig()->isUseStaticItemCaching()) {
115123
if (\preg_match('~([' . \preg_quote(self::$unsupportedKeyChars, '~') . ']+)~', $key, $matches)) {
116124
throw new PhpfastcacheInvalidArgumentException(
117125
'Unsupported key character detected: "' . $matches[1] . '". Please check: https://github.com/PHPSocialNetwork/phpfastcache/wiki/%5BV6%5D-Unsupported-characters-in-key-identifiers'
@@ -219,21 +227,26 @@ public function getItem($key)
219227
$item->expiresAfter(abs((int)$this->getConfig()['defaultTtl']));
220228
}
221229
}
230+
}else{
231+
$item = $this->itemInstances[$key];
222232
}
223-
} else {
224-
throw new PhpfastcacheInvalidArgumentException(\sprintf('$key must be a string, got type "%s" instead.', \gettype($key)));
225-
}
226233

227-
/**
228-
* @eventName CacheGetItem
229-
* @param $this ExtendedCacheItemPoolInterface
230-
* @param $this ExtendedCacheItemInterface
231-
*/
232-
$this->eventManager->dispatch('CacheGetItem', $this, $this->itemInstances[$key]);
233234

234-
$this->itemInstances[$key]->isHit() ? $this->getIO()->incReadHit() : $this->getIO()->incReadMiss();
235+
if($item !== null){
236+
/**
237+
* @eventName CacheGetItem
238+
* @param $this ExtendedCacheItemPoolInterface
239+
* @param $this ExtendedCacheItemInterface
240+
*/
241+
$this->eventManager->dispatch('CacheGetItem', $this, $item);
235242

236-
return $this->itemInstances[$key];
243+
$item->isHit() ? $this->getIO()->incReadHit() : $this->getIO()->incReadMiss();
244+
245+
return $item;
246+
}
247+
throw new PhpfastcacheInvalidArgumentException(\sprintf('Item %s was not build due to an unknown error', \gettype($key)));
248+
}
249+
throw new PhpfastcacheInvalidArgumentException(\sprintf('$key must be a string, got type "%s" instead.', \gettype($key)));
237250
}
238251

239252
/**
@@ -388,7 +401,9 @@ public function save(CacheItemInterface $item)
388401
* loop dispatching operations
389402
*/
390403
if (!isset($this->itemInstances[$item->getKey()])) {
391-
$this->itemInstances[$item->getKey()] = $item;
404+
if($this->getConfig()->isUseStaticItemCaching()){
405+
$this->itemInstances[$item->getKey()] = $item;
406+
}
392407
} else {
393408
if (\spl_object_hash($item) !== \spl_object_hash($this->itemInstances[$item->getKey()])) {
394409
throw new RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');

lib/Phpfastcache/Core/Pool/ExtendedCacheItemPoolTrait.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ public function attachItem(CacheItemInterface $item)
9191
);
9292
}
9393

94+
if(!$this->getConfig()->isUseStaticItemCaching()){
95+
throw new PhpfastcacheLogicException(
96+
'The static item caching option (useStaticItemCaching) is disabled so you cannot attach an item.'
97+
);
98+
}
99+
94100
$this->itemInstances[$item->getKey()] = $item;
95101
}
96102

lib/Phpfastcache/Core/Pool/IO/IOHelperTrait.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,20 @@ public function getStats(): DriverStatistic
5656
if (!is_dir($path)) {
5757
throw new PhpfastcacheIOException("Can't read PATH:" . $path);
5858
}
59-
60-
$stat->setData(implode(', ', \array_keys($this->itemInstances)))
61-
->setRawData(
59+
$stat->setRawData(
6260
[
6361
'tmp' => $this->tmp,
6462
]
6563
)
6664
->setSize(Directory::dirSize($path))
6765
->setInfo('Number of files used to build the cache: ' . Directory::getFileCount($path));
6866

67+
if($this->getConfig()->isUseStaticItemCaching()){
68+
$stat->setData(implode(', ', \array_keys($this->itemInstances)));
69+
}else{
70+
$stat->setData('No data available since static item caching option (useStaticItemCaching) is disabled.');
71+
}
72+
6973
return $stat;
7074
}
7175

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/**
4+
* @author Khoa Bui (khoaofgod) <[email protected]> https://www.phpfastcache.com
5+
* @author Georges.L (Geolim4) <[email protected]>
6+
*/
7+
8+
use Phpfastcache\CacheManager;
9+
use Phpfastcache\Config\ConfigurationOption;
10+
use Phpfastcache\Core\Item\ExtendedCacheItemInterface;
11+
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
12+
use Phpfastcache\Entities\ItemBatch;
13+
use Phpfastcache\EventManager;
14+
use Phpfastcache\Helper\TestHelper;
15+
16+
chdir(__DIR__);
17+
require_once __DIR__ . '/../vendor/autoload.php';
18+
$testHelper = new TestHelper('Testing disabling static item caching');
19+
$defaultDriver = (!empty($argv[ 1 ]) ? ucfirst($argv[ 1 ]) : 'Files');
20+
$driverInstance = CacheManager::getInstance($defaultDriver, new ConfigurationOption([
21+
'useStaticItemCaching' => false,
22+
]));
23+
24+
if(!$testHelper->isHHVM()){
25+
$testHelper->runSubProcess('DisabledStaticItemCaching');
26+
/**
27+
* Give some time to the
28+
* subprocess to start
29+
* just like a concurrent
30+
* php request
31+
*/
32+
$item = $driverInstance->getItem('TestUseStaticItemCaching');
33+
$item->set('654321-fedcba');
34+
$driverInstance->save($item);
35+
$testHelper->runSubProcess('DisabledStaticItemCaching');
36+
usleep(random_int(250000, 800000));
37+
38+
// We dont want to clear cache instance since we disabled the static item caching
39+
$item = $driverInstance->getItem('TestUseStaticItemCaching');
40+
41+
/**
42+
* @see CacheSlamsProtection.subprocess.php:28
43+
*/
44+
if($item->isHit() && $item->get() === 'abcdef-123456'){
45+
$testHelper->printPassText('The static item caching being disabled, the cache item has been fetched straight from backend.' . $item->get());
46+
}else{
47+
$testHelper->printFailText('The static item caching may not have been disabled since the cache item value does not match the expected value.');
48+
}
49+
50+
/**
51+
* Cleanup the driver
52+
*/
53+
$driverInstance->deleteItem($item->getKey());
54+
55+
}else{
56+
$testHelper->printSkipText('Test ignored on HHVM builds due to sub-process issues with C.I.');
57+
}
58+
59+
$testHelper->terminateTest();
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/**
4+
* @author Georges.L (Geolim4) <[email protected]>
5+
*/
6+
7+
use Phpfastcache\CacheManager;
8+
use Phpfastcache\Config\ConfigurationOption;
9+
use Phpfastcache\Entities\ItemBatch;
10+
11+
chdir(__DIR__);
12+
require_once __DIR__ . '/../../vendor/autoload.php';
13+
14+
$driverInstance = CacheManager::getInstance('Files', new ConfigurationOption([
15+
'useStaticItemCaching' => false,
16+
]));
17+
18+
/**
19+
* Emulate an active ItemBatch
20+
*/
21+
$batchItem = $driverInstance->getItem('TestUseStaticItemCaching');
22+
$batchItem->set('abcdef-123456');
23+
$driverInstance->save($batchItem);
24+
25+
exit(0);

0 commit comments

Comments
 (0)