8000 [FrameworkBundle] Wire PhpArrayAdapter with a new cache warmer for an… · symfony/symfony@9768dfe · GitHub
[go: up one dir, main page]

Skip to content

Commit 9768dfe

Browse files
committed
[FrameworkBundle] Wire PhpArrayAdapter with a new cache warmer for annotations
1 parent 1be7424 commit 9768dfe

File tree

8 files changed

+149
-5
lines changed

8 files changed

+149
-5
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
namespace Symfony\Bundle\FrameworkBundle\CacheWarmer;
13+
14+
use Doctrine\Common\Annotations\CachedReader;
15+
use Doctrine\Common\Annotations\Reader;
16+
use Psr\Cache\CacheItemPoolInterface;
17+
use Symfony\Component\Cache\Adapter\AdapterInterface;
18+
use Symfony\Component\Cache\Adapter\ArrayAdapter;
19+
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
20+
use Symfony\Component\Cache\Adapter\ProxyAdapter;
21+
use Symfony\Component\Cache\DoctrineProvider;
22+
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
23+
24+
/**
25+
* Warms up annotation caches for classes found in composer's autoload class map
26+
* and declared in DI bundle extensions using the addAnnotatedClassesToCache method.
27+
*
28+
* @author Titouan Galopin <galopintitouan@gmail.com>
29+
*/
30+
class AnnotationsCacheWarmer implements CacheWarmerInterface
31+
{
32+
private $annotationReader;
33+
private $phpArrayFile;
34+
private $fallbackPool;
35+
36+
/**
37+
* @param Reader $annotationReader
38+
* @param string $phpArrayFile The PHP file where annotations are cached.
39+
* @param CacheItemPoolInterface $fallbackPool The pool where runtime-discovered annotations are cached.
40+
*/
41+
public function __construct(Reader $annotationReader, $phpArrayFile, CacheItemPoolInterface $fallbackPool)
42+
{
43+
$this->annotationReader = $annotationReader;
44+
$this->phpArrayFile = $phpArrayFile;
45+
if (!$fallbackPool instanceof AdapterInterface) {
46+
$fallbackPool = new ProxyAdapter($fallbackPool);
47+
}
48+
$this->fallbackPool = $fallbackPool;
49+
}
50+
51+
/**
52+
* {@inheritdoc}
53+
*/
54+
public function warmUp($cacheDir)
55+
{
56+
$adapter = new PhpArrayAdapter($this->phpArrayFile, $this->fallbackPool);
57+
$annotatedClassPatterns = $cacheDir.'/annotations.map';
58+
59+
if (!is_file($annotatedClassPatterns)) {
60+
$adapter A92E ->warmUp(array());
61+
62+
return;
63+
}
64+
65+
$annotatedClasses = include $annotatedClassPatterns;
66+
67+
$arrayPool = new ArrayAdapter(0, false);
68+
$reader = new CachedReader($this->annotationReader, new DoctrineProvider($arrayPool));
69+
70+
foreach ($annotatedClasses as $class) {
71+
$this->readAllComponents($reader, $class);
72+
}
73+
74+
$values = $arrayPool->getValues();
75+
$adapter->warmUp($values);
76+
77+
foreach ($values as $k => $v) {
78+
$item = $this->fallbackPool->getItem($k);
79+
$this->fallbackPool->saveDeferred($item->set($v));
80+
}
81+
$this->fallbackPool->commit();
82+
}
83+
84+
/**
85+
* {@inheritdoc}
86+
*/
87+
public function isOptional()
88+
{
89+
return true;
90+
}
91+
92+
private function readAllComponents(Reader $reader, $class)
93+
{
94+
$reflectionClass = new \ReflectionClass($class);
95+
$reader->getClassAnnotations($reflectionClass);
96+
97+
foreach ($reflectionClass->getMethods() as $reflectionMethod) {
98+
$reader->getMethodAnnotations($reflectionMethod);
99+
}
100+
101+
foreach ($reflectionClass->getProperties() as $reflectionProperty) {
102+
$reader->getPropertyAnnotations($reflectionProperty);
103+
}
104+
}
105+
}

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ private function addAnnotationsSection(ArrayNodeDefinition $rootNode)
594594
->info('annotation configuration')
595595
->addDefaultsIfNotSet()
596596
->children()
597-
->scalarNode('cache')->defaultValue('file')->end()
597+
->scalarNode('cache')->defaultValue('php_array')->end()
598598
->scalarNode('file_cache_dir')->defaultValue('%kernel.cache_dir%/annotations')->end()
599599
->booleanNode('debug')->defaultValue($this->debug)->end()
600600
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -914,8 +914,17 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde
914914
$loader->load('annotations.xml');
915915

