[Cache] Fix double fetch in ProxyAdapter
This commit is contained in:
parent
c87c175ad5
commit
040f53d3e6
@ -42,7 +42,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
|
|||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
},
|
},
|
||||||
$this,
|
null,
|
||||||
CacheItem::class
|
CacheItem::class
|
||||||
);
|
);
|
||||||
$this->mergeByLifetime = \Closure::bind(
|
$this->mergeByLifetime = \Closure::bind(
|
||||||
@ -63,7 +63,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
|
|||||||
|
|
||||||
return $byLifetime;
|
return $byLifetime;
|
||||||
},
|
},
|
||||||
$this,
|
null,
|
||||||
CacheItem::class
|
CacheItem::class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface
|
|||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
},
|
},
|
||||||
$this,
|
null,
|
||||||
CacheItem::class
|
CacheItem::class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -132,9 +132,9 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$item = (array) $item;
|
$item = (array) $item;
|
||||||
$key = $item[CacheItem::CAST_PREFIX.'key'];
|
$key = $item["\0*\0key"];
|
||||||
$value = $item[CacheItem::CAST_PREFIX.'value'];
|
$value = $item["\0*\0value"];
|
||||||
$expiry = $item[CacheItem::CAST_PREFIX.'expiry'];
|
$expiry = $item["\0*\0expiry"];
|
||||||
|
|
||||||
if (null !== $expiry && $expiry <= time()) {
|
if (null !== $expiry && $expiry <= time()) {
|
||||||
$this->deleteItem($key);
|
$this->deleteItem($key);
|
||||||
|
@ -62,7 +62,7 @@ class ChainAdapter implements AdapterInterface
|
|||||||
$adapter->save($item);
|
$adapter->save($item);
|
||||||
$item->defaultLifetime = $origDefaultLifetime;
|
$item->defaultLifetime = $origDefaultLifetime;
|
||||||
},
|
},
|
||||||
$this,
|
null,
|
||||||
CacheItem::class
|
CacheItem::class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -24,23 +24,28 @@ class ProxyAdapter implements AdapterInterface
|
|||||||
private $namespace;
|
private $namespace;
|
||||||
private $namespaceLen;
|
private $namespaceLen;
|
||||||
private $createCacheItem;
|
private $createCacheItem;
|
||||||
|
private $poolHash;
|
||||||
|
|
||||||
public function __construct(CacheItemPoolInterface $pool, $namespace = '', $defaultLifetime = 0)
|
public function __construct(CacheItemPoolInterface $pool, $namespace = '', $defaultLifetime = 0)
|
||||||
{
|
{
|
||||||
$this->pool = $pool;
|
$this->pool = $pool;
|
||||||
|
$this->poolHash = $poolHash = spl_object_hash($pool);
|
||||||
$this->namespace = '' === $namespace ? '' : $this->getId($namespace);
|
$this->namespace = '' === $namespace ? '' : $this->getId($namespace);
|
||||||
$this->namespaceLen = strlen($namespace);
|
$this->namespaceLen = strlen($namespace);
|
||||||
$this->createCacheItem = \Closure::bind(
|
$this->createCacheItem = \Closure::bind(
|
||||||
function ($key, $value, $isHit) use ($defaultLifetime) {
|
function ($key, $innerItem) use ($defaultLifetime, $poolHash) {
|
||||||
$item = new CacheItem();
|
$item = new CacheItem();
|
||||||
$item->key = $key;
|
$item->key = $key;
|
||||||
$item->value = $value;
|
$item->value = $innerItem->get();
|
||||||
$item->isHit = $isHit;
|
$item->isHit = $innerItem->isHit();
|
||||||
$item->defaultLifetime = $defaultLifetime;
|
$item->defaultLifetime = $defaultLifetime;
|
||||||
|
$item->innerItem = $innerItem;
|
||||||
|
$item->poolHash = $poolHash;
|
||||||
|
$innerItem->set(null);
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
},
|
},
|
||||||
$this,
|
null,
|
||||||
CacheItem::class
|
CacheItem::class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -53,7 +58,7 @@ class ProxyAdapter implements AdapterInterface
|
|||||||
$f = $this->createCacheItem;
|
$f = $this->createCacheItem;
|
||||||
$item = $this->pool->getItem($this->getId($key));
|
$item = $this->pool->getItem($this->getId($key));
|
||||||
|
|
||||||
return $f($key, $item->get(), $item->isHit());
|
return $f($key, $item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,12 +143,12 @@ class ProxyAdapter implements AdapterInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$item = (array) $item;
|
$item = (array) $item;
|
||||||
$expiry = $item[CacheItem::CAST_PREFIX.'expiry'];
|
$expiry = $item["\0*\0expiry"];
|
||||||
$poolItem = $this->pool->getItem($this->namespace.$item[CacheItem::CAST_PREFIX.'key']);
|
$innerItem = $item["\0*\0poolHash"] === $this->poolHash ? $item["\0*\0innerItem"] : $this->pool->getItem($this->namespace.$item["\0*\0key"]);
|
||||||
$poolItem->set($item[CacheItem::CAST_PREFIX.'value']);
|
$innerItem->set($item["\0*\0value"]);
|
||||||
$poolItem->expiresAt(null !== $expiry ? \DateTime::createFromFormat('U', $expiry) : null);
|
$innerItem->expiresAt(null !== $expiry ? \DateTime::createFromFormat('U', $expiry) : null);
|
||||||
|
|
||||||
return $this->pool->$method($poolItem);
|
return $this->pool->$method($innerItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateItems($items)
|
private function generateItems($items)
|
||||||
@ -155,7 +160,7 @@ class ProxyAdapter implements AdapterInterface
|
|||||||
$key = substr($key, $this->namespaceLen);
|
$key = substr($key, $this->namespaceLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
yield $key => $f($key, $item->get(), $item->isHit());
|
yield $key => $f($key, $item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,16 +20,13 @@ use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
|||||||
*/
|
*/
|
||||||
final class CacheItem implements CacheItemInterface
|
final class CacheItem implements CacheItemInterface
|
||||||
{
|
{
|
||||||
/**
|
protected $key;
|
||||||
* @internal
|
protected $value;
|
||||||
*/
|
protected $isHit;
|
||||||
const CAST_PREFIX = "\0Symfony\Component\Cache\CacheItem\0";
|
protected $expiry;
|
||||||
|
protected $defaultLifetime;
|
||||||
private $key;
|
protected $innerItem;
|
||||||
private $value;
|
protected $poolHash;
|
||||||
private $isHit;
|
|
||||||
private $expiry;
|
|
||||||
private $defaultLifetime;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
@ -12,8 +12,10 @@
|
|||||||
namespace Symfony\Component\Cache\Tests\Adapter;
|
namespace Symfony\Component\Cache\Tests\Adapter;
|
||||||
|
|
||||||
use Cache\IntegrationTests\CachePoolTest;
|
use Cache\IntegrationTests\CachePoolTest;
|
||||||
|
use Psr\Cache\CacheItemInterface;
|
||||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||||
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
use Symfony\Component\Cache\Adapter\ProxyAdapter;
|
||||||
|
use Symfony\Component\Cache\CacheItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group time-sensitive
|
* @group time-sensitive
|
||||||
@ -29,4 +31,41 @@ class ProxyAdapterTest extends CachePoolTest
|
|||||||
{
|
{
|
||||||
return new ProxyAdapter(new ArrayAdapter());
|
return new ProxyAdapter(new ArrayAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Exception
|
||||||
|
* @expectedExceptionMessage OK bar
|
||||||
|
*/
|
||||||
|
public function testProxyfiedItem()
|
||||||
|
{
|
||||||
|
$item = new CacheItem();
|
||||||
|
$pool = new ProxyAdapter(new TestingArrayAdapter($item));
|
||||||
|
|
||||||
|
$proxyItem = $pool->getItem('foo');
|
||||||
|
|
||||||
|
$this->assertFalse($proxyItem === $item);
|
||||||
|
$pool->save($proxyItem->set('bar'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestingArrayAdapter extends ArrayAdapter
|
||||||
|
{
|
||||||
|
private $item;
|
||||||
|
|
||||||
|
public function __construct(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
$this->item = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItem($key)
|
||||||
|
{
|
||||||
|
return $this->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(CacheItemInterface $item)
|
||||||
|
{
|
||||||
|
if ($item === $this->item) {
|
||||||
|
throw new \Exception('OK '.$item->get());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user