Skip to content

Commit bc8f774

Browse files
[DI] skip preloading dependencies of non-preloaded services
1 parent d364824 commit bc8f774

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

DependencyInjection/RegisterListenersPass.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class RegisterListenersPass implements CompilerPassInterface
3232

3333
private $hotPathEvents = [];
3434
private $hotPathTagName;
35+
private $noPreloadEvents = [];
36+
private $noPreloadTagName;
3537

3638
public function __construct(string $dispatcherService = 'event_dispatcher', string $listenerTag = 'kernel.event_listener', string $subscriberTag = 'kernel.event_subscriber', string $eventAliasesParameter = 'event_dispatcher.event_aliases')
3739
{
@@ -41,14 +43,28 @@ public function __construct(string $dispatcherService = 'event_dispatcher', stri
4143
$this->eventAliasesParameter = $eventAliasesParameter;
4244
}
4345

44-
public function setHotPathEvents(array $hotPathEvents, $tagName = 'container.hot_path')
46+
/**
47+
* @return $this
48+
*/
49+
public function setHotPathEvents(array $hotPathEvents, string $tagName = 'container.hot_path')
4550
{
4651
$this->hotPathEvents = array_flip($hotPathEvents);
4752
$this->hotPathTagName = $tagName;
4853

4954
return $this;
5055
}
5156

57+
/**
58+
* @return $this
59+
*/
60+
public function setNoPreloadEvents(array $noPreloadEvents, string $tagName = 'container.no_preload'): self
61+
{
62+
$this->noPreloadEvents = array_flip($noPreloadEvents);
63+
$this->noPreloadTagName = $tagName;
64+
65+
return $this;
66+
}
67+
5268
public function process(ContainerBuilder $container)
5369
{
5470
if (!$container->hasDefinition($this->dispatcherService) && !$container->hasAlias($this->dispatcherService)) {
@@ -64,6 +80,8 @@ public function process(ContainerBuilder $container)
6480
$globalDispatcherDefinition = $container->findDefinition($this->dispatcherService);
6581

6682
foreach ($container->findTaggedServiceIds($this->listenerTag, true) as $id => $events) {
83+
$noPreload = 0;
84+
6785
foreach ($events as $event) {
6886
$priority = isset($event['priority']) ? $event['priority'] : 0;
6987

@@ -99,8 +117,14 @@ public function process(ContainerBuilder $container)
99117

100118
if (isset($this->hotPathEvents[$event['event']])) {
101119
$container->getDefinition($id)->addTag($this->hotPathTagName);
120+
} elseif (isset($this->noPreloadEvents[$event['event']])) {
121+
++$noPreload;
102122
}
103123
}
124+
125+
if ($noPreload && \count($events) === $noPreload) {
126+
$container->getDefinition($id)->addTag($this->noPreloadTagName);
127+
}
104128
}
105129

106130
$extractingDispatcher = new ExtractingEventDispatcher();
@@ -132,6 +156,7 @@ public function process(ContainerBuilder $container)
132156
$dispatcherDefinitions = [$globalDispatcherDefinition];
133157
}
134158

159+
$noPreload = 0;
135160
ExtractingEventDispatcher::$aliases = $aliases;
136161
ExtractingEventDispatcher::$subscriber = $class;
137162
$extractingDispatcher->addSubscriber($extractingDispatcher);
@@ -143,8 +168,13 @@ public function process(ContainerBuilder $container)
143168

144169
if (isset($this->hotPathEvents[$args[0]])) {
145170
$container->getDefinition($id)->addTag($this->hotPathTagName);
171+
} elseif (isset($this->noPreloadEvents[$args[0]])) {
172+
++$noPreload;
146173
}
147174
}
175+
if ($noPreload && \count($extractingDispatcher->listeners) === $noPreload) {
176+
$container->getDefinition($id)->addTag($this->noPreloadTagName);
177+
}
148178
$extractingDispatcher->listeners = [];
149179
ExtractingEventDispatcher::$aliases = [];
150180
}

Tests/DependencyInjection/RegisterListenersPassTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,27 @@ public function testHotPathEvents()
157157
$this->assertTrue($container->getDefinition('foo')->hasTag('container.hot_path'));
158158
}
159159

160+
public function testNoPreloadEvents()
161+
{
162+
$container = new ContainerBuilder();
163+
164+
$container->register('foo', SubscriberService::class)->addTag('kernel.event_subscriber', []);
165+
$container->register('bar')->addTag('kernel.event_listener', ['event' => 'cold_event']);
166+
$container->register('baz')
167+
->addTag('kernel.event_listener', ['event' => 'event'])
168+
->addTag('kernel.event_listener', ['event' => 'cold_event']);
169+
$container->register('event_dispatcher', 'stdClass');
170+
171+
(new RegisterListenersPass())
172+
->setHotPathEvents(['event'])
173+
->setNoPreloadEvents(['cold_event'])
174+
->process($container);
175+
176+
$this->assertFalse($container->getDefinition('foo')->hasTag('container.no_preload'));
177+
$this->assertTrue($container->getDefinition('bar')->hasTag('container.no_preload'));
178+
$this->assertFalse($container->getDefinition('baz')->hasTag('container.no_preload'));
179+
}
180+
160181
public function testEventSubscriberUnresolvableClassName()
161182
{
162183
$this->expectException('InvalidArgumentException');

0 commit comments

Comments
 (0)