916916
if ('none' !== $config['cache']) {
917-
if ('file' === $config['cache']) {
917+
$cacheService = $config['cache'];
918+
919+
if ('php_array' === $config['cache']) {
920+
$cacheService = 'annotations.cache';
921+
922+
// Enable warmer only if PHP array is used for cache
923+
$definition = $container->findDefinition('annotations.cache_warmer');
924+
$definition->addTag('kernel.cache_warmer');
925+
} elseif ('file' === $config['cache']) {
918926
$cacheDir = $container->getParameterBag()->resolveValue($config['file_cache_dir']);
927+
919928
if (!is_dir($cacheDir) && false === @mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
920929
throw new \RuntimeException(sprintf('Could not create cache directory "%s".', $cacheDir));
921930
}
@@ -924,11 +933,13 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde
924933
->getDefinition('annotations.filesystem_cache')
925934
->replaceArgument(0, $cacheDir)
926935
;
936+
937+
$cacheService = 'annotations.filesystem_cache';
927938
}
928939

929940
$container
930941
->getDefinition('annotations.cached_reader')
931-
->replaceArgument(1, new Reference('file' !== $config['cache'] ? $config['cache'] : 'annotations.filesystem_cache'))
942+
->replaceArgument(1, new Reference($cacheService))
932943
->replaceArgument(2, $config['debug'])
933944
->addAutowiringType(Reader::class)
934945
;

src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@
1919
<argument /><!-- Cache-Directory -->
2020
</service>
2121

22+
<service id="annotations.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\AnnotationsCacheWarmer" public="false">
23+
<argument type="service" id="annotations.reader" />
24+
<argument>%kernel.cache_dir%/annotations.php</argument>
25+
<argument type="service" id="cache.annotations" />
26+
</service>
27+
28+
<service id="annotations.cache" class="Symfony\Component\Cache\DoctrineProvider" public="false">
29+
<argument type="service">
30+
<service class="Symfony\Component\Cache\Adapter\PhpArrayAdapter">
31+
<factory class="Symfony\Component\Cache\Adapter\PhpArrayAdapter" method="create" />
32+
<argument>%kernel.cache_dir%/annotations.php</argument>
33+
<argument type="service" id="cache.annotations" />
34+
</service>
35+
</argument>
36+
</service>
37+
2238
<service id="annotation_reader" alias="annotations.reader" />
2339
</services>
2440
</container>

src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
<tag name="cache.pool" />
2323
</service>
2424

25+
<service id="cache.annotations" parent="cache.system" public="false">
26+
<tag name="cache.pool" />
27+
</service>
28+
2529
<service id="cache.adapter.system" class="Symfony\Component\Cache\Adapter\AdapterInterface" abstract="true">
2630
<factory class="Symfony\Component\Cache\Adapter\AbstractAdapter" method="createSystemCache" />
2731
<tag name="cache.pool" clearer="cache.default_clearer" />

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ protected static function getBundleDefaultConfig()
214214
'cache' => 'validator.mapping.cache.symfony',
215215
),
216216
'annotations' => array(
217-
'cache' => 'file',
217+
'cache' => 'php_array',
218218
'file_cache_dir' => '%kernel.cache_dir%/annotations',
219219
'debug' => true,
220220
),

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"require": {
1919
"php": ">=5.5.9",
2020
"symfony/asset": "~2.8|~3.0",
21-
"symfony/cache": "~3.1",
21+
"symfony/cache": "~3.2",
2222
"symfony/class-loader": "~3.2",
2323
"symfony/dependency-injection": "~3.2",
2424
"symfony/config": "~2.8|~3.0",

src/Symfony/Component/Cache/Adapter/ArrayAdapter.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ public function getItems(array $keys = array())
7979
return $this->generateItems($keys, time());
8080
}
8181

82+
/**
83+
* @return array
84+
*/
85+
public function getValues()
86+
{
87+
return $this->values;
88+
}
89+
8290
/**
8391
* {@inheritdoc}
8492
*/

0 commit comments

Comments
 (0)
0