Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel flush cache with more than one tag

I'm using Redis cache on Laravel 5.2, and I have my keys with 2 tags (basically), the year and the source.

Example:

$this->cache->tags(['online', 2016])->put("key1", $value1, 10));
$this->cache->tags(['online', 2016])->put("key2", $value2, 10));
$this->cache->tags(['online', 2017])->put("key3", $value3, 10));
$this->cache->tags(['online', 2017])->put("key4", $value4, 10));

$this->cache->tags(['database', 2016])->put("key5", $value5, 10));
$this->cache->tags(['database', 2016])->put("key6", $value6, 10));
$this->cache->tags(['database', 2017])->put("key7", $value7, 10));
$this->cache->tags(['database', 2017])->put("key8", $value8, 10));

I want to flush the cache for the tags 2016 & online.

Using this $this->cache->tags(['online', 2016])->flush(); It will flush everything with any of the tags, i.e., either online or 2016 (in this case key1, key2, key3, key4, key5, key6).

I want to delete everything including all the tags, i.e., both online and 2016 (in this case only key1 and key2)

like image 598
Pepote Avatar asked Jun 22 '17 07:06

Pepote


People also ask

Which command is used to reset the cache in Laravel?

Removing items from the cache programmatically is as easy as clearing the cache via the artisan command. In addition, you can use the cache facade to access the cache or use the cache helper.

How does Laravel manage cache?

The cache configuration is located at app/config/cache. php . In this file you may specify which cache driver you would like used by default throughout your application. Laravel supports popular caching backends like Memcached and Redis out of the box.

What does php artisan config clear do?

php artisan config:clear Laravel stores all the configuration from App/config directory to a single cached config file at App/bootstrap/cache/config.


2 Answers

So this took a bit of digging but here's the verdict.

Yes this is technically possible (the best kind of possible?)

First of all, the RedisTaggedCache (responsible for implementing tagging in redis) stores all tag member keys in a redis set. Here's how to discover where it is and how you can get all keys:

function getAllTagKeys($cache,$tags) {
    $tagStore = new TagSet($cache->getStore(),$tags);
    $key = "<prefix>:{$tagStore->getNamespace()}:". RedisTaggedCache::REFERENCE_KEY_STANDARD;//use REFERENCE_KEY_FOREVER if the keys are cached forever or both one after the other to get all of them
    return collect($cache->getRedis()->smembers($key));
}

Then you can do:

getAllTagKeys($this->cache, ["online"])
    ->insersect(getAllTagKeys($this->cache, ["2016"]))
    ->each(function ($v) {
         $this->cache->getRedis()->del();
     });

This looks like a horrible way to do this. Perhaps it's more sensible to make a feature request to Laravel since this looks like it's something they should be exposing?

like image 116
apokryfos Avatar answered Oct 16 '22 16:10

apokryfos


I think I would make a key to fit the delete ...

$this->cache->tags([andKey('online', 2016)])->put("key1", $value1, 10)); 
$this->cache->tags([andKey('online', 2016)])->put("key2", $value2, 10));
    
$this->cache->tags([andKey('online', 2016)])->flush();

helper:
function andKey($a, $b)
{
   return sprintf("%s.%s", $a, $b);  
}

Bit more work, but will save loads of headache when cache system is changed.

edit: As suggested in comments you can add all keys and flush on any 3.

$this->cache->tags(['online', '2016', andKey('online', 2016)])->put("key1", $value1, 10)); 
$this->cache->tags(['online', '2016', andKey('online', 2016)])->put("key2", $value2, 10));
   
$this->cache->tags([andKey('online', 2016)])->flush();

helper:
function andKey($a, $b)
{
   return sprintf("combined.%s.%s", $a, $b);  
}
like image 31
Joeri Avatar answered Oct 16 '22 14:10

Joeri