Skip to content

Commit 8d38bb2

Browse files
authored
Merge pull request #628 from php-enqueue/multi-client-configuration
[bundle] Multi Client Configuration
2 parents 9bc6693 + 1351930 commit 8d38bb2

File tree

57 files changed

+1431
-796
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1431
-796
lines changed

Diff for: docs/bundle/async_commands.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ $ composer require enqueue/async-command:0.9.x-dev
2121
# config/packages/enqueue_async_commands.yaml
2222

2323
enqueue:
24-
async_commands: true
24+
default:
25+
async_commands: true
2526
```
2627
2728
## Usage

Diff for: docs/bundle/async_events.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ If you already [installed the bundle](quick_tour.md#install), then enable `async
3131
# app/config/config.yml
3232

3333
enqueue:
34-
async_events:
35-
enabled: true
36-
# if you'd like to send send messages onTerminate use spool_producer (it further reduces response time):
37-
# spool_producer: true
34+
default:
35+
async_events:
36+
enabled: true
37+
# if you'd like to send send messages onTerminate use spool_producer (it further reduces response time):
38+
# spool_producer: true
3839
```
3940

4041
## Usage

Diff for: docs/bundle/config_reference.md

+36-38
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,42 @@ You can get this info by running `./bin/console config:dump-reference enqueue` c
1414
```yaml
1515
# Default configuration for extension with alias: "enqueue"
1616
enqueue:
17-
18-
# The transport option could accept a string DSN, an array with DSN key, or null. It accept extra options. To find out what option you can set, look at connection factory constructor docblock.
19-
transport:
20-
21-
# The broker DSN. These schemes are supported: "file", "amqp", "amqps", "db2", "ibm-db2", "mssql", "sqlsrv", "mysql", "mysql2", "pgsql", "postgres", "sqlite", "sqlite3", "null", "gearman", "beanstalk", "kafka", "rdkafka", "redis", "stomp", "sqs", "gps", "mongodb", to use these "file", "amqp", "amqps", "db2", "ibm-db2", "mssql", "sqlsrv", "mysql", "mysql2", "pgsql", "postgres", "sqlite", "sqlite3", "null", "gearman", "beanstalk", "kafka", "rdkafka", "redis", "stomp", "sqs", "gps", "mongodb" you have to install a package.
22-
dsn: ~ # Required
23-
24-
# The connection factory class should implement "Interop\Queue\ConnectionFactory" interface
25-
connection_factory_class: ~
26-
27-
# The factory class should implement "Enqueue\ConnectionFactoryFactoryInterface" interface
28-
factory_service: ~
29-
30-
# The factory service should be a class that implements "Enqueue\ConnectionFactoryFactoryInterface" interface
31-
factory_class: ~
32-
client:
33-
traceable_producer: true
34-
prefix: enqueue
35-
app_name: app
36-
router_topic: default
37-
router_queue: default
38-
router_processor: Enqueue\Client\RouterProcessor
39-
default_processor_queue: default
40-
redelivered_delay_time: 0
41-
consumption:
42-
43-
# the time in milliseconds queue consumer waits for a message (100 ms by default)
44-
receive_timeout: 100
45-
job: false
46-
async_events:
47-
enabled: false
48-
async_commands:
49-
enabled: false
50-
extensions:
51-
doctrine_ping_connection_extension: false
52-
doctrine_clear_identity_map_extension: false
53-
signal_extension: true
54-
reply_extension: true
17+
# Configuration name
18+
default:
19+
# The transport option could accept a string DSN, an array with DSN key, or null. It accept extra options. To find out what option you can set, look at connection factory constructor docblock.
20+
transport:
21+
22+
# The broker DSN. These schemes are supported: "file", "amqp", "amqps", "db2", "ibm-db2", "mssql", "sqlsrv", "mysql", "mysql2", "pgsql", "postgres", "sqlite", "sqlite3", "null", "gearman", "beanstalk", "kafka", "rdkafka", "redis", "stomp", "sqs", "gps", "mongodb", to use these "file", "amqp", "amqps", "db2", "ibm-db2", "mssql", "sqlsrv", "mysql", "mysql2", "pgsql", "postgres", "sqlite", "sqlite3", "null", "gearman", "beanstalk", "kafka", "rdkafka", "redis", "stomp", "sqs", "gps", "mongodb" you have to install a package.
23+
dsn: ~ # Required
24+
25+
# The connection factory class should implement "Interop\Queue\ConnectionFactory" interface
26+
connection_factory_class: ~
27+
28+
# The factory class should implement "Enqueue\ConnectionFactoryFactoryInterface" interface
29+
factory_service: ~
30+
31+
# The factory service should be a class that implements "Enqueue\ConnectionFactoryFactoryInterface" interface
32+
factory_class: ~
33+
client:
34+
traceable_producer: true
35+
prefix: enqueue
36+
app_name: app
37+
router_topic: default
38+
router_queue: default
39+
router_processor: Enqueue\Client\RouterProcessor
40+
default_processor_queue: default
41+
redelivered_delay_time: 0
42+
consumption:
43+
44+
# the time in milliseconds queue consumer waits for a message (100 ms by default)
45+
receive_timeout: 100
46+
async_commands:
47+
enabled: false
48+
extensions:
49+
doctrine_ping_connection_extension: false
50+
doctrine_clear_identity_map_extension: false
51+
signal_extension: true
52+
reply_extension: true
5553
```
5654
5755
[back to index](../index.md)

Diff for: docs/bundle/debugging.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ To enable profiler
2121
# app/config/config_dev.yml
2222

2323
enqueue:
24-
client:
25-
traceable_producer: true
24+
default:
25+
client:
26+
traceable_producer: true
2627
```
2728
2829
Now suppose you have this code in an action:

