Uložení Guzzle requestu do Nette cache

pata.kusik111
Člen | 78
+
0
-

Ahoj,
dělám nový pohled nad daty z jiného webu, takže si stáhnu HTML z URL a to si rozparsuju.
Protože nechci zbytečně zatěžovat tu aplikaci, tak si všechny „stabilní“ response ukládám do cache, ale zaboha nemohu přijít na to, proč nemohu načítat z cache napříč requesty:


final class GoutteClientFactory
{
    public static function create(IStorage $storage): GoutteClient
    {
        $stack = new HandlerStack();
        $stack->setHandler(new CurlHandler());

        $thisRequestCacheStrategy = new class(new class implements CacheStorageInterface
        {
            /** @var array */
            private $storage = [];

            public function fetch($key)
            {
                return $this->storage[$key] ?? null;
            }

            public function save(
                $key, CacheEntry $data
            ): bool {
                $this->storage[$key] = $data;
                return true;
            }

            public function delete($key): bool
            {
                unset($this->storage[$key]);
                return true;
            }
        }) implements CacheStrategyInterface
        {
            /** @var CacheStorageInterface */
            private $cacheStorage;

            public function __construct(CacheStorageInterface $cacheStorage)
            {
                $this->cacheStorage = $cacheStorage;
            }

            private static function key(RequestInterface $request): string
            {
                return sha1($request->getUri()->__toString());
            }

            public function fetch(RequestInterface $request): ?CacheEntry
            {
                Debugger::barDump([
                                      'loading from memory',
                                      self::key($request),
                                      $this->cacheStorage->fetch(self::key($request))
                                  ]);
                return $this->cacheStorage->fetch(self::key($request));
            }

            public function cache(RequestInterface $request, ResponseInterface $response): bool
            {
                Debugger::barDump(['saving to memory']);
                return $this->cacheStorage->save(self::key($request),
                                                 new CacheEntry($request, $response, new DateTime()));
            }

            public function update(RequestInterface $request, ResponseInterface $response): bool
            {
                return $this->cacheStorage->save(self::key($request),
                                                 new CacheEntry($request, $response, new DateTime()));
            }

            public function delete(RequestInterface $request): bool
            {
                return $this->cacheStorage->delete(self::key($request));
            }
        };

        $cache = new Cache($storage, 'webPage');

        $netteCacheStrategy = new class($cache) implements CacheStrategyInterface
        {

            /** @var Cache */
            private $cache;

            public function __construct(Cache $cache)
            {
                $this->cache = $cache;
            }

            private static function key(RequestInterface $request): string
            {
                return sha1($request->getUri()->__toString());
            }

            public function fetch(RequestInterface $request): ?CacheEntry
            {
                Debugger::barDump([
                                      'loading from nette',
                                      self::key($request),
                                      $this->cache->load(self::key($request))
                                  ]);
                return $this->cache->load(self::key($request));
            }

            public function cache(RequestInterface $request, ResponseInterface $response): bool
            {
                Debugger::barDump(['saving to cache']);
                $this->cache->save(self::key($request), new CacheEntry($request, $response, new DateTime()), [
                    Cache::EXPIRE  => '20 minutes',
                    Cache::SLIDING => true,
                ]);
                return true;
            }

            public function update(RequestInterface $request, ResponseInterface $response): bool
            {
                $this->cache->save(self::key($request), new CacheEntry($request, $response, new DateTime()), [
                    Cache::EXPIRE  => '20 minutes',
                    Cache::SLIDING => true,
                ]);
                return true;
            }

            public function delete(RequestInterface $request): bool
            {
                $this->cache->remove(self::key($request));
                return true;
            }
        };

        $strategy = new DelegatingCacheStrategy($netteCacheStrategy);
        $strategy->registerRequestMatcher(new class implements RequestMatcherInterface
        {
            public function matches(RequestInterface $request): bool
            {
                return Strings::contains($request->getUri()->getPath(), 'VysledkySouteziPredbezne');
            }
        }, $thisRequestCacheStrategy);
        $stack->push(new CacheMiddleware($strategy));

        $panel = new Panel();
        $stack->push(new Middleware($panel));
        Debugger::getBar()->addPanel($panel);

        return (new GoutteClient())->setClient(new Client(['handler' => $stack]));
    }
}
Jak to funguje teď
všechny requesty na obsahující v URL „VysledkySouteziPredbezne“ se cachují pouze do paměti (tak abych v jednom běhu na mojí aplikaci se na tu URL dotazoval jenom jednou) – tady se data ale „rychle“ mění, tak to nehci cachovat napříč requesty
vše ostatní se ukládá do nette pomocí $netteCacheStrategy
při druhém reqeustu na mojí aplikaci se data z $netteCacheStrategy pro URL nenačtou a já udělám nový request (vidím v Tracy panelu)
Jak to má fungovat
při druhém reqeustu na mojí aplikaci se data z $netteCacheStrategy mají načíst a já nemám dělat request na aplikaci ze které data získávám.
Příklady z barDump/Tracy panelu
První request (26 dotazů jde na API skrz)

0 => "loading from nette"
1 => "bbda9713296440f71bcfddbe4a898ec30fe785e6"
2 => null

0 => "saving to cache"

0 => "loading from nette"
1 => "95f6b79a9f71631de6319a6427d337b8027c8773"
2 => null

0 => "saving to cache"

0 => "loading from nette"
1 => "92a27f114ba4b336b6ef2a153050f9815cbee820"
2 => null

atd.

Druhý request (opět 26 dotazů ale mělo by být 0):


0 => "loading from nette"
1 => "bbda9713296440f71bcfddbe4a898ec30fe785e6"
2 => CacheEntry

0 => "saving to cache"

0 => "loading from nette"
1 => "95f6b79a9f71631de6319a6427d337b8027c8773"
2 => CacheEntry

0 => "saving to cache"

0 => "loading from nette"
1 => "92a27f114ba4b336b6ef2a153050f9815cbee820"
2 => CacheEntry

atd.

Tady by se nemělo ani být "saving to cache"

Podotýkám, že $thisRequestCacheStrategy funguje OK.

Vidíte někdo, v čem je problém?

Jan Tvrdík
Nette guru | 2595
+
0
-

Potřebuješ pomoc s nastavením xdebugu? Nebo vysvětlit, jak se pomocí xdebugu podobné problémy diagnostikují?