Move commands-specifics to a compiler pass in FWB
This commit is contained in:
parent
30de3b8ef2
commit
b5415ead46
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\Messenger\DependencyInjection\MessengerPass;
|
||||
|
||||
/**
|
||||
* @author Samuel Roze <samuel.roze@gmail.com>
|
||||
*/
|
||||
class MessengerCommandsPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('console.command.messenger_consume_messages')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$buses = array();
|
||||
foreach ($container->findTaggedServiceIds('messenger.bus') as $busId => $tags) {
|
||||
$buses[$busId] = new Reference($busId);
|
||||
}
|
||||
|
||||
$container
|
||||
->getDefinition('console.command.messenger_consume_messages')
|
||||
->replaceArgument(3, $this->findReceiverNames($container))
|
||||
;
|
||||
}
|
||||
|
||||
private function findReceiverNames(ContainerBuilder $container)
|
||||
{
|
||||
$receiverNames = array();
|
||||
foreach (MessengerPass::findReceivers($container, 'messenger.receiver') as $name => $reference) {
|
||||
$receiverNames[(string) $reference] = $name;
|
||||
}
|
||||
|
||||
return array_values($receiverNames);
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPrunerP
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\DataCollectorTranslatorPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\MessengerCommandsPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass;
|
||||
@ -119,6 +120,7 @@ class FrameworkBundle extends Bundle
|
||||
$container->addCompilerPass(new TestServiceContainerWeakRefPass(), PassConfig::TYPE_BEFORE_REMOVING, -32);
|
||||
$container->addCompilerPass(new TestServiceContainerRealRefPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||
$this->addCompilerPassIfExists($container, MessengerPass::class);
|
||||
$container->addCompilerPass(new MessengerCommandsPass());
|
||||
|
||||
if ($container->getParameter('kernel.debug')) {
|
||||
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);
|
||||
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\MessengerCommandsPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\Messenger\Command\ConsumeMessagesCommand;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\DummyReceiver;
|
||||
use Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceiver;
|
||||
|
||||
class MessengerCommandsPassTest extends TestCase
|
||||
{
|
||||
public function testItRegistersMultipleReceiversAndSetsTheReceiverNamesOnTheCommand()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('my_bus_name', MessageBusInterface::class)->addTag('messenger.bus')->setArgument(0, array());
|
||||
$container->register('console.command.messenger_consume_messages', ConsumeMessagesCommand::class)->setArguments(array(
|
||||
null,
|
||||
new Reference('messenger.receiver_locator'),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
));
|
||||
|
||||
$container->register(AmqpReceiver::class, AmqpReceiver::class)->addTag('messenger.receiver', array('alias' => 'amqp'));
|
||||
$container->register(DummyReceiver::class, DummyReceiver::class)->addTag('messenger.receiver', array('alias' => 'dummy'));
|
||||
|
||||
(new MessengerCommandsPass())->process($container);
|
||||
|
||||
$this->assertSame(array('amqp', 'dummy'), $container->getDefinition('console.command.messenger_consume_messages')->getArgument(3));
|
||||
}
|
||||
}
|
@ -67,6 +67,7 @@
|
||||
"symfony/asset": "<3.4",
|
||||
"symfony/console": "<3.4",
|
||||
"symfony/form": "<4.1",
|
||||
"symfony/messenger": "<4.1.5",
|
||||
"symfony/property-info": "<3.4",
|
||||
"symfony/serializer": "<4.1",
|
||||
"symfony/stopwatch": "<3.4",
|
||||
|
@ -220,30 +220,7 @@ class MessengerPass implements CompilerPassInterface
|
||||
|
||||
private function registerReceivers(ContainerBuilder $container)
|
||||
{
|
||||
$receiverMapping = array();
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->receiverTag) as $id => $tags) {
|
||||
$receiverClass = $container->findDefinition($id)->getClass();
|
||||
if (!is_subclass_of($receiverClass, ReceiverInterface::class)) {
|
||||
throw new RuntimeException(sprintf('Invalid receiver "%s": class "%s" must implement interface "%s".', $id, $receiverClass, ReceiverInterface::class));
|
||||
}
|
||||
|
||||
$receiverMapping[$id] = new Reference($id);
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if (isset($tag['alias'])) {
|
||||
$receiverMapping[$tag['alias']] = $receiverMapping[$id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($container->hasDefinition('console.command.messenger_consume_messages')) {
|
||||
$receiverNames = array();
|
||||
foreach ($receiverMapping as $name => $reference) {
|
||||
$receiverNames[(string) $reference] = $name;
|
||||
}
|
||||
$container->getDefinition('console.command.messenger_consume_messages')->replaceArgument(3, array_values($receiverNames));
|
||||
}
|
||||
$receiverMapping = self::findReceivers($container, $this->receiverTag);
|
||||
|
||||
$container->getDefinition('messenger.receiver_locator')->replaceArgument(0, $receiverMapping);
|
||||
}
|
||||
@ -312,4 +289,29 @@ class MessengerPass implements CompilerPassInterface
|
||||
|
||||
$container->getDefinition($busId)->replaceArgument(0, $middlewareReferences);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function findReceivers(ContainerBuilder $container, string $receiverTag)
|
||||
{
|
||||
$receiverMapping = array();
|
||||
|
||||
foreach ($container->findTaggedServiceIds($receiverTag) as $id => $tags) {
|
||||
$receiverClass = $container->findDefinition($id)->getClass();
|
||||
if (!is_subclass_of($receiverClass, ReceiverInterface::class)) {
|
||||
throw new RuntimeException(sprintf('Invalid receiver "%s": class "%s" must implement interface "%s".', $id, $receiverClass, ReceiverInterface::class));
|
||||
}
|
||||
|
||||
$receiverMapping[$id] = new Reference($id);
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if (isset($tag['alias'])) {
|
||||
$receiverMapping[$tag['alias']] = $receiverMapping[$id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $receiverMapping;
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,9 @@ use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ServiceLocator;
|
||||
use Symfony\Component\Messenger\Command\ConsumeMessagesCommand;
|
||||
use Symfony\Component\Messenger\Command\DebugCommand;
|
||||
use Symfony\Component\Messenger\DataCollector\MessengerDataCollector;
|
||||
use Symfony\Component\Messenger\DependencyInjection\MessengerPass;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Handler\ChainHandler;
|
||||
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
||||
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
|
||||
@ -35,12 +33,12 @@ use Symfony\Component\Messenger\Tests\Fixtures\DummyCommandHandler;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\DummyQuery;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\DummyQueryHandler;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\DummyReceiver;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\MultipleBusesMessage;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\MultipleBusesMessageHandler;
|
||||
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
|
||||
use Symfony\Component\Messenger\Transport\AmqpExt\AmqpReceiver;
|
||||
use Symfony\Component\Messenger\Transport\AmqpExt\AmqpSender;
|
||||
use Symfony\Component\Messenger\Transport\ReceiverInterface;
|
||||
|
||||
class MessengerPassTest extends TestCase
|
||||
{
|
||||
@ -237,24 +235,6 @@ class MessengerPassTest extends TestCase
|
||||
$this->assertEquals(array(AmqpReceiver::class => new Reference(AmqpReceiver::class)), $container->getDefinition('messenger.receiver_locator')->getArgument(0));
|
||||
}
|
||||
|
||||
public function testItRegistersMultipleReceiversAndSetsTheReceiverNamesOnTheCommand()
|
||||
{
|
||||
$container = $this->getContainerBuilder();
|
||||
$container->register('console.command.messenger_consume_messages', ConsumeMessagesCommand::class)->setArguments(array(
|
||||
new Reference('message_bus'),
|
||||
new Reference('messenger.receiver_locator'),
|
||||
null,
|
||||
null,
|
||||
));
|
||||
|
||||
$container->register(AmqpReceiver::class, AmqpReceiver::class)->addTag('messenger.receiver', array('alias' => 'amqp'));
|
||||
$container->register(DummyReceiver::class, DummyReceiver::class)->addTag('messenger.receiver', array('alias' => 'dummy'));
|
||||
|
||||
(new MessengerPass())->process($container);
|
||||
|
||||
$this->assertSame(array('amqp', 'dummy'), $container->getDefinition('console.command.messenger_consume_messages')->getArgument(3));
|
||||
}
|
||||
|
||||
public function testItRegistersSenders()
|
||||
{
|
||||
$container = $this->getContainerBuilder();
|
||||
@ -587,20 +567,6 @@ class DummyHandler
|
||||
}
|
||||
}
|
||||
|
||||
class DummyReceiver implements ReceiverInterface
|
||||
{
|
||||
public function receive(callable $handler): void
|
||||
{
|
||||
for ($i = 0; $i < 3; ++$i) {
|
||||
$handler(Envelope::wrap(new DummyMessage("Dummy $i")));
|
||||
}
|
||||
}
|
||||
|
||||
public function stop(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class InvalidReceiver
|
||||
{
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Messenger\Tests\Fixtures;
|
||||
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\Transport\ReceiverInterface;
|
||||
|
||||
class DummyReceiver implements ReceiverInterface
|
||||
{
|
||||
public function receive(callable $handler): void
|
||||
{
|
||||
for ($i = 0; $i < 3; ++$i) {
|
||||
$handler(Envelope::wrap(new DummyMessage("Dummy $i")));
|
||||
}
|
||||
}
|
||||
|
||||
public function stop(): void
|
||||
{
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user