Skip to content

Commit 52da22d

Browse files
committed
chore: add exclude-receivers consume parameters
1 parent 79cd71d commit 52da22d

File tree

2 files changed

+126
-37
lines changed

2 files changed

+126
-37
lines changed

src/Symfony/Component/Messenger/Command/ConsumeMessagesCommand.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ protected function configure(): void
7777
new InputOption('queues', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Limit receivers to only consume from the specified queues'),
7878
new InputOption('no-reset', null, InputOption::VALUE_NONE, 'Do not reset container services after each message'),
7979
new InputOption('all', null, InputOption::VALUE_NONE, 'Consume messages from all receivers'),
80+
new InputOption('exclude-receivers', 'er', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Exclude specific receivers from consumption (can only be used with --all)'),
8081
new InputOption('keepalive', null, InputOption::VALUE_OPTIONAL, 'Whether to use the transport\'s keepalive mechanism if implemented', self::DEFAULT_KEEPALIVE_INTERVAL),
8182
])
8283
->setHelp(<<<'EOF'
@@ -122,6 +123,10 @@ protected function configure(): void
122123
Use the --all option to consume from all receivers:
123124
124125
<info>php %command.full_name% --all</info>
126+
127+
Use the --exclude-receivers option to exclude specific receivers from consumption (can only be used with --all):
128+
129+
<info>php %command.full_name% --all --exclude-receivers=receiver1,receiver2</info>
125130
EOF
126131
)
127132
;
@@ -132,6 +137,11 @@ protected function initialize(InputInterface $input, OutputInterface $output): v
132137
if ($input->hasParameterOption('--keepalive')) {
133138
$this->getApplication()->setAlarmInterval((int) ($input->getOption('keepalive') ?? self::DEFAULT_KEEPALIVE_INTERVAL));
134139
}
140+
141+
// Validate that exclude-receivers is only used with --all
142+
if ($input->getOption('exclude-receivers') && !$input->getOption('all')) {
143+
throw new InvalidOptionException('The --exclude-receivers option can only be used with the --all option.');
144+
}
135145
}
136146

137147
protected function interact(InputInterface $input, OutputInterface $output): void
@@ -169,9 +179,24 @@ protected function interact(InputInterface $input, OutputInterface $output): voi
169179

170180
protected function execute(InputInterface $input, OutputInterface $output): int
171181
{
182+
// Validate that exclude-receivers is only used with --all
183+
if ($input->getOption('exclude-receivers') && !$input->getOption('all')) {
184+
throw new InvalidOptionException('The --exclude-receivers option can only be used with the --all option.');
185+
}
186+
172187
$receivers = [];
173188
$rateLimiters = [];
174189
$receiverNames = $input->getOption('all') ? $this->receiverNames : $input->getArgument('receivers');
190+
191+
// Filter out excluded receivers when using --all
192+
if ($input->getOption('all') && $excludedReceivers = $input->getOption('exclude-receivers')) {
193+
$receiverNames = array_diff($receiverNames, $excludedReceivers);
194+
195+
if (empty($receiverNames)) {
196+
throw new RuntimeException('All receivers have been excluded. Please specify at least one receiver to consume from.');
197+
}
198+
}
199+
175200
foreach ($receiverNames as $receiverName) {
176201
if (!$this->receiverLocator->has($receiverName)) {
177202
$message = \sprintf('The receiver "%s" does not exist.', $receiverName);
@@ -276,6 +301,10 @@ public function complete(CompletionInput $input, CompletionSuggestions $suggesti
276301
if ($input->mustSuggestOptionValuesFor('bus')) {
277302
$suggestions->suggestValues($this->busIds);
278303
}
304+
305+
if ($input->mustSuggestOptionValuesFor('exclude-receivers')) {
306+
$suggestions->suggestValues($this->receiverNames);
307+
}
279308
}
280309

281310
public function getSubscribedSignals(): array
@@ -328,4 +357,4 @@ private function convertToBytes(string $memoryLimit): int
328357

329358
return (int) $max;
330359
}
331-
}
360+
}

src/Symfony/Component/Messenger/Tests/Command/ConsumeMessagesCommandTest.php

Lines changed: 96 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,7 @@ public function testBasicRun()
6161
$command = new ConsumeMessagesCommand(new RoutableMessageBus($busLocator), $receiverLocator, new EventDispatcher());
6262

