Skip to content

Commit c0556cb

Browse files
dmaicherfabpot
authored andcommitted
[FrameworkBundle] fix ValidatorCacheWarmer: use serializing ArrayAdapter
1 parent 95c03f2 commit c0556cb

File tree

4 files changed

+143
-145
lines changed

4 files changed

+143
-145
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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 Psr\Cache\CacheItemPoolInterface;
15+
use Symfony\Component\Cache\Adapter\AdapterInterface;
16+
use Symfony\Component\Cache\Adapter\ArrayAdapter;
17+
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
18+
use Symfony\Component\Cache\Adapter\ProxyAdapter;
19+
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
20+
21+
/**
22+
* @internal
23+
*/
24+
abstract class AbstractPhpFileCacheWarmer implements CacheWarmerInterface
25+
{
26+
private $phpArrayFile;
27+
private $fallbackPool;
28+
29+
/**
30+
* @param string $phpArrayFile The PHP file where metadata are cached
31+
* @param CacheItemPoolInterface $fallbackPool The pool where runtime-discovered metadata are cached
32+
*/
33+
public function __construct($phpArrayFile, CacheItemPoolInterface $fallbackPool)
34+
{
35+
$this->phpArrayFile = $phpArrayFile;
36+
if (!$fallbackPool instanceof AdapterInterface) {
37+
$fallbackPool = new ProxyAdapter($fallbackPool);
38+
}
39+
$this->fallbackPool = $fallbackPool;
40+
}
41+
42+
/**
43+
* {@inheritdoc}
44+
*/
45+
public function isOptional()
46+
{
47+
return true;
48+
}
49+
50+
/**
51+
* {@inheritdoc}
52+
*/
53+
public function warmUp($cacheDir)
54+
{
55+
$arrayAdapter = new ArrayAdapter();
56+
57+
spl_autoload_register(array(PhpArrayAdapter::class, 'throwOnRequiredClass'));
58+
try {
59+
if (!$this->doWarmUp($cacheDir, $arrayAdapter)) {
60+
return;
61+
}
62+
} finally {
63+
spl_autoload_unregister(array(PhpArrayAdapter::class, 'throwOnRequiredClass'));
64+
}
65+
66+
// the ArrayAdapter stores the values serialized
67+
// to avoid mutation of the data after it was written to the cache
68+
// so here we un-serialize the values first
69+
$values = array_map(function ($val) { return null !== $val ? unserialize($val) : null; }, $arrayAdapter->getValues());
70+
71+
$this->warmUpPhpArrayAdapter(new PhpArrayAdapter($this->phpArrayFile, $this->fallbackPool), $values);
72+
73+
foreach ($values as $k => $v) {
74+
$item = $this->fallbackPool->getItem($k);
75+
$this->fallbackPool->saveDeferred($item->set($v));
76+
}
77+
$this->fallbackPool->commit();
78+
}
79+
80+
protected function warmUpPhpArrayAdapter(PhpArrayAdapter $phpArrayAdapter, array $values)
81+
{
82+
$phpArrayAdapter->warmUp($values);
83+
}
84+
85+
/**
86+
* @param string $cacheDir
87+
* @param ArrayAdapter $arrayAdapter
88+
*
89+
* @return bool false if there is nothing to warm-up
90+
*/
91+
abstract protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter);
92+
}

src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php

Lines changed: 20 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,18 @@
1515
use Doctrine\Common\Annotations\CachedReader;
1616
use Doctrine\Common\Annotations\Reader;
1717
use Psr\Cache\CacheItemPoolInterface;
18-
use Symfony\Component\Cache\Adapter\AdapterInterface;
1918
use Symfony\Component\Cache\Adapter\ArrayAdapter;
20-
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
21-
use Symfony\Component\Cache\Adapter\ProxyAdapter;
2219
use Symfony\Component\Cache\DoctrineProvider;
23-
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
2420

2521
/**
2622
* Warms up annotation caches for classes found in composer's autoload class map
2723
* and declared in DI bundle extensions using the addAnnotatedClassesToCache method.
2824
*
2925
* @author Titouan Galopin <galopintitouan@gmail.com>
3026
*/
31-
class AnnotationsCacheWarmer implements CacheWarmerInterface
27+
class AnnotationsCacheWarmer extends AbstractPhpFileCacheWarmer
3228
{
3329
private $annotationReader;
34-
private $phpArrayFile;
35-
private $fallbackPool;
3630

3731
/**
3832
* @param Reader $annotationReader
@@ -41,70 +35,41 @@ class AnnotationsCacheWarmer implements CacheWarmerInterface
4135
*/
4236
public function __construct(Reader $annotationReader, $phpArrayFile, CacheItemPoolInterface $fallbackPool)
4337
{
38+
parent::__construct($phpArrayFile, $fallbackPool);
4439
$this->annotationReader = $annotationReader;
45-
$this->phpArrayFile = $phpArrayFile;
46-
if (!$fallbackPool instanceof AdapterInterface) {
47-
$fallbackPool = new ProxyAdapter($fallbackPool);
48-
}
49-
$this->fallbackPool = $fallbackPool;
5040
}
5141

5242
/**
5343
* {@inheritdoc}
5444
*/
55-
public function warmUp($cacheDir)
45+
protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter)
5646
{
57-
$adapter = new PhpArrayAdapter($this->phpArrayFile, $this->fallbackPool);
5847
$annotatedClassPatterns = $cacheDir.'/annotations.map';
5948

6049
if (!is_file($annotatedClassPatterns)) {
61-
$adapter->warmUp(array());
62-
63-
return;
50+
return true;
6451
}
6552

6653
$annotatedClasses = include $annotatedClassPatterns;
67-
68-
$arrayPool = new ArrayAdapter(0, false);
69-
$reader = new CachedReader($this->annotationReader, new DoctrineProvider($arrayPool));
70-
71-
spl_autoload_register(array($adapter, 'throwOnRequiredClass'));
72-
try {
73-
foreach ($annotatedClasses as $class) {
74-
try {
75-
$this->readAllComponents($reader, $class);
76-
} catch (\ReflectionException $e) {
77-
// ignore failing reflection
78-
} catch (AnnotationException $e) {
79-
/*
80-
* Ignore any AnnotationException to not break the cache warming process if an Annotation is badly
81-
* configured or could not be found / read / etc.
82-
*
83-
* In particular cases, an Annotation in your code can be used and defined only for a specific
84-
* environment but is always added to the annotations.map file by some Symfony default behaviors,
85-
* and you always end up with a not found Annotation.
86-
*/
87-
}
54+
$reader = new CachedReader($this->annotationReader, new DoctrineProvider($arrayAdapter));
55+
56+
foreach ($annotatedClasses as $class) {
57+
try {
58+
$this->readAllComponents($reader, $class);
59+
} catch (\ReflectionException $e) {
60+
// ignore failing reflection
61+
} catch (AnnotationException $e) {
62+
/*
63+
* Ignore any AnnotationException to not break the cache warming process if an Annotation is badly
64+
* configured or could not be found / read / etc.
65+
*
66+
* In particular cases, an Annotation in your code can be used and defined only for a specific
67+
* environment but is always added to the annotations.map file by some Symfony default behaviors,
68+
* and you always end up with a not found Annotation.
69+
*/
8870
}
89-
} finally {
90-
spl_autoload_unregister(array($adapter, 'throwOnRequiredClass'));
91-
}
92-
93-
$values = $arrayPool->getValues();
94-
$adapter->warmUp($values);
95-
96-
foreach ($values as $k => $v) {
97-
$item = $this->fallbackPool->getItem($k);
98-
$this->fallbackPool->saveDeferred($item->set($v));
9971
}
100-
$this->fallbackPool->commit();
101-
}
10272

103-
/**
104-
* {@inheritdoc}
105-
*/
106-
public function isOptional()
107-
{
10873
return true;
10974
}
11075

src/Symfony/Bundle/FrameworkBundle/CacheWarmer/SerializerCacheWarmer.php

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

1414
use Doctrine\Common\Annotations\AnnotationException;
1515
use Psr\Cache\CacheItemPoolInterface;
16-
use Symfony\Component\Cache\Adapter\AdapterInterface;
1716
use Symfony\Component\Cache\Adapter\ArrayAdapter;
18-
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
19-
use Symfony\Component\Cache\Adapter\ProxyAdapter;
20-
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
2117
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
2218
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
2319
use Symfony\Component\Serializer\Mapping\Loader\LoaderChain;
@@ -30,11 +26,9 @@
3026
*
3127
* @author Titouan Galopin <galopintitouan@gmail.com>
3228
*/
33-
class SerializerCacheWarmer implements CacheWarmerInterface
29+
class SerializerCacheWarmer extends AbstractPhpFileCacheWarmer
3430
{
3531
private $loaders;
36-
private $phpArrayFile;
37-
private $fallbackPool;
3832

3933
/**
4034
* @param LoaderInterface[] $loaders The serializer metadata loaders
@@ -43,60 +37,33 @@ class SerializerCacheWarmer implements CacheWarmerInterface
4337
*/
4438
public function __construct(array $loaders, $phpArrayFile, CacheItemPoolInterface $fallbackPool)
4539
{
40+
parent::__construct($phpArrayFile, $fallbackPool);
4641
$this->loaders = $loaders;
47-
$this->phpArrayFile = $phpArrayFile;
48-
if (!$fallbackPool instanceof AdapterInterface) {
49-
$fallbackPool = new ProxyAdapter($fallbackPool);
50-
}
51-
$this->fallbackPool = $fallbackPool;
5242
}
5343

5444
/**
5545
* {@inheritdoc}
5646
*/
57-
public function warmUp($cacheDir)
47+
protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter)
5848
{
5949
if (!class_exists(CacheClassMetadataFactory::class) || !method_exists(XmlFileLoader::class, 'getMappedClasses') || !method_exists(YamlFileLoader::class, 'getMappedClasses')) {
60-
return;
50+
return false;
6151
}
6252

63-
$adapter = new PhpArrayAdapter($this->phpArrayFile, $this->fallbackPool);
64-
$arrayPool = new ArrayAdapter(0, false);
65-
66-
$metadataFactory = new CacheClassMetadataFactory(new ClassMetadataFactory(new LoaderChain($this->loaders)), $arrayPool);
53+
$metadataFactory = new CacheClassMetadataFactory(new ClassMetadataFactory(new LoaderChain($this->loaders)), $arrayAdapter);
6754

68-
spl_autoload_register(array($adapter, 'throwOnRequiredClass'));
69-
try {
70-
foreach ($this->extractSupportedLoaders($this->loaders) as $loader) {
71-
foreach ($loader->getMappedClasses() as $mappedClass) {
72-
try {
73-
$metadataFactory->getMetadataFor($mappedClass);
74-
} catch (\ReflectionException $e) {
75-
// ignore failing reflection
76-
} catch (AnnotationException $e) {
77-
// ignore failing annotations
78-
}
55+
foreach ($this->extractSupportedLoaders($this->loaders) as $loader) {
56+
foreach ($loader->getMappedClasses() as $mappedClass) {
57+
try {
58+
$metadataFactory->getMetadataFor($mappedClass);
59+
} catch (\ReflectionException $e) {
60+
// ignore failing reflection
61+
} catch (AnnotationException $e) {
62+
// ignore failing annotations
7963
}
8064
}
81-
} finally {
82-
spl_autoload_unregister(array($adapter, 'throwOnRequiredClass'));
83-
}
84-
85-
$values = $arrayPool->getValues();
86-
$adapter->warmUp($values);
87-
88-
foreach ($values as $k => $v) {
89-
$item = $this->fallbackPool->getItem($k);
90-
$this->fallbackPool->saveDeferred($item->set($v));
9165
}
92-
$this->fallbackPool->commit();
93-
}
9466

95-
/**
96-
* {@inheritdoc}
97-
*/
98-
public function isOptional()
99-
{
10067
return true;
10168
}
10269

0 commit comments

Comments
 (0)