[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)
|
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']);
|
$container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']);
|
||||||
|
|
||||||
foreach (array('doctrine', 'psr6', 'redis') as $name) {
|
foreach (array('doctrine', 'psr6', 'redis') as $name) {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
<tag name="monolog.logger" channel="cache" />
|
<tag name="monolog.logger" channel="cache" />
|
||||||
<argument /> <!-- namespace -->
|
<argument /> <!-- namespace -->
|
||||||
<argument /> <!-- default lifetime -->
|
<argument /> <!-- default lifetime -->
|
||||||
|
<argument /> <!-- nonce -->
|
||||||
<call method="setLogger">
|
<call method="setLogger">
|
||||||
<argument type="service" id="logger" on-invalid="ignore" />
|
<argument type="service" id="logger" on-invalid="ignore" />
|
||||||
</call>
|
</call>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Cache\Adapter;
|
namespace Symfony\Component\Cache\Adapter;
|
||||||
|
|
||||||
|
use Symfony\Component\Cache\CacheItem;
|
||||||
use Symfony\Component\Cache\Exception\CacheException;
|
use Symfony\Component\Cache\Exception\CacheException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,7 +19,7 @@ use Symfony\Component\Cache\Exception\CacheException;
|
|||||||
*/
|
*/
|
||||||
class ApcuAdapter extends AbstractAdapter
|
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'))) {
|
if (!function_exists('apcu_fetch') || !ini_get('apc.enabled') || ('cli' === PHP_SAPI && !ini_get('apc.enable_cli'))) {
|
||||||
throw new CacheException('APCu is not enabled');
|
throw new CacheException('APCu is not enabled');
|
||||||
@ -27,6 +28,15 @@ class ApcuAdapter extends AbstractAdapter
|
|||||||
ini_set('apc.use_request_time', 0);
|
ini_set('apc.use_request_time', 0);
|
||||||
}
|
}
|
||||||
parent::__construct($namespace, $defaultLifetime);
|
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');
|
$item = $pool->getItem('foo');
|
||||||
$this->assertFalse($item->isHit());
|
$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