diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index 802c30fa92..b8c4a08021 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -26,6 +26,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface private $deferred = array(); private $createCacheItem; private $getTagsByKey; + private $invalidateTags; private $tagsAdapter; public function __construct(AdapterInterface $itemsAdapter, AdapterInterface $tagsAdapter = null) @@ -33,17 +34,15 @@ class TagAwareAdapter implements TagAwareAdapterInterface $this->itemsAdapter = $itemsAdapter; $this->tagsAdapter = $tagsAdapter ?: $itemsAdapter; $this->createCacheItem = \Closure::bind( - function ($key, $value = null, CacheItem $protoItem = null) { + function ($key, $value, CacheItem $protoItem) { $item = new CacheItem(); $item->key = $key; $item->value = $value; $item->isHit = false; - - if (null !== $protoItem) { - $item->defaultLifetime = $protoItem->defaultLifetime; - $item->innerItem = $protoItem->innerItem; - $item->poolHash = $protoItem->poolHash; - } + $item->defaultLifetime = $protoItem->defaultLifetime; + $item->expiry = $protoItem->expiry; + $item->innerItem = $protoItem->innerItem; + $item->poolHash = $protoItem->poolHash; return $item; }, @@ -62,6 +61,20 @@ class TagAwareAdapter implements TagAwareAdapterInterface null, CacheItem::class ); + $this->invalidateTags = \Closure::bind( + function (AdapterInterface $tagsAdapter, array $tags) { + foreach ($tagsAdapter->getItems($tags) as $v) { + $v->set(1 + (int) $v->get()); + $v->defaultLifetime = 0; + $v->expiry = null; + $tagsAdapter->saveDeferred($v); + } + + return $tagsAdapter->commit(); + }, + null, + CacheItem::class + ); } /** @@ -74,13 +87,9 @@ class TagAwareAdapter implements TagAwareAdapterInterface $tags[$k] = $tag.static::TAGS_PREFIX; } } + $f = $this->invalidateTags; - foreach ($this->tagsAdapter->getItems($tags) as $v) { - $v->set(1 + (int) $v->get()); - $this->tagsAdapter->saveDeferred($v); - } - - return $this->tagsAdapter->commit(); + return $f($this->tagsAdapter, $tags); } /** @@ -211,7 +220,8 @@ class TagAwareAdapter implements TagAwareAdapterInterface $ok = true; if ($this->deferred) { - foreach ($this->deferred as $key => $item) { + $items = $this->deferred; + foreach ($items as $key => $item) { if (!$this->itemsAdapter->saveDeferred($item)) { unset($this->deferred[$key]); $ok = false; @@ -219,14 +229,14 @@ class TagAwareAdapter implements TagAwareAdapterInterface } $f = $this->getTagsByKey; - $tagsByKey = $f($this->deferred); + $tagsByKey = $f($items); $deletedTags = $this->deferred = array(); $tagVersions = $this->getTagVersions($tagsByKey); $f = $this->createCacheItem; foreach ($tagsByKey as $key => $tags) { if ($tags) { - $this->itemsAdapter->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags))); + $this->itemsAdapter->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key])); } else { $deletedTags[] = static::TAGS_PREFIX.$key; } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php index 20b1fd7a07..24586c0ca9 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php @@ -97,4 +97,21 @@ class TagAwareAdapterTest extends AdapterTestCase $this->assertTrue($pool->getItem('k')->isHit()); } + + public function testTagItemExpiry() + { + $pool = $this->createCachePool(10); + + $item = $pool->getItem('foo'); + $item->tag(array('baz')); + $item->expiresAfter(100); + + $pool->save($item); + $pool->invalidateTags(array('baz')); + $this->assertFalse($pool->getItem('foo')->isHit()); + + sleep(20); + + $this->assertFalse($pool->getItem('foo')->isHit()); + } }