8000 [Cache] Add nonce based cache invalidation to ApcuAdapter · symfony/symfony@a7899fe · GitHub
[go: up one dir, main page]

Skip to content

Commit a7899fe

Browse files
[Cache] Add nonce based cache invalidation to ApcuAdapter
1 parent b85ab60 commit a7899fe

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,8 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild
10371037

10381038
private function registerCacheConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
10391039
{
1040+
$nonce = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2);
1041+
$container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $nonce);
10401042
$container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']);
10411043

10421044
foreach (array('doctrine', 'psr6', 'redis') as $name) {

src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<tag name="monolog.logger" channel="cache" />
2828
<argument /> <!-- namespace -->
2929
<argument /> <!-- default lifetime -->
30+
<argument /> <!-- nonce -->
3031
<call method="setLogger">
3132
<argument type="service" id="logger" on-invalid="ignore" />
3233
</call>

src/Symfony/Component/Cache/Adapter/ApcuAdapter.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
namespace Symfony\Component\Cache\Adapter;
1313

14+
use Symfony\Component\Cache\CacheItem;
1415
use Symfony\Component\Cache\Exception\CacheException;
1516

1617
/**
1718
* @author Nicolas Grekas <p@tchwork.com>
1819
*/
1920
class ApcuAdapter extends AbstractAdapter
2021
{
21-
public function __construct($namespace = '', $defaultLifetime = 0)
22+
public function __construct($namespace = '', $defaultLifetime = 0, $nonce = null)
2223
{
2324
if (!function_exists('apcu_fetch') || !ini_get('apc.enabled') || ('cli' === PHP_SAPI && !ini_get('apc.enable_cli'))) {
2425
throw new CacheException('APCu is not enabled');
@@ -27,6 +28,15 @@ public function __construct($namespace = '', $defaultLifetime = 0)
2728
ini_set('apc.use_request_time', 0);
2829
}
2930
parent::__construct($namespace, $defaultLifetime);
31+
32+
if (null !== $nonce) {
33+
CacheItem::validateKey($nonce);
34+
35+
if (!apcu_exists($nonce.':nonce'.$namespace)) {
36+
$this->clear($namespace);
37+
apcu_add($nonce.':nonce'.$namespace, null);
38+
}
39+
}
3040
}
3141

3242
/**

src/Symfony/Component/Cache/Tests/Adapter/ApcuAdapterTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,29 @@ public function testUnserializable()
4343
$item = $pool->getItem('foo');
4444
$this->assertFalse($item->isHit());
4545
}
46+
47+
public function testNonce()
48+
{
49+
$namespace = str_replace('\\', '.', __CLASS__);
50+
51+
$pool1 = new ApcuAdapter($namespace, 0, 'p1');
52+
53+
$item = $pool1->getItem('foo');
54+
$this->assertFalse($item->isHit());
55+
$this->assertTrue($pool1->save($item->set('bar')));
56+
57+
$item = $pool1->getItem('foo');
58+
$this->assertTrue($item->isHit());
59+
$this->assertSame('bar', $item->get());
60+
61+
$pool2 = new ApcuAdapter($namespace, 0, 'p2');
62+
63+
$item = $pool2->getItem('foo');
64+
$this->assertFalse($item->isHit());
65+
$this->assertNull($item->get());
66+
67+
$item = $pool1->getItem('foo');
68+
$this->assertFalse($item->isHit());
69+
$this->assertNull($item->get());
70+
}
4671
}

0 commit comments

Comments
 (0)
0