Skip to content

Commit

Permalink
[DI] add tags container.preload/.no_preload to declare extra clas…
Browse files Browse the repository at this point in the history
…ses to preload/services to not preload
  • Loading branch information
nicolas-grekas authored and fabpot committed Apr 5, 2020
1 parent 8a2a69f commit fb04711
Show file tree
Hide file tree
Showing 27 changed files with 136 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class UnusedTagsPass implements CompilerPassInterface
'container.env_var_loader',
'container.env_var_processor',
'container.hot_path',
'container.no_preload',
'container.preload',
'container.reversible',
'container.service_locator',
'container.service_locator_context',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,8 @@ public function load(array $configs, ContainerBuilder $container)
$container->registerForAutoconfiguration(CacheClearerInterface::class)
->addTag('kernel.cache_clearer');
$container->registerForAutoconfiguration(CacheWarmerInterface::class)
->addTag('kernel.cache_warmer');
->addTag('kernel.cache_warmer')
->addTag('container.no_preload');
$container->registerForAutoconfiguration(EventSubscriberInterface::class)
->addTag('kernel.event_subscriber');
$container->registerForAutoconfiguration(LocaleAwareInterface::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
</service>

<service id="annotations.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\AnnotationsCacheWarmer">
<tag name="container.no_preload" />
<argument type="service" id="annotations.reader" />
<argument>%kernel.cache_dir%/annotations.php</argument>
<argument>#^Symfony\\(?:Component\\HttpKernel\\|Bundle\\FrameworkBundle\\Controller\\(?!.*Controller$))#</argument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<argument>cache.serializer</argument>
</argument>
<tag name="kernel.cache_warmer" priority="64" />
<tag name="container.no_preload" />
</service>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
<argument type="service" id="logger" on-invalid="null" />
<tag name="kernel.event_subscriber" />
<tag name="monolog.logger" channel="console" />
<tag name="container.no_preload" />
</service>

<service id="console.suggest_missing_package_subscriber" class="Symfony\Bundle\FrameworkBundle\EventListener\SuggestMissingPackageSubscriber">
<tag name="kernel.event_subscriber" />
<tag name="container.no_preload" />
</service>

<service id="console.command.about" class="Symfony\Bundle\FrameworkBundle\Command\AboutCommand">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
<service id="router.cache_warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\RouterCacheWarmer">
<tag name="container.service_subscriber" id="router" />
<tag name="kernel.cache_warmer" />
<tag name="container.no_preload" />
<argument type="service" id="Psr\Container\ContainerInterface" />
</service>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
<argument type="collection" /><!-- Loaders injected by the extension -->
<argument>%serializer.mapping.cache.file%</argument>
<tag name="kernel.cache_warmer" />
<tag name="container.no_preload" />
</service>

<service id="serializer.mapping.cache.symfony" class="Psr\Cache\CacheItemPoolInterface">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
<service id="Symfony\Component\HttpFoundation\UrlHelper" alias="url_helper" />

<service id="cache_warmer" class="Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate" public="true">
<tag name="container.no_preload" />
<argument type="tagged_iterator" tag="kernel.cache_warmer" />
<argument>%kernel.debug%</argument>
<argument>%kernel.cache_dir%/%kernel.container_class%Deprecations.log</argument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
<service id="translation.warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\TranslationsCacheWarmer">
<tag name="container.service_subscriber" id="translator" />
<tag name="kernel.cache_warmer" />
<tag name="container.no_preload" />
<argument type="service" id="Psr\Container\ContainerInterface" />
</service>
</services>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<argument type="service" id="validator.builder" />
<argument>%validator.mapping.cache.file%</argument>
<tag name="kernel.cache_warmer" />
<tag name="container.no_preload" />
</service>

<service id="validator.mapping.cache.adapter" class="Symfony\Component\Cache\Adapter\PhpArrayAdapter">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
<!-- Cache Warmers -->
<service id="security.cache_warmer.expression" class="Symfony\Bundle\SecurityBundle\CacheWarmer\ExpressionCacheWarmer">
<tag name="kernel.cache_warmer" />
<tag name="container.no_preload" />
<argument type="collection" /> <!-- expressions -->
<argument type="service" id="security.expression_language" />
</service>
Expand Down
9 changes: 9 additions & 0 deletions src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
<argument type="service" id="twig.runtime_loader" />
</call>
<configurator service="twig.configurator.environment" method="configure" />
<tag name="container.preload" class="Twig\Cache\FilesystemCache" />
<tag name="container.preload" class="Twig\Extension\CoreExtension" />
<tag name="container.preload" class="Twig\Extension\EscaperExtension" />
<tag name="container.preload" class="Twig\Extension\OptimizerExtension" />
<tag name="container.preload" class="Twig\Extension\StagingExtension" />
<tag name="container.preload" class="Twig\ExtensionSet" />
<tag name="container.preload" class="Twig\Template" />
<tag name="container.preload" class="Twig\TemplateWrapper" />
</service>
<service id="Twig_Environment" alias="twig" />
<service id="Twig\Environment" alias="twig" />
Expand All @@ -37,6 +45,7 @@

<service id="twig.template_cache_warmer" class="Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer">
<tag name="kernel.cache_warmer" />
<tag name="container.no_preload" />
<tag name="container.service_subscriber" id="twig" />
<argument type="service" id="Psr\Container\ContainerInterface" />
<argument type="service" id="twig.template_iterator" />
Expand Down
14 changes: 0 additions & 14 deletions src/Symfony/Bundle/TwigBundle/TwigBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,6 @@
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Twig\Cache\FilesystemCache;
use Twig\Extension\CoreExtension;
use Twig\Extension\EscaperExtension;
use Twig\Extension\OptimizerExtension;
use Twig\Extension\StagingExtension;
use Twig\ExtensionSet;

// Help opcache.preload discover always-needed symbols
class_exists(FilesystemCache::class);
class_exists(CoreExtension::class);
class_exists(EscaperExtension::class);
class_exists(OptimizerExtension::class);
class_exists(StagingExtension::class);
class_exists(ExtensionSet::class);

/**
* Bundle.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ class AddConsoleCommandPass implements CompilerPassInterface
{
private $commandLoaderServiceId;
private $commandTag;
private $noPreloadTag;

public function __construct(string $commandLoaderServiceId = 'console.command_loader', string $commandTag = 'console.command')
public function __construct(string $commandLoaderServiceId = 'console.command_loader', string $commandTag = 'console.command', string $noPreloadTag = 'container.no_preload')
{
$this->commandLoaderServiceId = $commandLoaderServiceId;
$this->commandTag = $commandTag;
$this->noPreloadTag = $noPreloadTag;
}

public function process(ContainerBuilder $container)
Expand All @@ -44,6 +46,7 @@ public function process(ContainerBuilder $container)

foreach ($commandServices as $id => $tags) {
$definition = $container->getDefinition($id);
$definition->addTag($this->noPreloadTag);
$class = $container->getParameterBag()->resolveValue($definition->getClass());

if (isset($tags[0]['command'])) {
Expand Down Expand Up @@ -91,6 +94,7 @@ public function process(ContainerBuilder $container)
$container
->register($this->commandLoaderServiceId, ContainerCommandLoader::class)
->setPublic(true)
->addTag($this->noPreloadTag)
->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]);

$container->setParameter('console.command.ids', $serviceIds);
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/DependencyInjection/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CHANGELOG
* deprecated the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service,
configure them explicitly instead
* added class `Symfony\Component\DependencyInjection\Dumper\Preloader` to help with preloading on PHP 7.4+
* added tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload

5.0.0
-----
Expand Down
27 changes: 19 additions & 8 deletions src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class PhpDumper extends Dumper
private $namespace;
private $asFiles;
private $hotPathTag;
private $preloadTags;
private $inlineFactories;
private $inlineRequires;
private $inlinedRequires = [];
Expand Down Expand Up @@ -143,6 +144,7 @@ public function dump(array $options = [])
'as_files' => false,
'debug' => true,
'hot_path_tag' => 'container.hot_path',
'preload_tags' => ['container.preload', 'container.no_preload'],
'inline_factories_parameter' => 'container.dumper.inline_factories',
'inline_class_loader_parameter' => 'container.dumper.inline_class_loader',
'preload_classes' => [],
Expand All @@ -154,6 +156,7 @@ public function dump(array $options = [])
$this->namespace = $options['namespace'];
$this->asFiles = $options['as_files'];
$this->hotPathTag = $options['hot_path_tag'];
$this->preloadTags = $options['preload_tags'];
$this->inlineFactories = $this->asFiles && $options['inline_factories_parameter'] && (!$this->container->hasParameter($options['inline_factories_parameter']) || $this->container->getParameter($options['inline_factories_parameter']));
$this->inlineRequires = $options['inline_class_loader_parameter'] && ($this->container->hasParameter($options['inline_class_loader_parameter']) ? $this->container->getParameter($options['inline_class_loader_parameter']) : (\PHP_VERSION_ID < 70400 || $options['debug']));
$this->serviceLocatorTag = $options['service_locator_tag'];
Expand Down Expand Up @@ -571,7 +574,7 @@ private function addServiceInclude(string $cId, Definition $definition): string
$lineage = [];
foreach ($this->inlinedDefinitions as $def) {
if (!$def->isDeprecated()) {
foreach ($this->getClasses($def) as $class) {
foreach ($this->getClasses($def, $cId) as $class) {
$this->collectLineage($class, $lineage);
}
}
Expand All @@ -583,7 +586,7 @@ private function addServiceInclude(string $cId, Definition $definition): string
&& $this->container->has($id)
&& $this->isTrivialInstance($def = $this->container->findDefinition($id))
) {
foreach ($this->getClasses($def) as $class) {
foreach ($this->getClasses($def, $cId) as $class) {
$this->collectLineage($class, $lineage);
}
}
Expand Down Expand Up @@ -838,9 +841,9 @@ protected function {$methodName}($lazyInitialization)
if ($definition->isDeprecated()) {
$deprecation = $definition->getDeprecation($id);
$code .= sprintf(" trigger_deprecation(%s, %s, %s);\n\n", $this->export($deprecation['package']), $this->export($deprecation['version']), $this->export($deprecation['message']));
} else {
} elseif (!$definition->hasTag($this->preloadTags[1])) {
foreach ($this->inlinedDefinitions as $def) {
foreach ($this->getClasses($def) as $class) {
foreach ($this->getClasses($def, $id) as $class) {
$this->preload[$class] = $class;
}
}
Expand Down Expand Up @@ -1003,10 +1006,10 @@ private function addServices(array &$services = null): string
foreach ($definitions as $id => $definition) {
if (!$definition->isSynthetic()) {
$services[$id] = $this->addService($id, $definition);
} else {
} elseif (!$definition->hasTag($this->preloadTags[1])) {
$services[$id] = null;

foreach ($this->getClasses($definition) as $class) {
foreach ($this->getClasses($definition, $id) as $class) {
$this->preload[$class] = $class;
}
}
Expand Down Expand Up @@ -1385,7 +1388,7 @@ private function addInlineRequires(): string
$inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]);

foreach ($inlinedDefinitions as $def) {
foreach ($this->getClasses($def) as $class) {
foreach ($this->getClasses($def, $id) as $class) {
$this->collectLineage($class, $lineage);
}
}
Expand Down Expand Up @@ -2112,11 +2115,19 @@ private function getAutoloadFile(): ?string
return null;
}

private function getClasses(Definition $definition): array
private function getClasses(Definition $definition, string $id): array
{
$classes = [];

while ($definition instanceof Definition) {
foreach ($definition->getTag($this->preloadTags[0]) as $tag) {
if (!isset($tag['class'])) {
throw new InvalidArgumentException(sprintf('Missing attribute "class" on tag "%s" for service "%s".', $this->preloadTags[0], $id));
}

$classes[] = trim($tag['class'], '\\');
}

$classes[] = trim($definition->getClass(), '\\');
$factory = $definition->getFactory();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@
->args([new Reference('errored_definition', ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE)])
->public();
$s->set('errored_definition', 'stdClass')->private();
$s->set('preload_sidekick', 'stdClass')
->tag('container.preload', ['class' => 'Some\Sidekick1'])
->tag('container.preload', ['class' => 'Some\Sidekick2'])
->public();

$s->alias('alias_for_foo', 'foo')->private()->public();
$s->alias('alias_for_alias', ref('alias_for_foo'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,9 @@
$container->register('errored_definition', 'stdClass')
->addError('Service "errored_definition" is broken.');

$container->register('preload_sidekick', 'stdClass')
->setPublic(true)
->addTag('container.preload', ['class' => 'Some\Sidekick1'])
->addTag('container.preload', ['class' => 'Some\Sidekick2']);

return $container;
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ digraph sc {
node_tagged_iterator [label="tagged_iterator\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_runtime_error [label="runtime_error\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_errored_definition [label="errored_definition\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_preload_sidekick [label="preload_sidekick\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];
node_foobaz [label="foobaz\n\n", shape=record, fillcolor="#ff9999", style="filled"];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,29 @@ class getNonSharedFooService extends ProjectServiceContainer
}
}

[Container%s/getPreloadSidekickService.php] => <?php

namespace Container%s;

use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
*/
class getPreloadSidekickService extends ProjectServiceContainer
{
/**
* Gets the public 'preload_sidekick' shared service.
*
* @return \stdClass
*/
public static function do($container, $lazyLoad = true)
{
return $container->services['preload_sidekick'] = new \stdClass();
}
}

[Container%s/getRuntimeErrorService.php] => <?php

namespace Container%s;
Expand Down Expand Up @@ -731,6 +754,7 @@ class ProjectServiceContainer extends Container
'method_call1' => 'getMethodCall1Service',
'new_factory_service' => 'getNewFactoryServiceService',
'non_shared_foo' => 'getNonSharedFooService',
'preload_sidekick' => 'getPreloadSidekickService',
'runtime_error' => 'getRuntimeErrorService',
'service_from_static_method' => 'getServiceFromStaticMethodService',
'tagged_iterator' => 'getTaggedIteratorService',
Expand Down Expand Up @@ -873,6 +897,7 @@ require __DIR__.'/Container%s/getThrowingOneService.php';
require __DIR__.'/Container%s/getTaggedIteratorService.php';
require __DIR__.'/Container%s/getServiceFromStaticMethodService.php';
require __DIR__.'/Container%s/getRuntimeErrorService.php';
require __DIR__.'/Container%s/getPreloadSidekickService.php';
require __DIR__.'/Container%s/getNonSharedFooService.php';
require __DIR__.'/Container%s/getNewFactoryServiceService.php';
require __DIR__.'/Container%s/getMethodCall1Service.php';
Expand Down Expand Up @@ -906,6 +931,8 @@ $classes[] = 'Foo';
$classes[] = 'LazyContext';
$classes[] = 'FooBarBaz';
$classes[] = 'FactoryClass';
$classes[] = 'Some\Sidekick1';
$classes[] = 'Some\Sidekick2';
$classes[] = 'Request';
$classes[] = 'Symfony\Component\DependencyInjection\ContainerInterface';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public function __construct()
'lazy_context_ignore_invalid_ref' => 'getLazyContextIgnoreInvalidRefService',
'method_call1' => 'getMethodCall1Service',
'new_factory_service' => 'getNewFactoryServiceService',
'preload_sidekick' => 'getPreloadSidekickService',
'runtime_error' => 'getRuntimeErrorService',
'service_from_static_method' => 'getServiceFromStaticMethodService',
'tagged_iterator' => 'getTaggedIteratorService',
Expand Down Expand Up @@ -359,6 +360,16 @@ protected function getNewFactoryServiceService()
return $instance;
}

/**
* Gets the public 'preload_sidekick' shared service.
*
* @return \stdClass
*/
protected function getPreloadSidekickService()
{
return $this->services['preload_sidekick'] = new \stdClass();
}

/**
* Gets the public 'runtime_error' shared service.
*
Expand Down

0 comments on commit fb04711

Please sign in to comment.