symfony: [CACHE] Never hits cache with TagAwareAdapter

Symfony version(s) affected

6.4.4

Description

A bit similar to #53825

As in the code below, there is fetching several keys with mget. Keys are already exists in database. First fetch of keys with mget retrieves them all and create good $bufferedItems.

But after that getTagVersion gets wrong tag (screenshot) and unseting them all (TagAwareAdapter.php:191). This bad tag have been stored by this adapter. image

And after unset them all it creates items with hit: false.

How to reproduce

$cache = new TagAwareAdapter(
    new ChainAdapter(
        [
            new ArrayAdapter(300, false, 300),
            new RedisTagAwareAdapter(
                $this->redisConnectionPoolService->getClientByPoolName('cache'),
                'redis.tag.aware.symfony1',
                86400,
                new DefaultMarshaller(false),
            ),
        ],
        300,
    ),
);

$keys = ['key1', 'key2', 'key3'];
$tag = 'some_tag';
$notHitItems = [];
$items = $cache->getItems($keys);
foreach ($items as $item) {
    if (! $item->isHit() || ! is_array($item->get())) {
        $notHitItems[] = $item;
    }
}

foreach ($notHitItems as $item) {
    $item->set(['some_value']);
    $item->expiresAfter(3 * 24 * 60 * 60);
    $item->tag($tag);

    $cache->saveDeferred($item);
}

if (! empty($notHitItems)) {
    $cache->commit();
}

Possible Solution

No response

Additional Context

Chain adapter is not really needed here. But this is my production setup. Seems kinda critical imho

About this issue

  • Original URL
  • State: open
  • Created 4 months ago
  • Reactions: 1
  • Comments: 22 (8 by maintainers)

Most upvoted comments

There are two storage strategies with redis:

  • TagAwareAdapter + RedisAdapter, which requires this second request but has better scalability (needed only if you hit some Redis limits with the second approach)
  • RedisTagAwareAdapter, which requires only one roundtrip (at the expense of more storage requirement, which can be manageable depending on your needs)

Chose one, just don’t mix both 😃

@nicolas-grekas here we go https://github.com/Fahl-Design/cache-issue-reproducer

image

*edit: inside redis: “tags” is always set as a key suffix NOT prefix

image

https://github.com/Fahl-Design/cache-issue-reproducer edit: updated to make it more visible and symfony v7 as well can be reproduces in v6.4 and v7.0

image

image

@nicolas-grekas thanks for clarification, sounds good to me would be a nice addition to prevent RedisTagAwareAdapter in a TagAwareAdapter Chain since is simply dose not work at all