laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 31 forks source link

Add Support for Tagging Cache Items Without Tag Namespacing #2625

Open cradigan opened 3 years ago

cradigan commented 3 years ago

Summary

Currently in order to retrieve a tagged item from the cache you need knowledge of all the tags applied to that item. This is because laravel prepends a tags namespace on the cache key when creating a tagged item. I have a use case where I need to flush cache items by tags but still retrieve the items without knowlege of every tag that might have been applied.

Issue in more detail

Right now (with the Redis driver) if you do: Cache::tags(‘tag1’, ‘tag2’, ‘tag3’)->set(‘myCacheKey’, ‘myCacheValue’)

The cache key actually saves as something similar to: {sha1(‘tag:tag1,tag:tag2,tag:tag3’):myCacheKey

This means if you want to to check the value for myCacheKey you need to know all the tags and the order of the tags. Eg:

Cache::tags(‘tag1’, ‘tag2’, ‘tag3’)->get(‘myCacheKey’) == ‘myCacheValue’
Cache::get(‘myCacheKey’) == null
Cache::tags(‘tag1’)->get(‘myCacheKey’) == null
Cache::tags(‘tag3’, ‘tag2’, ‘tag1’)->get(‘myCacheKey’) == null

I have a use case where I need to be able to add tags to a cache item and then look it up by key without any knowledge of the original tags.

Proposed Solution

I was thinking of maybe an implementation like this:

Cache::tags(‘tag3’, ‘tag2’, ‘tag1’)->useNamespace(false)->set(‘myCacheKey’, ‘myCacheValue’);
Cache::get(‘myCacheKey’) == ‘myCacheValue’

I’ve currently got this working via a custom redis cache driver which extends the default one. But I think maybe this could be a part of laravel itself.

So far I’ve only taken the time to dive into the Redis driver, so not sure yet what challenges might be presented when adding support to the other tag supported drivers.

dimitri-koenig commented 3 years ago

https://github.com/swayok/alternative-laravel-cache has a solution which works as it should imho. I really would like to see that in Laravel Core.

Simple use case: Caching a list with items, having key "main-list", but adding tags to it like "item-1", "item-2", where I don't know the tags beforehand. That's why I want to cache it, add tags to it, and invalidate the whole list as soon as I flush one of the tags. But accessing it should be possible with simple get('main-list').