feature #24226 [Cache] Add ResettableInterface to allow resetting any pool's local state (nicolas-grekas)
This PR was merged into the 3.4 branch.
Discussion
----------
[Cache] Add ResettableInterface to allow resetting any pool's local state
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
To allow pools to leverage #24155 so that they can be used in multi-request loops.
Commits
-------
14c91f2
[Cache] Add ResettableInterface to allow resetting any pool's local state
This commit is contained in:
commit
0c0a0525a1
@ -43,6 +43,7 @@ class CachePoolPass implements CompilerPassInterface
|
||||
'provider',
|
||||
'namespace',
|
||||
'default_lifetime',
|
||||
'reset',
|
||||
);
|
||||
foreach ($container->findTaggedServiceIds('cache.pool') as $id => $tags) {
|
||||
$adapter = $pool = $container->getDefinition($id);
|
||||
@ -73,13 +74,19 @@ class CachePoolPass implements CompilerPassInterface
|
||||
}
|
||||
$i = 0;
|
||||
foreach ($attributes as $attr) {
|
||||
if (isset($tags[0][$attr]) && ('namespace' !== $attr || ArrayAdapter::class !== $adapter->getClass())) {
|
||||
if (!isset($tags[0][$attr])) {
|
||||
// no-op
|
||||
} elseif ('reset' === $attr) {
|
||||
if ($tags[0][$attr]) {
|
||||
$pool->addTag('kernel.reset', array('method' => $tags[0][$attr]));
|
||||
}
|
||||
} elseif ('namespace' !== $attr || ArrayAdapter::class !== $adapter->getClass()) {
|
||||
$pool->replaceArgument($i++, $tags[0][$attr]);
|
||||
}
|
||||
unset($tags[0][$attr]);
|
||||
}
|
||||
if (!empty($tags[0])) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "namespace" and "default_lifetime", found "%s".', $id, implode('", "', array_keys($tags[0]))));
|
||||
throw new InvalidArgumentException(sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "namespace", "default_lifetime" and "reset", found "%s".', $id, implode('", "', array_keys($tags[0]))));
|
||||
}
|
||||
|
||||
if (null !== $clearer) {
|
||||
|
@ -25,6 +25,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
|
||||
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\Config\Resource\DirectoryResource;
|
||||
@ -339,6 +340,8 @@ class FrameworkExtension extends Extension
|
||||
->addTag('kernel.cache_warmer');
|
||||
$container->registerForAutoconfiguration(EventSubscriberInterface::class)
|
||||
->addTag('kernel.event_subscriber');
|
||||
$container->registerForAutoconfiguration(ResettableInterface::class)
|
||||
->addTag('kernel.reset', array('method' => 'reset'));
|
||||
$container->registerForAutoconfiguration(PropertyListExtractorInterface::class)
|
||||
->addTag('property_info.list_extractor');
|
||||
$container->registerForAutoconfiguration(PropertyTypeExtractorInterface::class)
|
||||
|
@ -8,7 +8,7 @@
|
||||
<defaults public="false" />
|
||||
|
||||
<service id="cache.app" parent="cache.adapter.filesystem" public="true">
|
||||
<tag name="cache.pool" clearer="cache.app_clearer" />
|
||||
<tag name="cache.pool" clearer="cache.app_clearer" reset="reset" />
|
||||
</service>
|
||||
|
||||
<service id="cache.system" parent="cache.adapter.system" public="true">
|
||||
@ -90,7 +90,7 @@
|
||||
</service>
|
||||
|
||||
<service id="cache.adapter.memcached" class="Symfony\Component\Cache\Adapter\MemcachedAdapter" abstract="true">
|
||||
<tag name="cache.pool" provider="cache.default_memcached_provider" clearer="cache.default_clearer" />
|
||||
<tag name="cache.pool" provider="cache.default_memcached_provider" clearer="cache.default_clearer" reset="reset" />
|
||||
<tag name="monolog.logger" channel="cache" />
|
||||
<argument /> <!-- Memcached connection service -->
|
||||
<argument /> <!-- namespace -->
|
||||
|
@ -17,12 +17,13 @@ use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\AbstractTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
|
||||
abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use AbstractTrait;
|
||||
|
||||
|
@ -14,12 +14,13 @@ namespace Symfony\Component\Cache\Adapter;
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ArrayTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ArrayAdapter implements AdapterInterface, LoggerAwareInterface
|
||||
class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use ArrayTrait;
|
||||
|
||||
|
@ -16,6 +16,7 @@ use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* Chains several adapters together.
|
||||
@ -25,7 +26,7 @@ use Symfony\Component\Cache\PruneableInterface;
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ChainAdapter implements AdapterInterface, PruneableInterface
|
||||
class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $adapters = array();
|
||||
private $adapterCount;
|
||||
@ -248,4 +249,16 @@ class ChainAdapter implements AdapterInterface, PruneableInterface
|
||||
|
||||
return $pruned;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
foreach ($this->adapters as $adapter) {
|
||||
if ($adapter instanceof ResettableInterface) {
|
||||
$adapter->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\PhpArrayTrait;
|
||||
|
||||
/**
|
||||
@ -24,7 +26,7 @@ use Symfony\Component\Cache\Traits\PhpArrayTrait;
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PhpArrayAdapter implements AdapterInterface
|
||||
class PhpArrayAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use PhpArrayTrait;
|
||||
|
||||
@ -37,7 +39,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
public function __construct($file, AdapterInterface $fallbackPool)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->fallbackPool = $fallbackPool;
|
||||
$this->pool = $fallbackPool;
|
||||
$this->zendDetectUnicode = ini_get('zend.detect_unicode');
|
||||
$this->createCacheItem = \Closure::bind(
|
||||
function ($key, $value, $isHit) {
|
||||
@ -89,7 +91,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
$this->initialize();
|
||||
}
|
||||
if (!isset($this->values[$key])) {
|
||||
return $this->fallbackPool->getItem($key);
|
||||
return $this->pool->getItem($key);
|
||||
}
|
||||
|
||||
$value = $this->values[$key];
|
||||
@ -144,7 +146,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
return isset($this->values[$key]) || $this->fallbackPool->hasItem($key);
|
||||
return isset($this->values[$key]) || $this->pool->hasItem($key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -159,7 +161,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->values[$key]) && $this->fallbackPool->deleteItem($key);
|
||||
return !isset($this->values[$key]) && $this->pool->deleteItem($key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +188,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
}
|
||||
|
||||
if ($fallbackKeys) {
|
||||
$deleted = $this->fallbackPool->deleteItems($fallbackKeys) && $deleted;
|
||||
$deleted = $this->pool->deleteItems($fallbackKeys) && $deleted;
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
@ -201,7 +203,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->values[$item->getKey()]) && $this->fallbackPool->save($item);
|
||||
return !isset($this->values[$item->getKey()]) && $this->pool->save($item);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,7 +215,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->values[$item->getKey()]) && $this->fallbackPool->saveDeferred($item);
|
||||
return !isset($this->values[$item->getKey()]) && $this->pool->saveDeferred($item);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -221,7 +223,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
return $this->fallbackPool->commit();
|
||||
return $this->pool->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,7 +261,7 @@ class PhpArrayAdapter implements AdapterInterface
|
||||
}
|
||||
|
||||
if ($fallbackKeys) {
|
||||
foreach ($this->fallbackPool->getItems($fallbackKeys) as $key => $item) {
|
||||
foreach ($this->pool->getItems($fallbackKeys) as $key => $item) {
|
||||
yield $key => $item;
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,17 @@ namespace Symfony\Component\Cache\Adapter;
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ProxyAdapter implements AdapterInterface
|
||||
class ProxyAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $pool;
|
||||
use ProxyTrait;
|
||||
|
||||
private $namespace;
|
||||
private $namespaceLen;
|
||||
private $createCacheItem;
|
||||
|
@ -12,13 +12,17 @@
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class SimpleCacheAdapter extends AbstractAdapter
|
||||
class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $pool;
|
||||
use ProxyTrait;
|
||||
|
||||
private $miss;
|
||||
|
||||
public function __construct(CacheInterface $pool, $namespace = '', $defaultLifetime = 0)
|
||||
|
@ -15,26 +15,29 @@ use Psr\Cache\CacheItemInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
const TAGS_PREFIX = "\0tags\0";
|
||||
|
||||
private $itemsAdapter;
|
||||
use ProxyTrait;
|
||||
|
||||
private $deferred = array();
|
||||
private $createCacheItem;
|
||||
private $setCacheItemTags;
|
||||
private $getTagsByKey;
|
||||
private $invalidateTags;
|
||||
private $tagsAdapter;
|
||||
private $tagsPool;
|
||||
|
||||
public function __construct(AdapterInterface $itemsAdapter, AdapterInterface $tagsAdapter = null)
|
||||
public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null)
|
||||
{
|
||||
$this->itemsAdapter = $itemsAdapter;
|
||||
$this->tagsAdapter = $tagsAdapter ?: $itemsAdapter;
|
||||
$this->pool = $itemsPool;
|
||||
$this->tags = $tagsPool ?: $itemsPool;
|
||||
$this->createCacheItem = \Closure::bind(
|
||||
function ($key, $value, CacheItem $protoItem) {
|
||||
$item = new CacheItem();
|
||||
@ -110,7 +113,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
}
|
||||
$f = $this->invalidateTags;
|
||||
|
||||
return $f($this->tagsAdapter, $tags);
|
||||
return $f($this->tags, $tags);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,10 +124,10 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
if (!$this->itemsAdapter->hasItem($key)) {
|
||||
if (!$this->pool->hasItem($key)) {
|
||||
return false;
|
||||
}
|
||||
if (!$itemTags = $this->itemsAdapter->getItem(static::TAGS_PREFIX.$key)->get()) {
|
||||
if (!$itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key)->get()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -165,9 +168,9 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
}
|
||||
|
||||
try {
|
||||
$items = $this->itemsAdapter->getItems($tagKeys + $keys);
|
||||
$items = $this->pool->getItems($tagKeys + $keys);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$this->itemsAdapter->getItems($keys); // Should throw an exception
|
||||
$this->pool->getItems($keys); // Should throw an exception
|
||||
|
||||
throw $e;
|
||||
}
|
||||
@ -182,7 +185,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
{
|
||||
$this->deferred = array();
|
||||
|
||||
return $this->itemsAdapter->clear();
|
||||
return $this->pool->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,7 +207,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
}
|
||||
}
|
||||
|
||||
return $this->itemsAdapter->deleteItems($keys);
|
||||
return $this->pool->deleteItems($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,7 +246,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
if ($this->deferred) {
|
||||
$items = $this->deferred;
|
||||
foreach ($items as $key => $item) {
|
||||
if (!$this->itemsAdapter->saveDeferred($item)) {
|
||||
if (!$this->pool->saveDeferred($item)) {
|
||||
unset($this->deferred[$key]);
|
||||
$ok = false;
|
||||
}
|
||||
@ -257,17 +260,17 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
|
||||
foreach ($tagsByKey as $key => $tags) {
|
||||
if ($tags) {
|
||||
$this->itemsAdapter->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key]));
|
||||
$this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key]));
|
||||
} else {
|
||||
$deletedTags[] = static::TAGS_PREFIX.$key;
|
||||
}
|
||||
}
|
||||
if ($deletedTags) {
|
||||
$this->itemsAdapter->deleteItems($deletedTags);
|
||||
$this->pool->deleteItems($deletedTags);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->itemsAdapter->commit() && $ok;
|
||||
return $this->pool->commit() && $ok;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
@ -328,23 +331,11 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface
|
||||
$tagVersions[$tag] = $tag.static::TAGS_PREFIX;
|
||||
$tags[$tag.static::TAGS_PREFIX] = $tag;
|
||||
}
|
||||
foreach ($this->tagsAdapter->getItems($tagVersions) as $tag => $version) {
|
||||
foreach ($this->tags->getItems($tagVersions) as $tag => $version) {
|
||||
$tagVersions[$tags[$tag]] = $version->get() ?: 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $tagVersions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prune()
|
||||
{
|
||||
if ($this->itemsAdapter instanceof PruneableInterface) {
|
||||
return $this->itemsAdapter->prune();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
namespace Symfony\Component\Cache\Adapter;
|
||||
|
||||
use Psr\Cache\CacheItemInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* An adapter that collects data about all cache calls.
|
||||
@ -20,7 +22,7 @@ use Psr\Cache\CacheItemInterface;
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TraceableAdapter implements AdapterInterface
|
||||
class TraceableAdapter implements AdapterInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
protected $pool;
|
||||
private $calls = array();
|
||||
@ -168,6 +170,38 @@ class TraceableAdapter implements AdapterInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prune()
|
||||
{
|
||||
if (!$this->pool instanceof PruneableInterface) {
|
||||
return false;
|
||||
}
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
return $event->result = $this->pool->prune();
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if (!$this->pool instanceof ResettableInterface) {
|
||||
return;
|
||||
}
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
$this->pool->reset();
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCalls()
|
||||
{
|
||||
try {
|
||||
|
@ -17,7 +17,7 @@ use Psr\Cache\CacheItemPoolInterface;
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class DoctrineProvider extends CacheProvider
|
||||
class DoctrineProvider extends CacheProvider implements PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $pool;
|
||||
|
||||
@ -26,6 +26,25 @@ class DoctrineProvider extends CacheProvider
|
||||
$this->pool = $pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prune()
|
||||
{
|
||||
return $this->pool instanceof PruneableInterface && $this->pool->prune();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->pool instanceof ResettableInterface) {
|
||||
$this->pool->reset();
|
||||
}
|
||||
$this->setNamespace($this->getNamespace());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
20
src/Symfony/Component/Cache/ResettableInterface.php
Normal file
20
src/Symfony/Component/Cache/ResettableInterface.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache;
|
||||
|
||||
/**
|
||||
* Resets a pool's local state.
|
||||
*/
|
||||
interface ResettableInterface
|
||||
{
|
||||
public function reset();
|
||||
}
|
@ -16,11 +16,12 @@ use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\Traits\AbstractTrait;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractCache implements CacheInterface, LoggerAwareInterface
|
||||
abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use AbstractTrait {
|
||||
deleteItems as private;
|
||||
|
@ -15,12 +15,13 @@ use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ArrayTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ArrayCache implements CacheInterface, LoggerAwareInterface
|
||||
class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInterface
|
||||
{
|
||||
use ArrayTrait {
|
||||
ArrayTrait::deleteItem as delete;
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Cache\Simple;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* Chains several caches together.
|
||||
@ -23,7 +24,7 @@ use Symfony\Component\Cache\PruneableInterface;
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ChainCache implements CacheInterface, PruneableInterface
|
||||
class ChainCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $miss;
|
||||
private $caches = array();
|
||||
@ -236,4 +237,16 @@ class ChainCache implements CacheInterface, PruneableInterface
|
||||
|
||||
return $pruned;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
foreach ($this->caches as $cache) {
|
||||
if ($cache instanceof ResettableInterface) {
|
||||
$cache->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Cache\Simple;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\Traits\PhpArrayTrait;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0.
|
||||
@ -22,7 +24,7 @@ use Symfony\Component\Cache\Traits\PhpArrayTrait;
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PhpArrayCache implements CacheInterface
|
||||
class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
use PhpArrayTrait;
|
||||
|
||||
@ -33,7 +35,7 @@ class PhpArrayCache implements CacheInterface
|
||||
public function __construct($file, CacheInterface $fallbackPool)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->fallbackPool = $fallbackPool;
|
||||
$this->pool = $fallbackPool;
|
||||
$this->zendDetectUnicode = ini_get('zend.detect_unicode');
|
||||
}
|
||||
|
||||
@ -68,7 +70,7 @@ class PhpArrayCache implements CacheInterface
|
||||
$this->initialize();
|
||||
}
|
||||
if (!isset($this->values[$key])) {
|
||||
return $this->fallbackPool->get($key, $default);
|
||||
return $this->pool->get($key, $default);
|
||||
}
|
||||
|
||||
$value = $this->values[$key];
|
||||
@ -124,7 +126,7 @@ class PhpArrayCache implements CacheInterface
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
return isset($this->values[$key]) || $this->fallbackPool->has($key);
|
||||
return isset($this->values[$key]) || $this->pool->has($key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +141,7 @@ class PhpArrayCache implements CacheInterface
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->values[$key]) && $this->fallbackPool->delete($key);
|
||||
return !isset($this->values[$key]) && $this->pool->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,7 +172,7 @@ class PhpArrayCache implements CacheInterface
|
||||
}
|
||||
|
||||
if ($fallbackKeys) {
|
||||
$deleted = $this->fallbackPool->deleteMultiple($fallbackKeys) && $deleted;
|
||||
$deleted = $this->pool->deleteMultiple($fallbackKeys) && $deleted;
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
@ -188,7 +190,7 @@ class PhpArrayCache implements CacheInterface
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
return !isset($this->values[$key]) && $this->fallbackPool->set($key, $value, $ttl);
|
||||
return !isset($this->values[$key]) && $this->pool->set($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -216,7 +218,7 @@ class PhpArrayCache implements CacheInterface
|
||||
}
|
||||
|
||||
if ($fallbackValues) {
|
||||
$saved = $this->fallbackPool->setMultiple($fallbackValues, $ttl) && $saved;
|
||||
$saved = $this->pool->setMultiple($fallbackValues, $ttl) && $saved;
|
||||
}
|
||||
|
||||
return $saved;
|
||||
@ -249,7 +251,7 @@ class PhpArrayCache implements CacheInterface
|
||||
}
|
||||
|
||||
if ($fallbackKeys) {
|
||||
foreach ($this->fallbackPool->getMultiple($fallbackKeys, $default) as $key => $item) {
|
||||
foreach ($this->pool->getMultiple($fallbackKeys, $default) as $key => $item) {
|
||||
yield $key => $item;
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,17 @@ use Psr\SimpleCache\CacheException as SimpleCacheException;
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
use Symfony\Component\Cache\CacheItem;
|
||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
use Symfony\Component\Cache\Traits\ProxyTrait;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class Psr6Cache implements CacheInterface
|
||||
class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $pool;
|
||||
use ProxyTrait;
|
||||
|
||||
private $createCacheItem;
|
||||
|
||||
public function __construct(CacheItemPoolInterface $pool)
|
||||
|
@ -12,13 +12,15 @@
|
||||
namespace Symfony\Component\Cache\Simple;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* An adapter that collects data about all cache calls.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class TraceableCache implements CacheInterface
|
||||
class TraceableCache implements CacheInterface, PruneableInterface, ResettableInterface
|
||||
{
|
||||
private $pool;
|
||||
private $miss;
|
||||
@ -177,6 +179,38 @@ class TraceableCache implements CacheInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prune()
|
||||
{
|
||||
if (!$this->pool instanceof PruneableInterface) {
|
||||
return false;
|
||||
}
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
return $event->result = $this->pool->prune();
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if (!$this->pool instanceof ResettableInterface) {
|
||||
return;
|
||||
}
|
||||
$event = $this->start(__FUNCTION__);
|
||||
try {
|
||||
$this->pool->reset();
|
||||
} finally {
|
||||
$event->end = microtime(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCalls()
|
||||
{
|
||||
try {
|
||||
|
@ -50,6 +50,7 @@ class PhpArrayAdapterTest extends AdapterTestCase
|
||||
'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
|
||||
'testDefaultLifeTime' => 'PhpArrayAdapter does not allow configuring a default lifetime.',
|
||||
'testPrune' => 'PhpArrayAdapter just proxies',
|
||||
);
|
||||
|
||||
protected static $file;
|
||||
|
@ -25,6 +25,7 @@ class PhpArrayAdapterWithFallbackTest extends AdapterTestCase
|
||||
'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.',
|
||||
'testPrune' => 'PhpArrayAdapter just proxies',
|
||||
);
|
||||
|
||||
protected static $file;
|
||||
|
@ -24,6 +24,7 @@ class ProxyAdapterTest extends AdapterTestCase
|
||||
protected $skippedTests = array(
|
||||
'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.',
|
||||
'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.',
|
||||
'testPrune' => 'ProxyAdapter just proxies',
|
||||
);
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
|
@ -19,6 +19,10 @@ use Symfony\Component\Cache\Adapter\SimpleCacheAdapter;
|
||||
*/
|
||||
class SimpleCacheAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = array(
|
||||
'testPrune' => 'SimpleCache just proxies',
|
||||
);
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime);
|
||||
|
@ -19,6 +19,10 @@ use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
||||
*/
|
||||
class TraceableAdapterTest extends AdapterTestCase
|
||||
{
|
||||
protected $skippedTests = array(
|
||||
'testPrune' => 'TraceableAdapter just proxies',
|
||||
);
|
||||
|
||||
public function createCachePool($defaultLifetime = 0)
|
||||
{
|
||||
return new TraceableAdapter(new FilesystemAdapter('', $defaultLifetime));
|
||||
|
@ -44,6 +44,7 @@ class PhpArrayCacheTest extends CacheTestCase
|
||||
'testSetValidData' => 'PhpArrayCache does no validation',
|
||||
|
||||
'testDefaultLifeTime' => 'PhpArrayCache does not allow configuring a default lifetime.',
|
||||
'testPrune' => 'PhpArrayCache just proxies',
|
||||
);
|
||||
|
||||
protected static $file;
|
||||
|
@ -31,6 +31,7 @@ class PhpArrayCacheWithFallbackTest extends CacheTestCase
|
||||
'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation',
|
||||
'testHasInvalidKeys' => 'PhpArrayCache does no validation',
|
||||
'testPrune' => 'PhpArrayCache just proxies',
|
||||
);
|
||||
|
||||
protected static $file;
|
||||
|
@ -19,6 +19,10 @@ use Symfony\Component\Cache\Simple\Psr6Cache;
|
||||
*/
|
||||
class Psr6CacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = array(
|
||||
'testPrune' => 'Psr6Cache just proxies',
|
||||
);
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new Psr6Cache(new FilesystemAdapter('', $defaultLifetime));
|
||||
|
@ -19,6 +19,10 @@ use Symfony\Component\Cache\Simple\TraceableCache;
|
||||
*/
|
||||
class TraceableCacheTest extends CacheTestCase
|
||||
{
|
||||
protected $skippedTests = array(
|
||||
'testPrune' => 'TraceableCache just proxies',
|
||||
);
|
||||
|
||||
public function createSimpleCache($defaultLifetime = 0)
|
||||
{
|
||||
return new TraceableCache(new FilesystemCache('', $defaultLifetime));
|
||||
|
@ -189,6 +189,17 @@ trait AbstractTrait
|
||||
return $wasEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->deferred) {
|
||||
$this->commit();
|
||||
}
|
||||
$this->namespaceVersion = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the native unserialize() function but throws an exception if anything goes wrong.
|
||||
*
|
||||
|
@ -69,6 +69,14 @@ trait ArrayTrait
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
private function generateItems(array $keys, $now, $f)
|
||||
{
|
||||
foreach ($keys as $i => $key) {
|
||||
|
@ -20,6 +20,15 @@ trait DoctrineTrait
|
||||
{
|
||||
private $provider;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
parent::reset();
|
||||
$this->provider->setNamespace($this->provider->getNamespace());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -22,9 +22,10 @@ use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||
*/
|
||||
trait PhpArrayTrait
|
||||
{
|
||||
use ProxyTrait;
|
||||
|
||||
private $file;
|
||||
private $values;
|
||||
private $fallbackPool;
|
||||
private $zendDetectUnicode;
|
||||
|
||||
/**
|
||||
@ -119,7 +120,7 @@ EOF;
|
||||
|
||||
$cleared = @unlink($this->file) || !file_exists($this->file);
|
||||
|
||||
return $this->fallbackPool->clear() && $cleared;
|
||||
return $this->pool->clear() && $cleared;
|
||||
}
|
||||
|
||||
/**
|
||||
|
41
src/Symfony/Component/Cache/Traits/ProxyTrait.php
Normal file
41
src/Symfony/Component/Cache/Traits/ProxyTrait.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Traits;
|
||||
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\ResettableInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
trait ProxyTrait
|
||||
{
|
||||
private $pool;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prune()
|
||||
{
|
||||
return $this->pool instanceof PruneableInterface && $this->pool->prune();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if ($this->pool instanceof ResettableInterface) {
|
||||
$this->pool->reset();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user