cache = $cacheFactory->createDistributed('pagination_'); } /** * @param string $uri * @param \Iterator $items * @return array{'token': string, 'count': int} */ public function store(string $uri, \Iterator $items): array { $token = $this->random->generate(32); $cacheKey = $this->buildCacheKey($uri, $token); $count = 0; foreach ($items as $item) { // Add small margin to avoid fetching valid count and then expired entries $this->cache->set($cacheKey . $count, $item, self::TTL + 60); ++$count; } $this->cache->set($cacheKey . self::CACHE_COUNT_SUFFIX, $count, self::TTL); return ['token' => $token, 'count' => $count]; } /** * @return Generator */ public function get(string $uri, string $token, int $offset, int $count): Generator { $cacheKey = $this->buildCacheKey($uri, $token); $nbItems = $this->cache->get($cacheKey . self::CACHE_COUNT_SUFFIX); if (!$nbItems || $offset > $nbItems) { return []; } $lastItem = min($nbItems, $offset + $count); for ($i = $offset; $i < $lastItem; ++$i) { yield $this->cache->get($cacheKey . $i); } } public function exists(string $uri, string $token): bool { return $this->cache->get($this->buildCacheKey($uri, $token) . self::CACHE_COUNT_SUFFIX) > 0; } private function buildCacheKey(string $uri, string $token): string { return $token . '_' . crc32($uri) . '_'; } }