diff --git a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php index c8d3cbb86b..47db1271b2 100644 --- a/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ArrayAdapter.php @@ -52,9 +52,10 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter /** * {@inheritdoc} */ - public function get(string $key, callable $callback, float $beta = null) + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { $item = $this->getItem($key); + $metadata = $item->getMetadata(); // ArrayAdapter works in memory, we don't care about stampede protection if (INF === $beta || !$item->isHit()) { diff --git a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php index 37972c3530..cd2a05b122 100644 --- a/src/Symfony/Component/Cache/Adapter/ChainAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ChainAdapter.php @@ -87,7 +87,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa /** * {@inheritdoc} */ - public function get(string $key, callable $callback, float $beta = null) + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { $lastItem = null; $i = 0; @@ -98,9 +98,9 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa $beta = INF === $beta ? INF : 0; } if ($adapter instanceof CacheInterface) { - $value = $adapter->get($key, $callback, $beta); + $value = $adapter->get($key, $callback, $beta, $metadata); } else { - $value = $this->doGet($adapter, $key, $callback, $beta); + $value = $this->doGet($adapter, $key, $callback, $beta, $metadata); } if (null !== $item) { ($this->syncItem)($lastItem = $lastItem ?? $item, $item); diff --git a/src/Symfony/Component/Cache/Adapter/NullAdapter.php b/src/Symfony/Component/Cache/Adapter/NullAdapter.php index 876b95b5ce..3c88a6902a 100644 --- a/src/Symfony/Component/Cache/Adapter/NullAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/NullAdapter.php @@ -40,7 +40,7 @@ class NullAdapter implements AdapterInterface, CacheInterface /** * {@inheritdoc} */ - public function get(string $key, callable $callback, float $beta = null) + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { return $callback(($this->createCacheItem)()); } diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php index bce598f4d9..a145a361d1 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php @@ -82,7 +82,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte /** * {@inheritdoc} */ - public function get(string $key, callable $callback, float $beta = null) + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { if (null === $this->values) { $this->initialize(); @@ -90,10 +90,10 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte if (!isset($this->keys[$key])) { get_from_pool: if ($this->pool instanceof CacheInterface) { - return $this->pool->get($key, $callback, $beta); + return $this->pool->get($key, $callback, $beta, $metadata); } - return $this->doGet($this->pool, $key, $callback, $beta); + return $this->doGet($this->pool, $key, $callback, $beta, $metadata); } $value = $this->values[$this->keys[$key]]; diff --git a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php index 7d0cd3df8f..d6b888788d 100644 --- a/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/ProxyAdapter.php @@ -91,10 +91,10 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa /** * {@inheritdoc} */ - public function get(string $key, callable $callback, float $beta = null) + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { if (!$this->pool instanceof CacheInterface) { - return $this->doGet($this, $key, $callback, $beta); + return $this->doGet($this, $key, $callback, $beta, $metadata); } return $this->pool->get($this->getId($key), function ($innerItem) use ($key, $callback) { @@ -103,7 +103,7 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa ($this->setInnerItem)($innerItem, (array) $item); return $value; - }, $beta); + }, $beta, $metadata); } /** diff --git a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php index 7d50d9b796..e1d96bb4ef 100644 --- a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php @@ -38,7 +38,7 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt /** * {@inheritdoc} */ - public function get(string $key, callable $callback, float $beta = null) + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { if (!$this->pool instanceof CacheInterface) { throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', \get_class($this->pool), CacheInterface::class)); @@ -53,7 +53,7 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt $event = $this->start(__FUNCTION__); try { - $value = $this->pool->get($key, $callback, $beta); + $value = $this->pool->get($key, $callback, $beta, $metadata); $event->result[$key] = \is_object($value) ? \get_class($value) : \gettype($value); } finally { $event->end = microtime(true); diff --git a/src/Symfony/Component/Cache/Traits/ContractsTrait.php b/src/Symfony/Component/Cache/Traits/ContractsTrait.php index 71fe729e82..f755e65fc3 100644 --- a/src/Symfony/Component/Cache/Traits/ContractsTrait.php +++ b/src/Symfony/Component/Cache/Traits/ContractsTrait.php @@ -47,7 +47,7 @@ trait ContractsTrait return $previousWrapper; } - private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta) + private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null) { if (0 > $beta = $beta ?? 1.0) { throw new InvalidArgumentException(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', \get_class($this), $beta)); @@ -85,6 +85,6 @@ trait ContractsTrait } finally { $this->callbackWrapper = $callbackWrapper; } - }, $beta); + }, $beta, $metadata); } } diff --git a/src/Symfony/Contracts/Cache/CacheInterface.php b/src/Symfony/Contracts/Cache/CacheInterface.php index 0e2aec324a..4b1686b873 100644 --- a/src/Symfony/Contracts/Cache/CacheInterface.php +++ b/src/Symfony/Contracts/Cache/CacheInterface.php @@ -29,19 +29,20 @@ interface CacheInterface * requested key, that could be used e.g. for expiration control. It could also * be an ItemInterface instance when its additional features are needed. * - * @param string $key The key of the item to retrieve from the cache - * @param callable|CallbackInterface $callback Should return the computed value for the given key/item - * @param float|null $beta A float that, as it grows, controls the likeliness of triggering - * early expiration. 0 disables it, INF forces immediate expiration. - * The default (or providing null) is implementation dependent but should - * typically be 1.0, which should provide optimal stampede protection. - * See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration + * @param string $key The key of the item to retrieve from the cache + * @param callable|CallbackInterface $callback Should return the computed value for the given key/item + * @param float|null $beta A float that, as it grows, controls the likeliness of triggering + * early expiration. 0 disables it, INF forces immediate expiration. + * The default (or providing null) is implementation dependent but should + * typically be 1.0, which should provide optimal stampede protection. + * See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration + * @param array &$metadata The metadata of the cached item {@see ItemInterface::getMetadata()} * * @return mixed The value corresponding to the provided key * * @throws InvalidArgumentException When $key is not valid or when $beta is negative */ - public function get(string $key, callable $callback, float $beta = null); + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null); /** * Removes an item from the pool. diff --git a/src/Symfony/Contracts/Cache/CacheTrait.php b/src/Symfony/Contracts/Cache/CacheTrait.php index d3ff783a9c..d82d96530b 100644 --- a/src/Symfony/Contracts/Cache/CacheTrait.php +++ b/src/Symfony/Contracts/Cache/CacheTrait.php @@ -24,9 +24,9 @@ trait CacheTrait /** * {@inheritdoc} */ - public function get(string $key, callable $callback, float $beta = null) + public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) { - return $this->doGet($this, $key, $callback, $beta); + return $this->doGet($this, $key, $callback, $beta, $metadata); } /** @@ -37,7 +37,7 @@ trait CacheTrait return $this->deleteItem($key); } - private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta) + private function doGet(CacheItemPoolInterface $pool, string $key, callable $callback, ?float $beta, array &$metadata = null) { if (0 > $beta = $beta ?? 1.0) { throw new class(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', \get_class($this), $beta)) extends \InvalidArgumentException implements InvalidArgumentException { @@ -46,9 +46,9 @@ trait CacheTrait $item = $pool->getItem($key); $recompute = !$item->isHit() || INF === $beta; + $metadata = $item instanceof ItemInterface ? $item->getMetadata() : array(); - if (!$recompute && $item instanceof ItemInterface) { - $metadata = $item->getMetadata(); + if (!$recompute && $metadata) { $expiry = $metadata[ItemInterface::METADATA_EXPIRY] ?? false; $ctime = $metadata[ItemInterface::METADATA_CTIME] ?? false; diff --git a/src/Symfony/Contracts/Cache/TagAwareCacheInterface.php b/src/Symfony/Contracts/Cache/TagAwareCacheInterface.php index 86b867df9c..7c4cf11116 100644 --- a/src/Symfony/Contracts/Cache/TagAwareCacheInterface.php +++ b/src/Symfony/Contracts/Cache/TagAwareCacheInterface.php @@ -20,11 +20,6 @@ use Psr\Cache\InvalidArgumentException; */ interface TagAwareCacheInterface extends CacheInterface { - /** - * {@inheritdoc} - */ - public function get(string $key, callable $callback, float $beta = null); - /** * Invalidates cached items using tags. *