diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php index 6a633c7b25..dafe0b7b8f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php @@ -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) { diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 4a940a70f0..ebb594fac1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -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) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml index cbed70e4e1..16b15a6617 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml @@ -8,7 +8,7 @@ - + @@ -90,7 +90,7 @@ - + diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 6b38991b77..a2fae2fc2f 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -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 */ -abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface +abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface { use AbstractTrait; diff --git a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php index 45c19c7a6c..2118e9c6ff 100644 --- a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php @@ -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 */ -class ArrayAdapter implements AdapterInterface, LoggerAwareInterface +class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface { use ArrayTrait; diff --git a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php index c38949975d..6bdf6b2d54 100644 --- a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php @@ -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 */ -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(); + } + } + } } diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php index 7e9686a018..511224f854 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php @@ -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 * @author Nicolas Grekas */ -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; } } diff --git a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php index cd310be062..82c95c5b04 100644 --- a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php @@ -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 */ -class ProxyAdapter implements AdapterInterface +class ProxyAdapter implements AdapterInterface, PruneableInterface, ResettableInterface { - private $pool; + use ProxyTrait; + private $namespace; private $namespaceLen; private $createCacheItem; diff --git a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php index f176624410..24db5d504a 100644 --- a/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/SimpleCacheAdapter.php @@ -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 */ -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) diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index 96df1128bb..cb71ed3fd8 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -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 */ -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; - } } diff --git a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php index 9959199f67..e8563521ba 100644 --- a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php @@ -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 * @author Nicolas Grekas */ -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 { diff --git a/src/Symfony/Component/Cache/DoctrineProvider.php b/src/Symfony/Component/Cache/DoctrineProvider.php index 5d9c2faed7..cebe95fbc7 100644 --- a/src/Symfony/Component/Cache/DoctrineProvider.php +++ b/src/Symfony/Component/Cache/DoctrineProvider.php @@ -17,7 +17,7 @@ use Psr\Cache\CacheItemPoolInterface; /** * @author Nicolas Grekas */ -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} */ diff --git a/src/Symfony/Component/Cache/ResettableInterface.php b/src/Symfony/Component/Cache/ResettableInterface.php new file mode 100644 index 0000000000..6be72861e7 --- /dev/null +++ b/src/Symfony/Component/Cache/ResettableInterface.php @@ -0,0 +1,20 @@ + + * + * 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(); +} diff --git a/src/Symfony/Component/Cache/Simple/AbstractCache.php b/src/Symfony/Component/Cache/Simple/AbstractCache.php index 264eb60653..e666effaf9 100644 --- a/src/Symfony/Component/Cache/Simple/AbstractCache.php +++ b/src/Symfony/Component/Cache/Simple/AbstractCache.php @@ -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 */ -abstract class AbstractCache implements CacheInterface, LoggerAwareInterface +abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface { use AbstractTrait { deleteItems as private; diff --git a/src/Symfony/Component/Cache/Simple/ArrayCache.php b/src/Symfony/Component/Cache/Simple/ArrayCache.php index a89768b0e2..8d027cd2a3 100644 --- a/src/Symfony/Component/Cache/Simple/ArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/ArrayCache.php @@ -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 */ -class ArrayCache implements CacheInterface, LoggerAwareInterface +class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInterface { use ArrayTrait { ArrayTrait::deleteItem as delete; diff --git a/src/Symfony/Component/Cache/Simple/ChainCache.php b/src/Symfony/Component/Cache/Simple/ChainCache.php index 8bb944fd47..9d0c75870e 100644 --- a/src/Symfony/Component/Cache/Simple/ChainCache.php +++ b/src/Symfony/Component/Cache/Simple/ChainCache.php @@ -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 */ -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(); + } + } + } } diff --git a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php index 92180e6316..3db8a2ac1c 100644 --- a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php @@ -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 * @author Nicolas Grekas */ -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; } } diff --git a/src/Symfony/Component/Cache/Simple/Psr6Cache.php b/src/Symfony/Component/Cache/Simple/Psr6Cache.php index 55fa98da12..81f14d4a70 100644 --- a/src/Symfony/Component/Cache/Simple/Psr6Cache.php +++ b/src/Symfony/Component/Cache/Simple/Psr6Cache.php @@ -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 */ -class Psr6Cache implements CacheInterface +class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterface { - private $pool; + use ProxyTrait; + private $createCacheItem; public function __construct(CacheItemPoolInterface $pool) diff --git a/src/Symfony/Component/Cache/Simple/TraceableCache.php b/src/Symfony/Component/Cache/Simple/TraceableCache.php index 29cc10bbb2..756403bf14 100644 --- a/src/Symfony/Component/Cache/Simple/TraceableCache.php +++ b/src/Symfony/Component/Cache/Simple/TraceableCache.php @@ -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 */ -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 { diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php index 134dba7c90..14b61263c5 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php @@ -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; diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php index 45a50d2323..1a23198c2f 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php @@ -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; diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ProxyAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ProxyAdapterTest.php index c0174dd248..5e6abd16c1 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ProxyAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ProxyAdapterTest.php @@ -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) diff --git a/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php index 1e0297c69e..d5795d52e7 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/SimpleCacheAdapterTest.php @@ -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); diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TraceableAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TraceableAdapterTest.php index dec2f25555..3755e88db5 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/TraceableAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/TraceableAdapterTest.php @@ -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)); diff --git a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php index 57361905f8..1bd0ca2778 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php @@ -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; diff --git a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php index a624fa73e7..4b6a94f709 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php @@ -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; diff --git a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php index 16e21d0c0b..78582894fb 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/Psr6CacheTest.php @@ -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)); diff --git a/src/Symfony/Component/Cache/Tests/Simple/TraceableCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/TraceableCacheTest.php index 7feccba1af..535f93da4b 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/TraceableCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/TraceableCacheTest.php @@ -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)); diff --git a/src/Symfony/Component/Cache/Traits/AbstractTrait.php b/src/Symfony/Component/Cache/Traits/AbstractTrait.php index 108ac67c8e..d7af3b559e 100644 --- a/src/Symfony/Component/Cache/Traits/AbstractTrait.php +++ b/src/Symfony/Component/Cache/Traits/AbstractTrait.php @@ -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. * diff --git a/src/Symfony/Component/Cache/Traits/ArrayTrait.php b/src/Symfony/Component/Cache/Traits/ArrayTrait.php index 3fb5fa36be..b7d2ad6d62 100644 --- a/src/Symfony/Component/Cache/Traits/ArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/ArrayTrait.php @@ -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) { diff --git a/src/Symfony/Component/Cache/Traits/DoctrineTrait.php b/src/Symfony/Component/Cache/Traits/DoctrineTrait.php index be351cf53a..c87ecabafc 100644 --- a/src/Symfony/Component/Cache/Traits/DoctrineTrait.php +++ b/src/Symfony/Component/Cache/Traits/DoctrineTrait.php @@ -20,6 +20,15 @@ trait DoctrineTrait { private $provider; + /** + * {@inheritdoc} + */ + public function reset() + { + parent::reset(); + $this->provider->setNamespace($this->provider->getNamespace()); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php index ccc48886d0..ae634d6baa 100644 --- a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php @@ -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; } /** diff --git a/src/Symfony/Component/Cache/Traits/ProxyTrait.php b/src/Symfony/Component/Cache/Traits/ProxyTrait.php new file mode 100644 index 0000000000..06dba7e59b --- /dev/null +++ b/src/Symfony/Component/Cache/Traits/ProxyTrait.php @@ -0,0 +1,41 @@ + + * + * 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 + */ +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(); + } + } +}