Giter Site home page Giter Site logo

Comments (2)

rhysemmerson avatar rhysemmerson commented on June 12, 2024

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.

from guzzle-cache-middleware.

rhysemmerson avatar rhysemmerson commented on June 12, 2024

We tackled this problem this week. The issue is that if the response has a validation header (Last-Modifed, etag etc) the LaravelCacheStorage class will use forever when saving to cache. This is because the response could be revalidated after it becomes stale.

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));
    }
}

from guzzle-cache-middleware.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.