Unable to get the latest value even cache is flushed
I am using Laravel 10 and Redis as cache driver.
Precisely, I am able to clear cache but I still get the old cached value. I have a Eloquent model called SystemSetting. I created a helper class to fetch data from the model. Then, I have a global helper function gss() which will be used in blade file to get specify system setting value.
if (!function_exists('gss')) {
function gss($key, $fallback = null)
{
return wncms()->system_setting()->get($key, $fallback);
}
}
wncms()->system_setting() will instantiate the system setting helper class and call the get() function.
//in SystemSettingHelper.php class
function get(string $key, $fallback = null)
{
$systemSettings = $this->getList();
return $systemSettings[$key] ?? $fallback;
}
in the get() function of class SystemSettingHelper, it call getList() to get an array of SystemSetting value and return value by array key
function getList(string|array|null $keys = [])
{
$method = "getList";
$shouldAuth = false;
$cacheKey = wn('cache')->createKey($this->cacheKeyPrefix, $method, $shouldAuth, wn()->getAllArgs(__METHOD__, func_get_args()));
$cacheTags = ['system_settings'];
$cacheTime = 3600;
// wn('cache')->clear($cacheKey, $cacheTags);
//cache()->tags($cacheTags)->flush();
return cache()->tags($cacheTags)->remember($cacheKey, $cacheTime, function () use($keys){
try{
if(!wncms_is_installed()) return [];
$q = SystemSetting::query();
if(!empty($keys)){
if(is_string($keys)){
$keys = explode(",", $keys);
}
$q->whereIn('key', $keys);
}
//return all keys if empty $keys is passed
return $q->pluck('value', 'key')->toArray();;
}catch(\Exception $e){
info($e->getMessage());
return [];
}
});
}
In above getList() function, $cacheKey is just a string generate from parameters passed. Its always the same when its called from get(). Then I use a cache tag ['system_settings'] to tag these cache.
Whenever I update some of the system settings. I will call cache()->tags(['system_settings'])->flush();. So matter what the $cacheKey it was, getList() should have the fresh new value because all cache key should be tagged by ['system_settings']
After I updated value of system setting with key version, I should get the latest value by calling gss('version'). However, I will get the old version value.
The following is some investigation I have done:
- flush cache and compare values. gss() show the old one while Eloquent method show the latest one.
dd(
cache()->tags(['system_settings'])->flush(), //return true
gss('version'), // return '3.0.6'
SystemSetting::where('key','version')->first()?->value, // return 3.0.7
);
- tags() function of Redis cache is intact. I write a simple test for it. When I flush tagged cache, $x always return a different value. When I disable the cache. It show the cached value.
$x = time();
$cacheTag = ['test'];
//cache()->tags($cacheTag)->flush();
$cache = cache()->tags($cacheTag)->remember('mytest', 3600, function() use($x){
return $x;
});
dd($cache);
- I have multiple laravel website on the same server so at the beginning I suspect it read cached data from other applications. Then I check the cache prefix of the app. In
configcache.phpand cache prefix is generated from APP_NAME (env don't have CACHE_PREFIX) which I am sure its specific to this application. Besides the old value retrieved from gss('version') is also specifc to this application.
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
To sum up. My problem is that even if I cleared cache with the tag ['system_settings']. gss() still get the old cached value. I have no idea where to debug. Please help.
Please or to participate in this conversation.