[Cache] Add nonce based cache invalidation to ApcuAdapter
This commit is contained in:
parent
b85ab60b70
commit
a7899fe65c
@ -1037,6 +1037,8 @@ class FrameworkExtension extends Extension
|
||||
|
||||
private function registerCacheConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
|
||||
{
|
||||
$nonce = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2);
|
||||
$container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $nonce);
|
||||
$container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']);
|
||||
|
||||
foreach (array('doctrine', 'psr6', 'redis') as $name) {
|
||||
|
@ -27,6 +27,7 @@
|
||||
<tag name="monolog.logger" channel="cache" />
|
||||
<argument /> <!-- namespace -->
|
||||
<argument /> <!-- default lifetime -->
|
||||
<argument /> <!-- nonce -->
|
||||
<call method="setLogger">
|
||||
<argument type="service" id="logger" on-invalid="ignore" />
|
||||
</call>
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\CacheException;
|
||||
|
||||
/**
|
||||
@ -18,7 +19,7 @@ use Symfony\Component\Cache\Exception\CacheException;
|
||||
*/
|
||||
class ApcuAdapter extends AbstractAdapter
|
||||
{
|
||||
public function __construct($namespace = '', $defaultLifetime = 0)
|
||||
public function __construct($namespace = '', $defaultLifetime = 0, $nonce = null)
|
||||
{
|
||||
if (!function_exists('apcu_fetch') || !ini_get('apc.enabled') || ('cli' === PHP_SAPI && !ini_get('apc.enable_cli'))) {
|
||||
throw new CacheException('APCu is not enabled');
|
||||
@ -27,6 +28,15 @@ class ApcuAdapter extends AbstractAdapter
|
||||
ini_set('apc.use_request_time', 0);
|
||||
}
|
||||
parent::__construct($namespace, $defaultLifetime);
|
||||
|
||||
if (null !== $nonce) {
|
||||
CacheItem::validateKey($nonce);
|
||||
|
||||
if (!apcu_exists($nonce.':nonce'.$namespace)) {
|
||||
$this->clear($namespace);
|
||||
apcu_add($nonce.':nonce'.$namespace, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,4 +43,29 @@ class ApcuAdapterTest extends CachePoolTest
|
||||
$item = $pool->getItem('foo');
|
||||
$this->assertFalse($item->isHit());
|
||||
}
|
||||
|
||||
public function testNonce()
|
||||
{
|
||||
$namespace = str_replace('\\', '.', __CLASS__);
|
||||
|
||||
$pool1 = new ApcuAdapter($namespace, 0, 'p1');
|
||||
|
||||
$item = $pool1->getItem('foo');
|
||||
$this->assertFalse($item->isHit());
|
||||
$this->assertTrue($pool1->save($item->set('bar')));
|
||||
|
||||
$item = $pool1->getItem('foo');
|
||||
$this->assertTrue($item->isHit());
|
||||
$this->assertSame('bar', $item->get());
|
||||
|
||||
$pool2 = new ApcuAdapter($namespace, 0, 'p2');
|
||||
|
||||
$item = $pool2->getItem('foo');
|
||||
$this->assertFalse($item->isHit());
|
||||
$this->assertNull($item->get());
|
||||
|
||||
$item = $pool1->getItem('foo');
|
||||
$this->assertFalse($item->isHit());
|
||||
$this->assertNull($item->get());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user