Skip to content

[Cache] TagAwareAdapter in combination with lifetime can return items with invalidated tags #21330

Closed
@maff

Description

@maff
Q A
Bug report? no
Feature request? no
BC Break report? no
RFC? no
Symfony version 3.2.1

When using the TagAwareAdapter in combination with an adapter with a default lifetime set it is possible to have the cache return previously invalidated items. See the example below:

<?php

use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Component\Cache\CacheItem;

class TagAwareAdapterTest extends TestCase
{
    public function testItemKeepsBeingExpired()
    {
        // items expire after 10 seconds
        $itemsAdapter = new ArrayAdapter(10);

        // tag adapter uses the same adapter for items and tags, expiring the tag items with the default lifetime
        $adapter = new TagAwareAdapter($itemsAdapter);

        /** @var CacheItem $item */
        $item = $adapter->getItem('foo');

        $item->set('bar');
        $item->tag(['baz']);
        $item->expiresAfter(100); // explicitely define a longer expiration

        $adapter->save($item);
        $this->assertTrue($adapter->getItem('foo')->isHit());

        $adapter->invalidateTags(['baz']);
        $this->assertFalse($adapter->getItem('foo')->isHit());

        // add an extra second to make sure tag invalidation version expires
        sleep(11);

        // this fails - item is available again as its tag invalidation version expired
        // isHit() returns true and the item has data again (as if the tag was never invalidated)
        $this->assertFalse($adapter->getItem('foo')->isHit());
    }
}

Technically it is not a bug as the adapter behaves as expected, but for the consumer it is not obvious why this can happen without studying the internals of how the TagAwareAdapter tracks invalidation. What do you think of one of the following?

  • Saving tag invalidation data with an infinite lifetime
  • Explicitely pointing out this behaviour in the documentation

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions