Skip to content

Commit 2f6710c

Browse files
committed
Added option to change strategy for publishing events
1 parent b3337e5 commit 2f6710c

8 files changed

Lines changed: 115 additions & 4 deletions

File tree

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"require-dev": {
2727
"phpunit/phpunit": "~4.0",
2828
"symfony/monolog-bundle": "~2.3",
29-
"satooshi/php-coveralls": "~0.6"
29+
"satooshi/php-coveralls": "~0.6",
30+
"matthiasnoback/symfony-dependency-injection-test": "^0.7"
3031
},
3132
"autoload": {
3233
"psr-4" : { "SimpleBus\\AsynchronousBundle\\" : "src" }

doc/getting_started.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,15 @@ simple_bus_asynchronous:
6868
```
6969

7070
This will log consumed messages to the `asynchronous_command_bus` and `asynchronous_event_bus` channels respectively.
71+
72+
## Choose event strategy
73+
74+
When handling events you have two strategies to choose from. Either you publish *all* events to the message queue or
75+
you only publish the events that have a registered subscriber. If your application is the only one that consuming messages
76+
you should consider using the **predefined** strategy. This will reduce the message overhead on the message queue.
77+
78+
```yaml
79+
simple_bus_asynchronous:
80+
events:
81+
strategy: 'predefined' # default: 'always'
82+
```
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace SimpleBus\AsynchronousBundle\DependencyInjection\Compiler;
4+
5+
use SimpleBus\SymfonyBridge\DependencyInjection\Compiler\CollectServices;
6+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
7+
use Symfony\Component\DependencyInjection\ContainerBuilder;
8+
9+
class CollectAsynchronousEventNames implements CompilerPassInterface
10+
{
11+
use CollectServices;
12+
13+
/**
14+
* Get all asynchronous event subscribers and save the name of the event they are listening to.
15+
*
16+
* @param ContainerBuilder $container
17+
*/
18+
public function process(ContainerBuilder $container)
19+
{
20+
$serviceId = 'simple_bus.asynchronous.publishes_predefined_messages_middleware';
21+
if (!$container->hasDefinition($serviceId)) {
22+
return;
23+
}
24+
25+
$names = array();
26+
$this->collectServiceIds(
27+
$container,
28+
'asynchronous_event_subscriber',
29+
'subscribes_to',
30+
function ($key) use (&$names) {
31+
$names[] = $key;
32+
}
33+
);
34+
35+
$container->getDefinition($serviceId)->replaceArgument(2, array_unique($names));
36+
}
37+
}

src/DependencyInjection/Configuration.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public function getConfigTreeBuilder()
4343
->arrayNode('events')
4444
->canBeEnabled()
4545
->children()
46+
->enumNode('strategy')
47+
->info('What strategy to use to publish messages')
48+
->defaultValue('always')
49+
->values(['always', 'predefined'])
50+
->end()
4651
->scalarNode('publisher_service_id')
4752
->info('Service id of an instance of Publisher')
4853
->isRequired()

src/DependencyInjection/SimpleBusAsynchronousExtension.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,15 @@ private function loadAsynchronousEventBus(array $config, ContainerBuilder $conta
100100
if ($config['logging']['enabled']) {
101101
$loader->load('asynchronous_events_logging.yml');
102102
}
103+
104+
105+
if ($config['strategy'] === 'always') {
106+
$eventMiddleware = 'simple_bus.asynchronous.always_publishes_messages_middleware';
107+
} else {
108+
$eventMiddleware = 'simple_bus.asynchronous.publishes_predefined_messages_middleware';
109+
}
110+
111+
// insert before the middleware that actually notifies a message subscriber of the message
112+
$container->getDefinition($eventMiddleware)->addTag('event_bus_middleware', ['priority' => 0]);
103113
}
104114
}

src/Resources/config/asynchronous_events.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@ services:
1313
public: false
1414
arguments:
1515
- '@simple_bus.asynchronous.event_publisher'
16-
tags:
17-
# insert before the middleware that actually notifies a message subscriber of the message
18-
- { name: event_bus_middleware, priority: 0 }
16+
17+
simple_bus.asynchronous.publishes_predefined_messages_middleware:
18+
class: SimpleBus\Asynchronous\MessageBus\PublishesPredefinedMessages
19+
public: false
20+
arguments:
21+
- '@simple_bus.asynchronous.event_publisher'
22+
- '@simple_bus.event_bus.event_name_resolver'
23+
- []
1924

2025
simple_bus.asynchronous.event_bus.finishes_message_before_handling_next_middleware:
2126
class: SimpleBus\Message\Bus\Middleware\FinishesHandlingMessageBeforeHandlingNext

src/SimpleBusAsynchronousBundle.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace SimpleBus\AsynchronousBundle;
44

5+
use SimpleBus\AsynchronousBundle\DependencyInjection\Compiler\CollectAsynchronousEventNames;
56
use SimpleBus\AsynchronousBundle\DependencyInjection\SimpleBusAsynchronousExtension;
67
use SimpleBus\SymfonyBridge\DependencyInjection\Compiler\ConfigureMiddlewares;
78
use SimpleBus\SymfonyBridge\DependencyInjection\Compiler\RegisterHandlers;
@@ -39,5 +40,7 @@ public function build(ContainerBuilder $container)
3940
'subscribes_to'
4041
)
4142
);
43+
44+
$container->addCompilerPass(new CollectAsynchronousEventNames());
4245
}
4346
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace SimpleBus\AsynchronousBundle\Tests\Unit\DependencyInjection\Compiler;
4+
5+
6+
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase;
7+
use SimpleBus\AsynchronousBundle\DependencyInjection\Compiler\CollectAsynchronousEventNames;
8+
use Symfony\Component\DependencyInjection\ContainerBuilder;
9+
use Symfony\Component\DependencyInjection\Definition;
10+
11+
class CollectAsynchronousEventNamesTest extends AbstractCompilerPassTestCase
12+
{
13+
protected function registerCompilerPass(ContainerBuilder $container)
14+
{
15+
$container->addCompilerPass(new CollectAsynchronousEventNames());
16+
}
17+
18+
/**
19+
* @test
20+
*/
21+
public function if_compiler_pass_collects_event_names()
22+
{
23+
$serviceId = 'simple_bus.asynchronous.publishes_predefined_messages_middleware';
24+
$middleware = new Definition();
25+
$middleware->addArgument('arg0');
26+
$middleware->addArgument('arg1');
27+
$middleware->addArgument([]);
28+
$this->setDefinition($serviceId, $middleware);
29+
30+
$subscriber = new Definition();
31+
$subscriber->addTag('asynchronous_event_subscriber', ['subscribes_to'=>'foo']);
32+
$this->setDefinition('event_subscriber', $subscriber);
33+
34+
$this->compile();
35+
36+
$this->assertContainerBuilderHasServiceDefinitionWithArgument($serviceId, 2, ['foo']);
37+
}
38+
}

0 commit comments

Comments
 (0)