Skip to content

Commit 0d911b9

Browse files
authored
Merge pull request #9322 from derrabus/feature/psr-region-cache
PSR-6 second level cache
2 parents c6d8aec + 5d0fbc4 commit 0d911b9

25 files changed

+304
-408
lines changed

UPGRADE.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Upgrade to 2.11
22

3+
## PSR-6-based second level cache
4+
5+
The second level cache has been reworked to consume a PSR-6 cache. Using a
6+
Doctrine Cache instance is deprecated.
7+
8+
* `DefaultCacheFactory`: The constructor expects a PSR-6 cache item pool as
9+
second argument now.
10+
* `DefaultMultiGetRegion`: This class is deprecated in favor of `DefaultRegion`.
11+
* `DefaultRegion`:
12+
* The constructor expects a PSR-6 cache item pool as second argument now.
13+
* The protected `$cache` property is deprecated.
14+
* The properties `$name` and `$lifetime` as well as the constant
15+
`REGION_KEY_SEPARATOR` and the method `getCacheEntryKey()` are flagged as
16+
`@internal` now. They all will become `private` in 3.0.
17+
* The method `getCache()` is deprecated without replacement.
18+
319
## Deprecated: `Doctrine\ORM\Mapping\Driver\PHPDriver`
420

521
Use `StaticPHPDriver` instead when you want to programmatically configure

docs/en/reference/second-level-cache.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ To enable the second-level-cache, you should provide a cache factory.
172172
173173
<?php
174174
/** @var \Doctrine\ORM\Cache\RegionsConfiguration $cacheConfig */
175-
/** @var \Doctrine\Common\Cache\Cache $cache */
175+
/** @var \Psr\Cache\CacheItemPoolInterface $cache */
176176
/** @var \Doctrine\ORM\Configuration $config */
177177
178178
$factory = new \Doctrine\ORM\Cache\DefaultCacheFactory($cacheConfig, $cache);

lib/Doctrine/ORM/Cache/DefaultCacheFactory.php

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@
44

55
namespace Doctrine\ORM\Cache;
66

7-
use Doctrine\Common\Cache\Cache as CacheAdapter;
8-
use Doctrine\Common\Cache\CacheProvider;
9-
use Doctrine\Common\Cache\MultiGetCache;
7+
use Doctrine\Common\Cache\Cache as LegacyCache;
8+
use Doctrine\Common\Cache\Psr6\CacheAdapter;
9+
use Doctrine\Deprecations\Deprecation;
1010
use Doctrine\ORM\Cache;
1111
use Doctrine\ORM\Cache\Persister\Collection\NonStrictReadWriteCachedCollectionPersister;
1212
use Doctrine\ORM\Cache\Persister\Collection\ReadOnlyCachedCollectionPersister;
1313
use Doctrine\ORM\Cache\Persister\Collection\ReadWriteCachedCollectionPersister;
1414
use Doctrine\ORM\Cache\Persister\Entity\NonStrictReadWriteCachedEntityPersister;
1515
use Doctrine\ORM\Cache\Persister\Entity\ReadOnlyCachedEntityPersister;
1616
use Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister;
17-
use Doctrine\ORM\Cache\Region\DefaultMultiGetRegion;
1817
use Doctrine\ORM\Cache\Region\DefaultRegion;
1918
use Doctrine\ORM\Cache\Region\FileLockRegion;
2019
use Doctrine\ORM\Cache\Region\UpdateTimestampCache;
@@ -24,16 +23,19 @@
2423
use Doctrine\ORM\Persisters\Entity\EntityPersister;
2524
use InvalidArgumentException;
2625
use LogicException;
26+
use Psr\Cache\CacheItemPoolInterface;
27+
use TypeError;
2728

2829
use function assert;
30+
use function get_debug_type;
2931
use function sprintf;
3032

3133
use const DIRECTORY_SEPARATOR;
3234

3335
class DefaultCacheFactory implements CacheFactory
3436
{
35-
/** @var CacheAdapter */
36-
private $cache;
37+
/** @var CacheItemPoolInterface */
38+
private $cacheItemPool;
3739

3840
/** @var RegionsConfiguration */
3941
private $regionsConfig;
@@ -47,9 +49,33 @@ class DefaultCacheFactory implements CacheFactory
4749
/** @var string|null */
4850
private $fileLockRegionDirectory;
4951

50-
public function __construct(RegionsConfiguration $cacheConfig, CacheAdapter $cache)
52+
/**
53+
* @param CacheItemPoolInterface $cacheItemPool
54+
*/
55+
public function __construct(RegionsConfiguration $cacheConfig, $cacheItemPool)
5156
{
52-
$this->cache = $cache;
57+
if ($cacheItemPool instanceof LegacyCache) {
58+
Deprecation::trigger(
59+
'doctrine/orm',
60+
'https://github.com/doctrine/orm/pull/9322',
61+
'Passing an instance of %s to %s is deprecated, pass a %s instead.',
62+
get_debug_type($cacheItemPool),
63+
__METHOD__,
64+
CacheItemPoolInterface::class
65+
);
66+
67+
$this->cacheItemPool = CacheAdapter::wrap($cacheItemPool);
68+
} elseif (! $cacheItemPool instanceof CacheItemPoolInterface) {
69+
throw new TypeError(sprintf(
70+
'%s: Parameter #2 is expected to be an instance of %s, got %s.',
71+
__METHOD__,
72+
CacheItemPoolInterface::class,
73+
get_debug_type($cacheItemPool)
74+
));
75+
} else {
76+
$this->cacheItemPool = $cacheItemPool;
77+
}
78+
5379
$this->regionsConfig = $cacheConfig;
5480
}
5581

@@ -183,13 +209,9 @@ public function getRegion(array $cache)
183209
return $this->regions[$cache['region']];
184210
}
185211

