Skip to content

Commit dd82ca8

Browse files
Merge branch '3.4'
* 3.4: [DI] Add "container.hot_path" tag to flag the hot path and inline related services [FrameworkBundle] Fine-tune generated annotations.php cache [HttpFoundation] Prevent PHP from sending Last-Modified on session start Micro optim using explicit root namespaces
2 parents 6781e53 + a3e0e49 commit dd82ca8

36 files changed

+578
-61
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,18 @@
2727
class AnnotationsCacheWarmer extends AbstractPhpFileCacheWarmer
2828
{
2929
private $annotationReader;
30+
private $excludeRegexp;
3031

3132
/**
3233
* @param Reader $annotationReader
3334
* @param string $phpArrayFile The PHP file where annotations are cached
3435
* @param CacheItemPoolInterface $fallbackPool The pool where runtime-discovered annotations are cached
3536
*/
36-
public function __construct(Reader $annotationReader, string $phpArrayFile, CacheItemPoolInterface $fallbackPool)
37+
public function __construct(Reader $annotationReader, string $phpArrayFile, CacheItemPoolInterface $fallbackPool, string $excludeRegexp = null)
3738
{
3839
parent::__construct($phpArrayFile, $fallbackPool);
3940
$this->annotationReader = $annotationReader;
41+
$this->excludeRegexp = $excludeRegexp;
4042
}
4143

4244
/**
@@ -54,6 +56,9 @@ protected function doWarmUp($cacheDir, ArrayAdapter $arrayAdapter)
5456
$reader = new CachedReader($this->annotationReader, new DoctrineProvider($arrayAdapter));
5557

5658
foreach ($annotatedClasses as $class) {
59+
if (null !== $this->excludeRegexp && preg_match($this->excludeRegexp, $class)) {
60+
continue;
61+
}
5762
try {
5863
$this->readAllComponents($reader, $class);
5964
} catch (\ReflectionException $e) {

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class UnusedTagsPass implements CompilerPassInterface
2424
private $whitelist = array(
2525
'cache.pool.clearer',
2626
'console.command',
27+
'container.hot_path',
2728
'container.service_locator',
2829
'container.service_subscriber',
2930
'controller.service_arguments',

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ public function load(array $configs, ContainerBuilder $container)
262262
'**\\Entity\\',
263263

264264
// Added explicitly so that we don't rely on the class map being dumped to make it work
265+
'Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController',
265266
'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller',
266267
));
267268

src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
use Symfony\Component\Form\DependencyInjection\FormPass;
4444
use Symfony\Component\HttpFoundation\Request;
4545
use Symfony\Component\HttpKernel\Bundle\Bundle;
46+
use Symfony\Component\HttpKernel\KernelEvents;
4647
use Symfony\Component\Config\Resource\ClassExistenceResource;
4748
use Symfony\Component\Translation\DependencyInjection\TranslationDumperPass;
4849
use Symfony\Component\Translation\DependencyInjection\TranslationExtractorPass;
@@ -75,14 +76,22 @@ public function build(ContainerBuilder $container)
7576
{
7677
parent::build($container);
7778

79+
$hotPathEvents = array(
80+
KernelEvents::REQUEST,
81+
KernelEvents::CONTROLLER,
82+
KernelEvents::CONTROLLER_ARGUMENTS,
83+
KernelEvents::RESPONSE,
84+
KernelEvents::FINISH_REQUEST,
85+
);
86+
7887
$container->addCompilerPass(new LoggerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);
7988
$container->addCompilerPass(new RegisterControllerArgumentLocatorsPass());
8089
$container->addCompilerPass(new RemoveEmptyControllerArgumentLocatorsPass(), PassConfig::TYPE_BEFORE_REMOVING);
8190
$container->addCompilerPass(new RoutingResolverPass());
8291
$container->addCompilerPass(new ProfilerPass());
8392
// must be registered before removing private services as some might be listeners/subscribers
8493
// but as late as possible to get resolved parameters
85-
$container->addCompilerPass(new RegisterListenersPass(), PassConfig::TYPE_BEFORE_REMOVING);
94+
$container->addCompilerPass((new RegisterListenersPass())->setHotPathEvents($hotPathEvents), PassConfig::TYPE_BEFORE_REMOVING);
8695
$container->addCompilerPass(new TemplatingPass());
8796
$this->addCompilerPassIfExists($container, AddConstraintValidatorsPass::class, PassConfig::TYPE_BEFORE_REMOVING);
8897
$container->addCompilerPass(new AddAnnotationsCachedReaderPass(), PassConfig::TYPE_BEFORE_REMOVING);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<argument type="service" id="annotations.reader" />
3838
<argument>%kernel.cache_dir%/annotations.php</argument>
3939
<argument type="service" id="cache.annotations" />
40+
<argument>#^Symfony\\(?:Component\\HttpKernel\\|Bundle\\FrameworkBundle\\Controller\\(?!AbstractController$|Controller$))#</argument>
4041
</service>
4142

4243
<service id="annotations.cache" class="Symfony\Component\Cache\DoctrineProvider">

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@
77
<services>
88
<defaults public="false" />
99

10-
<service id="event_dispatcher" class="Symfony\Component\EventDispatcher\EventDispatcher" public="true" />
10+
<service id="event_dispatcher" class="Symfony\Component\EventDispatcher\EventDispatcher" public="true">
11+
<tag name="container.hot_path" />
12+
</service>
1113
<service id="Symfony\Component\EventDispatcher\EventDispatcherInterface" alias="event_dispatcher" />
1214

1315
<service id="http_kernel" class="Symfony\Component\HttpKernel\HttpKernel" public="true">
1416
<argument type="service" id="event_dispatcher" />
1517
<argument type="service" id="controller_resolver" />
1618
<argument type="service" id="request_stack" />
1719
<argument type="service" id="argument_resolver" />
20+
<tag name="container.hot_path" />
1821
</service>
1922
<service id="Symfony\Component\HttpKernel\HttpKernelInterface" alias="http_kernel" />
2023

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"symfony/cache": "~3.4|~4.0",
2222
"symfony/dependency-injection": "~3.4|~4.0",
2323
"symfony/config": "~3.4|~4.0",
24-
"symfony/event-dispatcher": "~3.4|~4.0",
24+
"symfony/event-dispatcher": "~3.4-beta4|~4.0-beta4",
2525
"symfony/http-foundation": "~3.4|~4.0",
2626
"symfony/http-kernel": "~3.4|~4.0",
2727
"symfony/polyfill-mbstring": "~1.0",

src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public function __construct()
8888
)),
8989
new DefinitionErrorExceptionPass(),
9090
new CheckExceptionOnInvalidReferenceBehaviorPass(),
91+
new ResolveHotPathPass(),
9192
));
9293
}
9394

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[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+
namespace Symfony\Component\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Definition;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
19+
/**
20+
* Propagate "container.hot_path" tags to referenced services.
21+
*
22+
* @author Nicolas Grekas <[email protected]>
23+
*/
24+
class ResolveHotPathPass extends AbstractRecursivePass
25+
{
26+
private $tagName;
27+
private $resolvedIds = array();
28+
29+
public function __construct($tagName = 'container.hot_path')
30+
{
31+
$this->tagName = $tagName;
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function process(ContainerBuilder $container)
38+
{
39+
try {
40+
parent::process($container);
41+
$container->getDefinition('service_container')->clearTag($this->tagName);
42+
} finally {
43+
$this->resolvedIds = array();
44+
}
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
*/
50+
protected function processValue($value, $isRoot = false)
51+
{
52+
if ($value instanceof ArgumentInterface) {
53+
return $value;
54+
}
55+
if ($value instanceof Definition && $isRoot && (isset($this->resolvedIds[$this->currentId]) || !$value->hasTag($this->tagName))) {
56+
return $value;
57+
}
58+
if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->has($id = (string) $value)) {
59+
$definition = $this->container->findDefinition($id);
60+
if (!$definition->hasTag($this->tagName)) {
61+
$this->resolvedIds[$id] = true;
62+
$definition->addTag($this->tagName);
63+
parent::processValue($definition, false);
64+
}
65+
66+
return $value;
67+
}
68+
69+
return parent::processValue($value, $isRoot);
70+
}
71+
}

0 commit comments

Comments
 (0)