6363
$application = new Application();
64-
if (method_exists($application, 'addCommand')) {
65-
$application->addCommand($command);
66-
} else {
67-
$application->add($command);
68-
}
64+
$application->add($command);
6965
$tester = new CommandTester($application->get('messenger:consume'));
7066
$tester->execute([
7167
'receivers' => ['dummy-receiver'],
@@ -95,11 +91,7 @@ public function testRunWithBusOption()
9591
$command = new ConsumeMessagesCommand(new RoutableMessageBus($busLocator), $receiverLocator, new EventDispatcher());
9692

9793
$application = new Application();
98-
if (method_exists($application, 'addCommand')) {
99-
$application->addCommand($command);
100-
} else {
101-
$application->add($command);
102-
}
94+
$application->add($command);
10395
$tester = new CommandTester($application->get('messenger:consume'));
10496
$tester->execute([
10597
'receivers' => ['dummy-receiver'],
@@ -142,11 +134,7 @@ public function testRunWithResetServicesOption(bool $shouldReset)
142134
$command = new ConsumeMessagesCommand($bus, $receiverLocator, new EventDispatcher(), null, [], new ResetServicesListener($servicesResetter));
143135

144136
$application = new Application();
145-
if (method_exists($application, 'addCommand')) {
146-
$application->addCommand($command);
147-
} else {
148-
$application->add($command);
149-
}
137+
$application->add($command);
150138
$tester = new CommandTester($application->get('messenger:consume'));
151139
$tester->execute(array_merge([
152140
'receivers' => ['dummy-receiver'],
@@ -170,11 +158,7 @@ public function testRunWithInvalidOption(string $option, string $value, string $
170158
$command = new ConsumeMessagesCommand(new RoutableMessageBus(new Container()), $receiverLocator, new EventDispatcher());
171159

172160
$application = new Application();
173-
if (method_exists($application, 'addCommand')) {
174-
$application->addCommand($command);
175-
} else {
176-
$application->add($command);
177-
}
161+
$application->add($command);
178162
$tester = new CommandTester($application->get('messenger:consume'));
179163

180164
$this->expectException(InvalidOptionException::class);
@@ -212,11 +196,7 @@ public function testRunWithTimeLimit()
212196
$command = new ConsumeMessagesCommand(new RoutableMessageBus($busLocator), $receiverLocator, new EventDispatcher());
213197

214198
$application = new Application();
215-
if (method_exists($application, 'addCommand')) {
216-
$application->addCommand($command);
217-
} else {
218-
$application->add($command);
219-
}
199+
$application->add($command);
220200
$tester = new CommandTester($application->get('messenger:consume'));
221201
$tester->execute([
222202
'receivers' => ['dummy-receiver'],
@@ -255,11 +235,7 @@ public function log(...$args): void
255235
$command = new ConsumeMessagesCommand(new RoutableMessageBus($busLocator), $receiverLocator, new EventDispatcher(), $logger);
256236

257237
$application = new Application();
258-
if (method_exists($application, 'addCommand')) {
259-
$application->addCommand($command);
260-
} else {
261-
$application->add($command);
262-
}
238+
$application->add($command);
263239
$tester = new CommandTester($application->get('messenger:consume'));
264240
$tester->execute([
265241
'receivers' => ['dummy-receiver'],
@@ -300,11 +276,7 @@ public function testRunWithAllOption()
300276
);
301277

302278
$application = new Application();
303-
if (method_exists($application, 'addCommand')) {
304-
$application->addCommand($command);
305-
} else {
306-
$application->add($command);
307-
}
279+
$application->add($command);
308280
$tester = new CommandTester($application->get('messenger:consume'));
309281
$tester->execute([
310282
'--all' => true,
@@ -315,6 +287,92 @@ public function testRunWithAllOption()
315287
$this->assertStringContainsString('[OK] Consuming messages from transports "dummy-receiver1, dummy-receiver2"', $tester->getDisplay());
316288
}
317289

290+
public function testRunWithAllAndExcludeReceiversOption()
291+
{
292+
$envelope1 = new Envelope(new \stdClass(), [new BusNameStamp('dummy-bus')]);
293+
$envelope2 = new Envelope(new \stdClass(), [new BusNameStamp('dummy-bus')]);
294+
$envelope3 = new Envelope(new \stdClass(), [new BusNameStamp('dummy-bus')]);
295+
296+
$receiver1 = $this->createMock(ReceiverInterface::class);
297+
$receiver1->method('get')->willReturn([$envelope1]);
298+
$receiver2 = $this->createMock(ReceiverInterface::class);
299+
$receiver2->method('get')->willReturn([$envelope2]);
300+
$receiver3 = $this->createMock(ReceiverInterface::class);
301+
$receiver3->method('get')->willReturn([$envelope3]);
302+
303+
$receiverLocator = new Container();
304+
$receiverLocator->set('dummy-receiver1', $receiver1);
305+
$receiverLocator->set('dummy-receiver2', $receiver2);
306+
$receiverLocator->set('dummy-receiver3', $receiver3);
307+
308+
$bus = $this->createMock(MessageBusInterface::class);
309+
$bus->expects($this->exactly(2))->method('dispatch');
310+
311+
$busLocator = new Container();
312+
$busLocator->set('dummy-bus', $bus);
313+
314+
$command = new ConsumeMessagesCommand(
315+
new RoutableMessageBus($busLocator),
316+
$receiverLocator, new EventDispatcher(),
317+
receiverNames: ['dummy-receiver1', 'dummy-receiver2', 'dummy-receiver3']
318+
);
319+
320+
$application = new Application();
321+
$application->add($command);
322+
$tester = new CommandTester($application->get('messenger:consume'));
323+
$tester->execute([
324+
'--all' => true,
325+
'--exclude-receivers' => ['dummy-receiver2'],
326+
'--limit' => 2,
327+
]);
328+
329+
$tester->assertCommandIsSuccessful();
330+
$this->assertStringContainsString('[OK] Consuming messages from transports "dummy-receiver1, dummy-receiver3"', $tester->getDisplay());
331+
}
332+
333+
public function testRunWithExcludeReceiversWithoutAllOption()
334+
{
335+
$receiverLocator = new Container();
336+
$receiverLocator->set('dummy-receiver', new \stdClass());
337+
338+
$command = new ConsumeMessagesCommand(new RoutableMessageBus(new Container()), $receiverLocator, new EventDispatcher());
339+
340+
$application = new Application();
341+
$application->add($command);
342+
$tester = new CommandTester($application->get('messenger:consume'));
343+
344+
$this->expectException(InvalidOptionException::class);
345+
$this->expectExceptionMessage('The --exclude-receivers option can only be used with the --all option.');
346+
$tester->execute([
347+
'receivers' => ['dummy-receiver'],
348+
'--exclude-receivers' => ['dummy-receiver'],
349+
]);
350+
}
351+
352+
public function testRunWithAllAndExcludeAllReceivers()
353+
{
354+
$receiverLocator = new Container();
355+
$receiverLocator->set('dummy-receiver1', new \stdClass());
356+
$receiverLocator->set('dummy-receiver2', new \stdClass());
357+
358+
$command = new ConsumeMessagesCommand(
359+
new RoutableMessageBus(new Container()),
360+
$receiverLocator, new EventDispatcher(),
361+
receiverNames: ['dummy-receiver1', 'dummy-receiver2']
362+
);
363+
364+
$application = new Application();
365+
$application->add($command);
366+
$tester = new CommandTester($application->get('messenger:consume'));
367+
368+
$this->expectException(\Symfony\Component\Console\Exception\RuntimeException::class);
369+
$this->expectExceptionMessage('All receivers have been excluded. Please specify at least one receiver to consume from.');
370+
$tester->execute([
371+
'--all' => true,
372+
'--exclude-receivers' => ['dummy-receiver1', 'dummy-receiver2'],
373+
]);
374+
}
375+
318376
/**
319377
* @dataProvider provideCompletionSuggestions
320378
*/
@@ -333,5 +391,7 @@ public static function provideCompletionSuggestions()
333391
yield 'receiver (value)' => [['async'], ['async', 'async_high', 'failed']];
334392
yield 'receiver (no repeat)' => [['async', ''], ['async_high', 'failed']];
335393
yield 'option --bus' => [['--bus', ''], ['messenger.bus.default']];
394+
yield 'option --exclude-receivers' => [['--exclude-receivers', ''], ['async', 'async_high', 'failed']];
395+
yield 'option --exclude-receivers (value)' => [['--exclude-receivers', 'async'], ['async', 'async_high', 'failed']];
336396
}
337-
}
397+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy