[Contracts][Cache] allow retrieving metadata of cached items

This commit is contained in:
Nicolas Grekas 2018-11-24 10:35:08 +01:00
parent 4c1e8bd836
commit 302b8446a7
10 changed files with 30 additions and 33 deletions

View File

@ -52,9 +52,10 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
/** /**
* {@inheritdoc} * {@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); $item = $this->getItem($key);
$metadata = $item->getMetadata();
// ArrayAdapter works in memory, we don't care about stampede protection // ArrayAdapter works in memory, we don't care about stampede protection
if (INF === $beta || !$item->isHit()) { if (INF === $beta || !$item->isHit()) {

View File

@ -87,7 +87,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
/** /**
* {@inheritdoc} * {@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; $lastItem = null;
$i = 0; $i = 0;
@ -98,9 +98,9 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
$beta = INF === $beta ? INF : 0; $beta = INF === $beta ? INF : 0;
} }
if ($adapter instanceof CacheInterface) { if ($adapter instanceof CacheInterface) {
$value = $adapter->get($key, $callback, $beta); $value = $adapter->get($key, $callback, $beta, $metadata);
} else { } else {
$value = $this->doGet($adapter, $key, $callback, $beta); $value = $this->doGet($adapter, $key, $callback, $beta, $metadata);
} }
if (null !== $item) { if (null !== $item) {
($this->syncItem)($lastItem = $lastItem ?? $item, $item); ($this->syncItem)($lastItem = $lastItem ?? $item, $item);

View File

@ -40,7 +40,7 @@ class NullAdapter implements AdapterInterface, CacheInterface
/** /**
* {@inheritdoc} * {@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)()); return $callback(($this->createCacheItem)());
} }

View File

@ -82,7 +82,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
/** /**
* {@inheritdoc} * {@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) { if (null === $this->values) {
$this->initialize(); $this->initialize();
@ -90,10 +90,10 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
if (!isset($this->keys[$key])) { if (!isset($this->keys[$key])) {
get_from_pool: get_from_pool:
if ($this->pool instanceof CacheInterface) { 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]]; $value = $this->values[$this->keys[$key]];

View File

@ -91,10 +91,10 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
/** /**
* {@inheritdoc} * {@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) { 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) { 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); ($this->setInnerItem)($innerItem, (array) $item);
return $value; return $value;
}, $beta); }, $beta, $metadata);
} }
/** /**

View File

@ -38,7 +38,7 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
/** /**
* {@inheritdoc} * {@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) { 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)); 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__); $event = $this->start(__FUNCTION__);
try { 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); $event->result[$key] = \is_object($value) ? \get_class($value) : \gettype($value);
} finally { } finally {
$event->end = microtime(true); $event->end = microtime(true);

View File

@ -47,7 +47,7 @@ trait ContractsTrait
return $previousWrapper; 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) { 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)); 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 { } finally {
$this->callbackWrapper = $callbackWrapper; $this->callbackWrapper = $callbackWrapper;
} }
}, $beta); }, $beta, $metadata);
} }
} }

View File

@ -29,19 +29,20 @@ interface CacheInterface
* requested key, that could be used e.g. for expiration control. It could also * requested key, that could be used e.g. for expiration control. It could also
* be an ItemInterface instance when its additional features are needed. * be an ItemInterface instance when its additional features are needed.
* *
* @param string $key The key of the item to retrieve from the cache * @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 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 * @param float|null $beta A float that, as it grows, controls the likeliness of triggering
* early expiration. 0 disables it, INF forces immediate expiration. * early expiration. 0 disables it, INF forces immediate expiration.
* The default (or providing null) is implementation dependent but should * The default (or providing null) is implementation dependent but should
* typically be 1.0, which should provide optimal stampede protection. * typically be 1.0, which should provide optimal stampede protection.
* See https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration * 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 * @return mixed The value corresponding to the provided key
* *
* @throws InvalidArgumentException When $key is not valid or when $beta is negative * @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. * Removes an item from the pool.

View File

@ -24,9 +24,9 @@ trait CacheTrait
/** /**
* {@inheritdoc} * {@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); 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) { 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 { 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); $item = $pool->getItem($key);
$recompute = !$item->isHit() || INF === $beta; $recompute = !$item->isHit() || INF === $beta;
$metadata = $item instanceof ItemInterface ? $item->getMetadata() : array();
if (!$recompute && $item instanceof ItemInterface) { if (!$recompute && $metadata) {
$metadata = $item->getMetadata();
$expiry = $metadata[ItemInterface::METADATA_EXPIRY] ?? false; $expiry = $metadata[ItemInterface::METADATA_EXPIRY] ?? false;
$ctime = $metadata[ItemInterface::METADATA_CTIME] ?? false; $ctime = $metadata[ItemInterface::METADATA_CTIME] ?? false;

View File

@ -20,11 +20,6 @@ use Psr\Cache\InvalidArgumentException;
*/ */
interface TagAwareCacheInterface extends CacheInterface interface TagAwareCacheInterface extends CacheInterface
{ {
/**
* {@inheritdoc}
*/
public function get(string $key, callable $callback, float $beta = null);
/** /**
* Invalidates cached items using tags. * Invalidates cached items using tags.
* *