Skip to content

Commit

Permalink
bug #29302 [Contracts][Cache] allow retrieving metadata of cached ite…
Browse files Browse the repository at this point in the history
…ms (nicolas-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

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

| Q             | A
| ------------- | ---
| Branch?       | 4.2
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

We added `ItemInterface::getMetadata()` because getting them in userland is useful to propagate to higher level caches (eg sending tags + remaining ttl to Varnish).
But we forgot to add a way to retrieve them when using the new `CacheInterface::get()`.
This PR fixes it by adding a 4th `&$metadata` to the method.

Commits
-------

302b844 [Contracts][Cache] allow retrieving metadata of cached items
  • Loading branch information
fabpot committed Nov 26, 2018
2 parents 14931b1 + 302b844 commit 6612250
Show file tree
Hide file tree
Showing 10 changed files with 30 additions and 33 deletions.
3 changes: 2 additions & 1 deletion src/Symfony/Component/Cache/Adapter/ArrayAdapter.php
Expand Up @@ -52,9 +52,10 @@ function ($key, $value, $isHit) use ($defaultLifetime) {
/**
* {@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()) {
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Cache/Adapter/ChainAdapter.php
Expand Up @@ -87,7 +87,7 @@ function ($sourceItem, $item) use ($defaultLifetime) {
/**
* {@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;
Expand All @@ -98,9 +98,9 @@ public function get(string $key, callable $callback, float $beta = null)
$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);
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Cache/Adapter/NullAdapter.php
Expand Up @@ -40,7 +40,7 @@ function ($key) {
/**
* {@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)());
}
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php
Expand Up @@ -82,18 +82,18 @@ public static function create($file, CacheItemPoolInterface $fallbackPool)
/**
* {@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();
}
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]];

Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Cache/Adapter/ProxyAdapter.php
Expand Up @@ -91,10 +91,10 @@ function (CacheItemInterface $innerItem, array $item) {
/**
* {@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) {
Expand All @@ -103,7 +103,7 @@ public function get(string $key, callable $callback, float $beta = null)
($this->setInnerItem)($innerItem, (array) $item);

return $value;
}, $beta);
}, $beta, $metadata);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/Cache/Adapter/TraceableAdapter.php
Expand Up @@ -38,7 +38,7 @@ public function __construct(AdapterInterface $pool)
/**
* {@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));
Expand All @@ -53,7 +53,7 @@ public function get(string $key, callable $callback, float $beta = null)

$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);
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/Cache/Traits/ContractsTrait.php
Expand Up @@ -47,7 +47,7 @@ public function setCallbackWrapper(?callable $callbackWrapper): callable
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));
Expand Down Expand Up @@ -85,6 +85,6 @@ function (AdapterInterface $pool, ItemInterface $item, float $startTime) {
} finally {
$this->callbackWrapper = $callbackWrapper;
}
}, $beta);
}, $beta, $metadata);
}
}
17 changes: 9 additions & 8 deletions src/Symfony/Contracts/Cache/CacheInterface.php
Expand Up @@ -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.
Expand Down
10 changes: 5 additions & 5 deletions src/Symfony/Contracts/Cache/CacheTrait.php
Expand Up @@ -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);
}

/**
Expand All @@ -37,7 +37,7 @@ public function delete(string $key): bool
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 {
Expand All @@ -46,9 +46,9 @@ private function doGet(CacheItemPoolInterface $pool, string $key, callable $call

$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;

Expand Down
5 changes: 0 additions & 5 deletions src/Symfony/Contracts/Cache/TagAwareCacheInterface.php
Expand Up @@ -20,11 +20,6 @@
*/
interface TagAwareCacheInterface extends CacheInterface
{
/**
* {@inheritdoc}
*/
public function get(string $key, callable $callback, float $beta = null);

/**
* Invalidates cached items using tags.
*
Expand Down

0 comments on commit 6612250

Please sign in to comment.