Skip to content

Commit dcdea86

Browse files
authored
Merge pull request #1908 from bendavies/cache-trait
RFC: Cache trait
2 parents 592af01 + 6361a21 commit dcdea86

File tree

7 files changed

+97
-159
lines changed

7 files changed

+97
-159
lines changed

src/Bridge/Symfony/Routing/CachedRouteNameResolver.php

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
namespace ApiPlatform\Core\Bridge\Symfony\Routing;
1515

16-
use Psr\Cache\CacheException;
16+
use ApiPlatform\Core\Cache\CachedTrait;
1717
use Psr\Cache\CacheItemPoolInterface;
1818

1919
/**
@@ -23,11 +23,11 @@
2323
*/
2424
final class CachedRouteNameResolver implements RouteNameResolverInterface
2525
{
26+
use CachedTrait;
27+
2628
const CACHE_KEY_PREFIX = 'route_name_';
2729

28-
private $cacheItemPool;
2930
private $decorated;
30-
private $localCache = [];
3131

3232
public function __construct(CacheItemPoolInterface $cacheItemPool, RouteNameResolverInterface $decorated)
3333
{
@@ -43,33 +43,8 @@ public function getRouteName(string $resourceClass, $operationType /**, array $c
4343
$context = \func_num_args() > 2 ? func_get_arg(2) : [];
4444
$cacheKey = self::CACHE_KEY_PREFIX.md5(serialize([$resourceClass, $operationType, $context['subresource_resources'] ?? null]));
4545

46-
if (isset($this->localCache[$cacheKey])) {
47-
return $this->localCache[$cacheKey];
48-
}
49-
50-
try {
51-
$cacheItem = $this->cacheItemPool->getItem($cacheKey);
52-
53-
if ($cacheItem->isHit()) {
54-
return $this->localCache[$cacheKey] = $cacheItem->get();
55-
}
56-
} catch (CacheException $e) {
57-
//do nothing
58-
}
59-
60-
$routeName = $this->decorated->getRouteName($resourceClass, $operationType, $context);
61-
62-
if (!isset($cacheItem)) {
63-
return $this->localCache[$cacheKey] = $routeName;
64-
}
65-
66-
try {
67-
$cacheItem->set($routeName);
68-
$this->cacheItemPool->save($cacheItem);
69-
} catch (CacheException $e) {
70-
// do nothing
71-
}
72-
73-
return $this->localCache[$cacheKey] = $routeName;
46+
return $this->getCached($cacheKey, function () use ($resourceClass, $operationType, $context) {
47+
return $this->decorated->getRouteName($resourceClass, $operationType, $context);
48+
});
7449
}
7550
}

src/Cache/CachedTrait.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Core\Cache;
15+
16+
use Psr\Cache\CacheException;
17+
use Psr\Cache\CacheItemPoolInterface;
18+
19+
/**
20+
* @internal
21+
*/
22+
trait CachedTrait
23+
{
24+
/** @var CacheItemPoolInterface */
25+
private $cacheItemPool;
26+
private $localCache = [];
27+
28+
private function getCached(string $cacheKey, callable $getValue)
29+
{
30+
if (array_key_exists($cacheKey, $this->localCache)) {
31+
return $this->localCache[$cacheKey];
32+
}
33+
34+
try {
35+
$cacheItem = $this->cacheItemPool->getItem($cacheKey);
36+
37+
if ($cacheItem->isHit()) {
38+
return $this->localCache[$cacheKey] = $cacheItem->get();
39+
}
40+
} catch (CacheException $e) {
41+
//do nothing
42+
}
43+
44+
$value = $getValue();
45+
46+
if (!isset($cacheItem)) {
47+
return $this->localCache[$cacheKey] = $value;
48+
}
49+
50+
try {
51+
$cacheItem->set($value);
52+
$this->cacheItemPool->save($cacheItem);
53+
} catch (CacheException $e) {
54+
// do nothing
55+
}
56+
57+
return $this->localCache[$cacheKey] = $value;
58+
}
59+
}

src/Metadata/Property/Factory/CachedPropertyMetadataFactory.php

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
namespace ApiPlatform\Core\Metadata\Property\Factory;
1515

16+
use ApiPlatform\Core\Cache\CachedTrait;
1617
use ApiPlatform\Core\Metadata\Property\PropertyMetadata;
17-
use Psr\Cache\CacheException;
1818
use Psr\Cache\CacheItemPoolInterface;
1919

2020
/**
@@ -24,11 +24,11 @@
2424
*/
2525
final class CachedPropertyMetadataFactory implements PropertyMetadataFactoryInterface
2626
{
27+
use CachedTrait;
28+
2729
const CACHE_KEY_PREFIX = 'property_metadata_';
2830

29-
private $cacheItemPool;
3031
private $decorated;
31-
private $localCache = [];
3232

3333
public function __construct(CacheItemPoolInterface $cacheItemPool, PropertyMetadataFactoryInterface $decorated)
3434
{
@@ -41,28 +41,10 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, PropertyMetad
4141
*/
4242
public function create(string $resourceClass, string $property, array $options = []): PropertyMetadata
4343
{
44-
$localCacheKey = serialize([$resourceClass, $property, $options]);
45-
if (isset($this->localCache[$localCacheKey])) {
46-
return $this->localCache[$localCacheKey];
47-
}
48-
49-
$cacheKey = self::CACHE_KEY_PREFIX.md5($localCacheKey);
50-
51-
try {
52-
$cacheItem = $this->cacheItemPool->getItem($cacheKey);
53-
} catch (CacheException $e) {
54-
return $this->localCache[$localCacheKey] = $this->decorated->create($resourceClass, $property, $options);
55-
}
56-
57-
if ($cacheItem->isHit()) {
58-
return $this->localCache[$localCacheKey] = $cacheItem->get();
59-
}
60-
61-
$propertyMetadata = $this->decorated->create($resourceClass, $property, $options);
62-
63-
$cacheItem->set($propertyMetadata);
64-
$this->cacheItemPool->save($cacheItem);
44+
$cacheKey = self::CACHE_KEY_PREFIX.md5(serialize([$resourceClass, $property, $options]));
6545

66-
return $this->localCache[$localCacheKey] = $propertyMetadata;
46+
return $this->getCached($cacheKey, function () use ($resourceClass, $property, $options) {
47+
return $this->decorated->create($resourceClass, $property, $options);
48+
});
6749
}
6850
}

src/Metadata/Property/Factory/CachedPropertyNameCollectionFactory.php

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
namespace ApiPlatform\Core\Metadata\Property\Factory;
1515

16+
use ApiPlatform\Core\Cache\CachedTrait;
1617
use ApiPlatform\Core\Metadata\Property\PropertyNameCollection;
17-
use Psr\Cache\CacheException;
1818
use Psr\Cache\CacheItemPoolInterface;
1919

2020
/**
@@ -24,11 +24,11 @@
2424
*/
2525
final class CachedPropertyNameCollectionFactory implements PropertyNameCollectionFactoryInterface
2626
{
27+
use CachedTrait;
28+
2729
const CACHE_KEY_PREFIX = 'property_name_collection_';
2830

29-
private $cacheItemPool;
3031
private $decorated;
31-
private $localCache = [];
3232

3333
public function __construct(CacheItemPoolInterface $cacheItemPool, PropertyNameCollectionFactoryInterface $decorated)
3434
{
@@ -41,28 +41,10 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, PropertyNameC
4141
*/
4242
public function create(string $resourceClass, array $options = []): PropertyNameCollection
4343
{
44-
$localCacheKey = serialize([$resourceClass, $options]);
45-
if (isset($this->localCache[$localCacheKey])) {
46-
return $this->localCache[$localCacheKey];
47-
}
48-
49-
$cacheKey = self::CACHE_KEY_PREFIX.md5($localCacheKey);
50-
51-
try {
52-
$cacheItem = $this->cacheItemPool->getItem($cacheKey);
53-
} catch (CacheException $e) {
54-
return $this->localCache[$localCacheKey] = $this->decorated->create($resourceClass, $options);
55-
}
56-
57-
if ($cacheItem->isHit()) {
58-
return $this->localCache[$localCacheKey] = $cacheItem->get();
59-
}
60-
61-
$propertyNameCollection = $this->decorated->create($resourceClass, $options);
62-
63-
$cacheItem->set($propertyNameCollection);
64-
$this->cacheItemPool->save($cacheItem);
44+
$cacheKey = self::CACHE_KEY_PREFIX.md5(serialize([$resourceClass, $options]));
6545

66-
return $this->localCache[$localCacheKey] = $propertyNameCollection;
46+
return $this->getCached($cacheKey, function () use ($resourceClass, $options) {
47+
return $this->decorated->create($resourceClass, $options);
48+
});
6749
}
6850
}

src/Metadata/Resource/Factory/CachedResourceMetadataFactory.php

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
namespace ApiPlatform\Core\Metadata\Resource\Factory;
1515

16+
use ApiPlatform\Core\Cache\CachedTrait;
1617
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
17-
use Psr\Cache\CacheException;
1818
use Psr\Cache\CacheItemPoolInterface;
1919

2020
/**
@@ -24,11 +24,11 @@
2424
*/
2525
final class CachedResourceMetadataFactory implements ResourceMetadataFactoryInterface
2626
{
27+
use CachedTrait;
28+
2729
const CACHE_KEY_PREFIX = 'resource_metadata_';
2830

29-
private $cacheItemPool;
3031
private $decorated;
31-
private $localCache = [];
3232

3333
public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceMetadataFactoryInterface $decorated)
3434
{
@@ -41,27 +41,10 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceMetad
4141
*/
4242
public function create(string $resourceClass): ResourceMetadata
4343
{
44-
if (isset($this->localCache[$resourceClass])) {
45-
return $this->localCache[$resourceClass];
46-
}
47-
4844
$cacheKey = self::CACHE_KEY_PREFIX.md5($resourceClass);
4945

50-
try {
51-
$cacheItem = $this->cacheItemPool->getItem($cacheKey);
52-
} catch (CacheException $e) {
53-
return $this->localCache[$resourceClass] = $this->decorated->create($resourceClass);
54-
}
55-
56-
if ($cacheItem->isHit()) {
57-
return $this->localCache[$resourceClass] = $cacheItem->get();
58-
}
59-
60-
$resourceMetadata = $this->decorated->create($resourceClass);
61-
62-
$cacheItem->set($resourceMetadata);
63-
$this->cacheItemPool->save($cacheItem);
64-
65-
return $this->localCache[$resourceClass] = $resourceMetadata;
46+
return $this->getCached($cacheKey, function () use ($resourceClass) {
47+
return $this->decorated->create($resourceClass);
48+
});
6649
}
6750
}

src/Metadata/Resource/Factory/CachedResourceNameCollectionFactory.php

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
namespace ApiPlatform\Core\Metadata\Resource\Factory;
1515

16+
use ApiPlatform\Core\Cache\CachedTrait;
1617
use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection;
17-
use Psr\Cache\CacheException;
1818
use Psr\Cache\CacheItemPoolInterface;
1919

2020
/**
@@ -24,11 +24,11 @@
2424
*/
2525
final class CachedResourceNameCollectionFactory implements ResourceNameCollectionFactoryInterface
2626
{
27+
use CachedTrait;
28+
2729
const CACHE_KEY = 'resource_name_collection';
2830

29-
private $cacheItemPool;
3031
private $decorated;
31-
private $localCache;
3232

3333
public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceNameCollectionFactoryInterface $decorated)
3434
{
@@ -41,25 +41,8 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceNameC
4141
*/
4242
public function create(): ResourceNameCollection
4343
{
44-
if (null !== $this->localCache) {
45-
return $this->localCache;
46-
}
47-
48-
try {
49-
$cacheItem = $this->cacheItemPool->getItem(self::CACHE_KEY);
50-
} catch (CacheException $e) {
51-
return $this->localCache = $this->decorated->create();
52-
}
53-
54-
if ($cacheItem->isHit()) {
55-
return $this->localCache = $cacheItem->get();
56-
}
57-
58-
$resourceNameCollection = $this->decorated->create();
59-
60-
$cacheItem->set($resourceNameCollection);
61-
$this->cacheItemPool->save($cacheItem);
62-
63-
return $this->localCache = $resourceNameCollection;
44+
return $this->getCached(self::CACHE_KEY, function () {
45+
return $this->decorated->create();
46+
});
6447
}
6548
}

0 commit comments

Comments
 (0)