186-
$name = $cache['region'];
187-
$cacheAdapter = $this->createRegionCache($name);
188-
$lifetime = $this->regionsConfig->getLifetime($cache['region']);
189-
190-
$region = $cacheAdapter instanceof MultiGetCache
191-
? new DefaultMultiGetRegion($name, $cacheAdapter, $lifetime)
192-
: new DefaultRegion($name, $cacheAdapter, $lifetime);
212+
$name = $cache['region'];
213+
$lifetime = $this->regionsConfig->getLifetime($cache['region']);
214+
$region = new DefaultRegion($name, $this->cacheItemPool, $lifetime);
193215

194216
if ($cache['usage'] === ClassMetadata::CACHE_USAGE_READ_WRITE) {
195217
if (
@@ -209,25 +231,6 @@ public function getRegion(array $cache)
209231
return $this->regions[$cache['region']] = $region;
210232
}
211233

212-
private function createRegionCache(string $name): CacheAdapter
213-
{
214-
$cacheAdapter = clone $this->cache;
215-
216-
if (! $cacheAdapter instanceof CacheProvider) {
217-
return $cacheAdapter;
218-
}
219-
220-
$namespace = $cacheAdapter->getNamespace();
221-
222-
if ($namespace !== '') {
223-
$namespace .= ':';
224-
}
225-
226-
$cacheAdapter->setNamespace($namespace . $name);
227-
228-
return $cacheAdapter;
229-
}
230-
231234
/**
232235
* {@inheritdoc}
233236
*/
@@ -237,7 +240,7 @@ public function getTimestampRegion()
237240
$name = Cache::DEFAULT_TIMESTAMP_REGION_NAME;
238241
$lifetime = $this->regionsConfig->getLifetime($name);
239242

240-
$this->timestampRegion = new UpdateTimestampCache($name, clone $this->cache, $lifetime);
243+
$this->timestampRegion = new UpdateTimestampCache($name, $this->cacheItemPool, $lifetime);
241244
}
242245

243246
return $this->timestampRegion;
@@ -246,8 +249,8 @@ public function getTimestampRegion()
246249
/**
247250
* {@inheritdoc}
248251
*/
249-
public function createCache(EntityManagerInterface $em)
252+
public function createCache(EntityManagerInterface $entityManager)
250253
{
251-
return new DefaultCache($em);
254+
return new DefaultCache($entityManager);
252255
}
253256
}

lib/Doctrine/ORM/Cache/Region/DefaultMultiGetRegion.php

Lines changed: 2 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,11 @@
44

55
namespace Doctrine\ORM\Cache\Region;
66

7-
use Doctrine\Common\Cache\Cache;
8-
use Doctrine\Common\Cache\MultiGetCache;
9-
use Doctrine\ORM\Cache\CacheEntry;
10-
use Doctrine\ORM\Cache\CollectionCacheEntry;
11-
12-
use function assert;
13-
use function count;
14-
157
/**
168
* A cache region that enables the retrieval of multiple elements with one call
9+
*
10+
* @deprecated Use {@link DefaultRegion} instead.
1711
*/
1812
class DefaultMultiGetRegion extends DefaultRegion
1913
{
20-
/**
21-
* Note that the multiple type is due to doctrine/cache not integrating the MultiGetCache interface
22-
* in its signature due to BC in 1.x
23-
*
24-
* @var MultiGetCache|Cache
25-
*/
26-
protected $cache;
27-
28-
/**
29-
* {@inheritDoc}
30-
*
31-
* @param MultiGetCache $cache
32-
*/
33-
public function __construct($name, MultiGetCache $cache, $lifetime = 0)
34-
{
35-
assert($cache instanceof Cache);
36-
parent::__construct($name, $cache, $lifetime);
37-
}
38-
39-
/**
40-
* {@inheritdoc}
41-
*/
42-
public function getMultiple(CollectionCacheEntry $collection)
43-
{
44-
$keysToRetrieve = [];
45-
46-
foreach ($collection->identifiers as $index => $key) {
47-
$keysToRetrieve[$index] = $this->getCacheEntryKey($key);
48-
}
49-
50-
$items = $this->cache->fetchMultiple($keysToRetrieve);
51-
if (count($items) !== count($keysToRetrieve)) {
52-
return null;
53-
}
54-
55-
$returnableItems = [];
56-
57-
foreach ($keysToRetrieve as $index => $key) {
58-
if (! $items[$key] instanceof CacheEntry) {
59-
return null;
60-
}
61-
62-
$returnableItems[$index] = $items[$key];
63-
}
64-
65-
return $returnableItems;
66-
}
6714
}

0 commit comments

Comments
 (0)