Diff for: docs/bundle/functional_testing.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ Here's how you can configure it.
2727
# app/config/config_test.yml
2828

2929
enqueue:
30-
transport: 'null:'
31-
client: ~
30+
default:
31+
transport: 'null:'
32+
client: ~
3233
```
3334
3435
## Traceable message producer
@@ -40,8 +41,9 @@ There is a solution for that. You have to enable traceable message producer in t
4041
# app/config/config_test.yml
4142

4243
enqueue:
43-
client:
44-
traceable_producer: true
44+
default:
45+
client:
46+
traceable_producer: true
4547
```
4648
4749
If you did so, you can use its methods `getTraces`, `getTopicTraces` or `clearTraces`. Here's an example:

Diff for: docs/bundle/job_queue.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ class AppKernel extends Kernel
5757
# app/config/config.yml
5858

5959
enqueue:
60-
# plus basic bundle configuration
61-
62-
job: true
60+
default:
61+
# plus basic bundle configuration
62+
63+
job: true
6364

6465
doctrine:
6566
# plus basic bundle configuration

Diff for: docs/bundle/quick_tour.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ First, you have to configure a transport layer and set one to be default.
5757
# app/config/config.yml
5858

5959
enqueue:
60-
transport: "amqp:"
61-
client: ~
60+
default:
61+
transport: "amqp:"
62+
client: ~
6263
```
6364
6465
Once you configured everything you can start producing messages:

Diff for: pkg/async-command/DependencyInjection/AsyncCommandExtension.php

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Enqueue\AsyncCommand\DependencyInjection;
44

5+
use Enqueue\AsyncCommand\RunCommandProcessor;
56
use Symfony\Component\Config\FileLocator;
67
use Symfony\Component\DependencyInjection\ContainerBuilder;
78
use Symfony\Component\DependencyInjection\Extension\Extension;
@@ -16,5 +17,13 @@ public function load(array $configs, ContainerBuilder $container)
1617
{
1718
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
1819
$loader->load('services.yml');
20+
21+
$service = $container->register('enqueue.async_command.run_command_processor', RunCommandProcessor::class)
22+
->addArgument('%kernel.project_dir%')
23+
;
24+
25+
foreach ($configs['clients'] as $client) {
26+
$service->addTag('enqueue.command_subscriber', ['client' => $client]);
27+
}
1928
}
2029
}

Diff for: pkg/enqueue-bundle/DependencyInjection/Configuration.php

+45-72
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
namespace Enqueue\Bundle\DependencyInjection;
44

5+
use Enqueue\AsyncCommand\RunCommandProcessor;
6+
use Enqueue\Monitoring\Symfony\DependencyInjection\MonitoringFactory;
57
use Enqueue\Symfony\Client\DependencyInjection\ClientFactory;
68
use Enqueue\Symfony\DependencyInjection\TransportFactory;
9+
use Enqueue\Symfony\MissingComponentFactory;
710
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
811
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
912
use Symfony\Component\Config\Definition\ConfigurationInterface;
@@ -21,86 +24,56 @@ public function getConfigTreeBuilder(): TreeBuilder
2124
{
2225
$tb = new TreeBuilder();
2326
$rootNode = $tb->root('enqueue');
24-
$rootNode
25-
->beforeNormalization()
26-
->always(function ($value) {
27-
if (empty($value)) {
28-
return [
29-
'transport' => [
30-
'default' => [
31-
'dsn' => 'null:',
32-
],
33-
],
34-
];
35-
}
36-
37-
if (is_string($value)) {
38-
return [
39-
'transport' => [
40-
'default' => [
41-
'dsn' => $value,
42-
],
43-
],
44-
];
45-
}
46-
47-
return $value;
48-
})
49-
;
50-
51-
$transportFactory = new TransportFactory('default');
5227

53-
/** @var ArrayNodeDefinition $transportNode */
54-
$transportNode = $rootNode->children()->arrayNode('transport');
55-
$transportNode
56-
->beforeNormalization()
57-
->always(function ($value) {
58-
if (empty($value)) {
59-
return ['default' => ['dsn' => 'null:']];
60-
}
61-
if (is_string($value)) {
62-
return ['default' => ['dsn' => $value]];
63-
}
64-
65-
if (is_array($value) && array_key_exists('dsn', $value)) {
66-
return ['default' => $value];
67-
}
68-
69-
return $value;
70-
});
71-
$transportPrototypeNode = $transportNode
28+
$rootNode
7229
->requiresAtLeastOneElement()
7330
->useAttributeAsKey('key')
74-
->prototype('array')
31+
->arrayPrototype()
32+
->children()
33+
->append(TransportFactory::getConfiguration())
34+
->append(TransportFactory::getQueueConsumerConfiguration())
35+
->append(ClientFactory::getConfiguration($this->debug))
36+
->append($this->getMonitoringConfiguration())
37+
->append($this->getAsyncCommandsConfiguration())
38+
->arrayNode('extensions')->addDefaultsIfNotSet()->children()
39+
->booleanNode('doctrine_ping_connection_extension')->defaultFalse()->end()
40+
->booleanNode('doctrine_clear_identity_map_extension')->defaultFalse()->end()
41+
->booleanNode('signal_extension')->defaultValue(function_exists('pcntl_signal_dispatch'))->end()
42+
->booleanNode('reply_extension')->defaultTrue()->end()
43+
->end()->end()
44+
->end()
45+
->end()
7546
;
7647

77-
$transportFactory->addTransportConfiguration($transportPrototypeNode);
48+
// $rootNode->children()
49+
// ->booleanNode('job')->defaultFalse()->end()
50+
// ->arrayNode('async_events')
51+
// ->addDefaultsIfNotSet()
52+
// ->canBeEnabled()
53+
// ->end()
54+
// ;
55+
56+
return $tb;
57+
}
7858

79-
$consumptionNode = $rootNode->children()->arrayNode('consumption');
80-
$transportFactory->addQueueConsumerConfiguration($consumptionNode);
59+
private function getMonitoringConfiguration(): ArrayNodeDefinition
60+
{
61+
if (false === class_exists(MonitoringFactory::class)) {
62+
return MissingComponentFactory::getConfiguration('monitoring', ['enqueue/monitoring']);
63+
}
8164

82-
$clientFactory = new ClientFactory('default');
83-
$clientNode = $rootNode->children()->arrayNode('client');
84-
$clientFactory->addClientConfiguration($clientNode, $this->debug);
65+
return MonitoringFactory::getConfiguration();
66+
}
8567

86-
$rootNode->children()
87-
->booleanNode('job')->defaultFalse()->end()
88-
->arrayNode('async_events')
89-
->addDefaultsIfNotSet()
90-
->canBeEnabled()
91-
->end()
92-
->arrayNode('async_commands')
93-
->addDefaultsIfNotSet()
94-
->canBeEnabled()
95-
->end()
96-
->arrayNode('extensions')->addDefaultsIfNotSet()->children()
97-
->booleanNode('doctrine_ping_connection_extension')->defaultFalse()->end()
98-
->booleanNode('doctrine_clear_identity_map_extension')->defaultFalse()->end()
99-
->booleanNode('signal_extension')->defaultValue(function_exists('pcntl_signal_dispatch'))->end()
100-
->booleanNode('reply_extension')->defaultTrue()->end()
101-
->end()->end()
102-
;
68+
private function getAsyncCommandsConfiguration(): ArrayNodeDefinition
69+
{
70+
if (false === class_exists(RunCommandProcessor::class)) {
71+
return MissingComponentFactory::getConfiguration('async_commands', ['enqueue/async-command']);
72+
}
10373

104-
return $tb;
74+
return (new ArrayNodeDefinition('async_commands'))
75+
->addDefaultsIfNotSet()
76+
->canBeEnabled()
77+
;
10578
}
10679
}

0 commit comments

Comments
 (0)