-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] Redis - Deleting Cached Items Once Expired #142
Comments
I think the problem is it only uses the ttl when fetching from the cache but not when saving to the cache. This is because some Cache Control rules allow serving from cache after the max-age has passed. There might be a way to configure a default ttl, maybe a global max ttl config would be useful. |
We tackled this problem this week. The issue is that if the response has a validation header ( This would be fine for a large file cache but when using redis the memory limits are more restrictive and the eviction policy doesn't work well with large amounts of entries with no ttl. We've written our own implementation which unfortunately requires reflection. I'll submit a PR at some point that allows for a nicer way of doing this. <?php
namespace Frontend\Http\Guzzle;
use Kevinrob\GuzzleCache\CacheEntry;
use Kevinrob\GuzzleCache\Storage\LaravelCacheStorage;
use ReflectionObject;
use ReflectionProperty;
class LaravelTtlAwareCacheStorage extends LaravelCacheStorage
{
/**
* {@inheritdoc}
*/
public function save($key, CacheEntry $data)
{
try {
$lifeTime = $this->getLifeTime($data);
if ($lifeTime > 0) {
return $this->cache->add(
$key,
serialize($data),
$lifeTime
);
}
} catch (\Throwable $ignored) {
report($ignored);
}
return false;
}
protected function getLifeTime(CacheEntry $data)
{
$ttl = $data->getTTL();
if ($ttl < 0) {
return $ttl;
}
$entry = $this->makeAccessible($data);
$stateIfError = $entry['staleIfErrorTo']
? now()->diffInSeconds($entry['staleIfErrorTo']) : 0;
$staleWhileRevalidate = $entry['staleWhileRevalidateTo']
? now()->diffInSeconds($entry['staleWhileRevalidateTo']) : 0;
return max(now()->diffInSeconds($entry['staleAt']), $stateIfError, $staleWhileRevalidate);
}
private function makeAccessible(CacheEntry $entry)
{
return collect((new ReflectionObject($entry))->getProperties())
->each(fn (ReflectionProperty $property) => $property->setAccessible(true))
->keyBy(fn (ReflectionProperty $property) => $property->getName())
->map(fn (ReflectionProperty $property) => $property->getValue($entry));
}
} |
I have my caching set up as such which works as expected:
The one issue is, the items aren't being deleted from Redis.
The cache isn't being hit and requests are being sent once the TTL has expired which is expected, but as mentioned above the items aren't actually being deleted from Redis.
How would one set the items to delete automatically?
The text was updated successfully, but these errors were encountered: