rascal 16.0.0 → 16.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +15 -0
- package/lib/amqp/Vhost.js +3 -3
- package/lib/amqp/tasks/applyBindings.js +5 -3
- package/lib/amqp/tasks/assertExchanges.js +9 -4
- package/lib/amqp/tasks/assertQueues.js +5 -3
- package/lib/amqp/tasks/checkExchanges.js +5 -3
- package/lib/amqp/tasks/checkQueues.js +5 -3
- package/lib/amqp/tasks/closeChannels.js +18 -0
- package/lib/amqp/tasks/createChannels.js +19 -0
- package/lib/amqp/tasks/deleteExchanges.js +5 -3
- package/lib/amqp/tasks/deleteQueues.js +5 -3
- package/lib/amqp/tasks/index.js +2 -2
- package/lib/amqp/tasks/purgeQueues.js +5 -3
- package/lib/config/baseline.js +1 -0
- package/lib/config/configure.js +1 -0
- package/lib/config/schema.json +4 -0
- package/lib/config/validate.js +1 -1
- package/package.json +1 -1
- package/lib/amqp/tasks/closeChannel.js +0 -12
- package/lib/amqp/tasks/createChannel.js +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 16.1.1
|
|
4
|
+
|
|
5
|
+
- Updated README
|
|
6
|
+
- Removed debug
|
|
7
|
+
|
|
8
|
+
## 16.1.0
|
|
9
|
+
|
|
10
|
+
- Added concurrency option for managing RabbitMQ topology. Rascal will create and use upto this number of channels when asserting/checking/deleting/purging queues, exchanges and bindings.
|
|
11
|
+
|
|
3
12
|
## 16.0.0
|
|
4
13
|
|
|
5
14
|
- Automatically set replyTo message property when a publication references a replyTo queue
|
package/README.md
CHANGED
|
@@ -494,6 +494,20 @@ const components = { agent };
|
|
|
494
494
|
const broker = await Broker.create(config, components);
|
|
495
495
|
```
|
|
496
496
|
|
|
497
|
+
#### concurrency
|
|
498
|
+
|
|
499
|
+
If you have a high number of exchanges, queues and bindings you may wish to initialise Rascal using multiple channels to improve startup time. Do this per vhost by setting the `concurrency` attribute to the number of channels you want to create and use.
|
|
500
|
+
|
|
501
|
+
```json
|
|
502
|
+
{
|
|
503
|
+
"vhosts": {
|
|
504
|
+
"v1": {
|
|
505
|
+
"concurrency": 10
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
497
511
|
#### assert
|
|
498
512
|
|
|
499
513
|
When set to true, Rascal will create the vhost if one doesn't exist using the RabbitMQ management API. This requires the [management plugin](https://www.rabbitmq.com/management.html) to be installed on the broker and for the management user to have necessary permissions.
|
|
@@ -692,6 +706,7 @@ Sometimes you want to publish a message, and have the consumer of the message se
|
|
|
692
706
|
}
|
|
693
707
|
},
|
|
694
708
|
"publications": {
|
|
709
|
+
"exchange": "e1",
|
|
695
710
|
"replyTo": "q1"
|
|
696
711
|
}
|
|
697
712
|
}
|
package/lib/amqp/Vhost.js
CHANGED
|
@@ -26,10 +26,10 @@ function Vhost(vhostConfig, components) {
|
|
|
26
26
|
let confirmChannelPool;
|
|
27
27
|
const channelCreator = async.queue(createChannel, 1);
|
|
28
28
|
|
|
29
|
-
const init = async.compose(tasks.
|
|
29
|
+
const init = async.compose(tasks.closeChannels, tasks.applyBindings, tasks.purgeQueues, tasks.checkQueues, tasks.assertQueues, tasks.checkExchanges, tasks.assertExchanges, tasks.createChannels, tasks.createConnection, tasks.checkVhost, tasks.assertVhost);
|
|
30
30
|
const connect = async.compose(tasks.createConnection);
|
|
31
|
-
const purge = async.compose(tasks.closeConnection, tasks.
|
|
32
|
-
const nuke = async.compose(tasks.closeConnection, tasks.
|
|
31
|
+
const purge = async.compose(tasks.closeConnection, tasks.closeChannels, tasks.purgeQueues, tasks.createChannels, tasks.createConnection);
|
|
32
|
+
const nuke = async.compose(tasks.closeConnection, tasks.closeChannels, tasks.deleteQueues, tasks.deleteExchanges, tasks.createChannels, tasks.createConnection);
|
|
33
33
|
let timer = backoff({});
|
|
34
34
|
let paused = true;
|
|
35
35
|
let shuttingDown = false;
|
|
@@ -9,10 +9,12 @@ module.exports = _.curry((config, ctx, next) => {
|
|
|
9
9
|
exchange: bindExchange,
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
async.
|
|
12
|
+
async.eachOfLimit(
|
|
13
13
|
_.values(config.bindings),
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
config.concurrency,
|
|
15
|
+
(binding, index, cb) => {
|
|
16
|
+
const channel = ctx.channels[index % config.concurrency];
|
|
17
|
+
bind[binding.destinationType](config, channel, binding, cb);
|
|
16
18
|
},
|
|
17
19
|
(err) => {
|
|
18
20
|
next(err, config, ctx);
|
|
@@ -3,10 +3,12 @@ const _ = require('lodash');
|
|
|
3
3
|
const async = require('async');
|
|
4
4
|
|
|
5
5
|
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
-
async.
|
|
6
|
+
async.eachOfLimit(
|
|
7
7
|
_.keys(config.exchanges),
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
config.concurrency,
|
|
9
|
+
(name, index, cb) => {
|
|
10
|
+
const channel = ctx.channels[index % config.concurrency];
|
|
11
|
+
assertExchange(channel, config.exchanges[name], cb);
|
|
10
12
|
},
|
|
11
13
|
(err) => {
|
|
12
14
|
next(err, config, ctx);
|
|
@@ -18,5 +20,8 @@ function assertExchange(channel, config, next) {
|
|
|
18
20
|
if (!config.assert) return next();
|
|
19
21
|
if (config.fullyQualifiedName === '') return next();
|
|
20
22
|
debug('Asserting exchange: %s', config.fullyQualifiedName);
|
|
21
|
-
channel.assertExchange(config.fullyQualifiedName, config.type, config.options,
|
|
23
|
+
channel.assertExchange(config.fullyQualifiedName, config.type, config.options, (err) => {
|
|
24
|
+
if (err) return next(err);
|
|
25
|
+
next();
|
|
26
|
+
});
|
|
22
27
|
}
|
|
@@ -3,10 +3,12 @@ const _ = require('lodash');
|
|
|
3
3
|
const async = require('async');
|
|
4
4
|
|
|
5
5
|
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
-
async.
|
|
6
|
+
async.eachOfLimit(
|
|
7
7
|
_.keys(config.queues),
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
config.concurrency,
|
|
9
|
+
(name, index, cb) => {
|
|
10
|
+
const channel = ctx.channels[index % config.concurrency];
|
|
11
|
+
assertQueue(channel, config.queues[name], cb);
|
|
10
12
|
},
|
|
11
13
|
(err) => {
|
|
12
14
|
next(err, config, ctx);
|
|
@@ -3,10 +3,12 @@ const _ = require('lodash');
|
|
|
3
3
|
const async = require('async');
|
|
4
4
|
|
|
5
5
|
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
-
async.
|
|
6
|
+
async.eachOfLimit(
|
|
7
7
|
_.keys(config.exchanges),
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
config.concurrency,
|
|
9
|
+
(name, index, cb) => {
|
|
10
|
+
const channel = ctx.channels[index % config.concurrency];
|
|
11
|
+
checkExchange(channel, config.exchanges[name], cb);
|
|
10
12
|
},
|
|
11
13
|
(err) => {
|
|
12
14
|
next(err, config, ctx);
|
|
@@ -3,10 +3,12 @@ const _ = require('lodash');
|
|
|
3
3
|
const async = require('async');
|
|
4
4
|
|
|
5
5
|
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
-
async.
|
|
6
|
+
async.eachOfLimit(
|
|
7
7
|
_.keys(config.queues),
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
config.concurrency,
|
|
9
|
+
(name, index, cb) => {
|
|
10
|
+
const channel = ctx.channels[index % config.concurrency];
|
|
11
|
+
checkQueue(channel, config.queues[name], cb);
|
|
10
12
|
},
|
|
11
13
|
(err) => {
|
|
12
14
|
next(err, config, ctx);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const debug = require('debug')('rascal:tasks:closeChannels');
|
|
2
|
+
const async = require('async');
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
|
|
5
|
+
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
+
debug('Closing %d channels', ctx.channels.length);
|
|
7
|
+
|
|
8
|
+
async.each(
|
|
9
|
+
ctx.channels,
|
|
10
|
+
(channel, cb) => {
|
|
11
|
+
channel.close(cb);
|
|
12
|
+
},
|
|
13
|
+
(err) => {
|
|
14
|
+
delete ctx.channels;
|
|
15
|
+
return next(err, config, ctx);
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const debug = require('debug')('rascal:tasks:createChannel');
|
|
2
|
+
const async = require('async');
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
|
|
5
|
+
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
+
debug('Creating %d channels', config.concurrency);
|
|
7
|
+
|
|
8
|
+
async.times(
|
|
9
|
+
config.concurrency,
|
|
10
|
+
(index, cb) => {
|
|
11
|
+
ctx.connection.createChannel(cb);
|
|
12
|
+
},
|
|
13
|
+
(err, channels) => {
|
|
14
|
+
if (err) return next(err, config, ctx);
|
|
15
|
+
ctx.channels = channels;
|
|
16
|
+
next(null, config, ctx);
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
});
|
|
@@ -3,10 +3,12 @@ const _ = require('lodash');
|
|
|
3
3
|
const async = require('async');
|
|
4
4
|
|
|
5
5
|
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
-
async.
|
|
6
|
+
async.eachOfLimit(
|
|
7
7
|
_.keys(config.exchanges),
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
config.concurrency,
|
|
9
|
+
(name, index, cb) => {
|
|
10
|
+
const channel = ctx.channels[index % config.concurrency];
|
|
11
|
+
deleteExchange(channel, config.exchanges[name], cb);
|
|
10
12
|
},
|
|
11
13
|
(err) => {
|
|
12
14
|
next(err, config, ctx);
|
|
@@ -3,10 +3,12 @@ const _ = require('lodash');
|
|
|
3
3
|
const async = require('async');
|
|
4
4
|
|
|
5
5
|
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
-
async.
|
|
6
|
+
async.eachOfLimit(
|
|
7
7
|
_.keys(config.queues),
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
config.concurrency,
|
|
9
|
+
(name, index, cb) => {
|
|
10
|
+
const channel = ctx.channels[index % config.concurrency];
|
|
11
|
+
deleteQueue(channel, config.queues[name], cb);
|
|
10
12
|
},
|
|
11
13
|
(err) => {
|
|
12
14
|
next(err, config, ctx);
|
package/lib/amqp/tasks/index.js
CHANGED
|
@@ -6,9 +6,9 @@ exports.bounceVhost = require('./bounceVhost');
|
|
|
6
6
|
exports.checkExchanges = require('./checkExchanges');
|
|
7
7
|
exports.checkQueues = require('./checkQueues');
|
|
8
8
|
exports.checkVhost = require('./checkVhost');
|
|
9
|
-
exports.
|
|
9
|
+
exports.closeChannels = require('./closeChannels');
|
|
10
10
|
exports.closeConnection = require('./closeConnection');
|
|
11
|
-
exports.
|
|
11
|
+
exports.createChannels = require('./createChannels');
|
|
12
12
|
exports.createConnection = require('./createConnection');
|
|
13
13
|
exports.deleteExchanges = require('./deleteExchanges');
|
|
14
14
|
exports.deleteQueues = require('./deleteQueues');
|
|
@@ -3,10 +3,12 @@ const _ = require('lodash');
|
|
|
3
3
|
const async = require('async');
|
|
4
4
|
|
|
5
5
|
module.exports = _.curry((config, ctx, next) => {
|
|
6
|
-
async.
|
|
6
|
+
async.eachOfLimit(
|
|
7
7
|
_.keys(config.queues),
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
config.concurrency,
|
|
9
|
+
(name, index, cb) => {
|
|
10
|
+
const channel = ctx.channels[index % config.concurrency];
|
|
11
|
+
purgeQueue(channel, config.queues[name], ctx, cb);
|
|
10
12
|
},
|
|
11
13
|
(err) => {
|
|
12
14
|
next(err, config, ctx);
|
package/lib/config/baseline.js
CHANGED
package/lib/config/configure.js
CHANGED
|
@@ -43,6 +43,7 @@ module.exports = _.curry((rascalConfig, next) => {
|
|
|
43
43
|
{
|
|
44
44
|
name,
|
|
45
45
|
namespace: rascalConfig.defaults.vhosts.namespace,
|
|
46
|
+
concurrency: rascalConfig.defaults.vhosts.concurrency,
|
|
46
47
|
connectionStrategy: rascalConfig.defaults.vhosts.connectionStrategy,
|
|
47
48
|
publicationChannelPools: rascalConfig.defaults.vhosts.publicationChannelPools,
|
|
48
49
|
},
|
package/lib/config/schema.json
CHANGED
package/lib/config/validate.js
CHANGED
|
@@ -20,7 +20,7 @@ module.exports = _.curry((config, next) => {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function validateVhost(vhost, vhostName) {
|
|
23
|
-
validateAttributes('Vhost', vhost, vhostName, ['defaults', 'namespace', 'name', 'publicationChannelPools', 'connection', 'connections', 'connectionStrategy', 'exchanges', 'queues', 'bindings', 'check', 'assert']);
|
|
23
|
+
validateAttributes('Vhost', vhost, vhostName, ['defaults', 'namespace', 'name', 'concurrency', 'publicationChannelPools', 'connection', 'connections', 'connectionStrategy', 'exchanges', 'queues', 'bindings', 'check', 'assert']);
|
|
24
24
|
validateConnectionStrategy(vhost.connectionStrategy, vhostName);
|
|
25
25
|
validateConnectionAttributes(vhost.connection, vhostName, ['slashes', 'protocol', 'hostname', 'user', 'password', 'port', 'vhost', 'options', 'retry', 'auth', 'pathname', 'query', 'url', 'loggableUrl', 'management']);
|
|
26
26
|
validateManagementConnectionAttributes(_.get(vhost), 'connection.management', vhostName, ['slashes', 'protocol', 'hostname', 'user', 'password', 'port', 'vhost', 'options', 'auth', 'pathname', 'query', 'url', 'loggableUrl']);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rascal",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.1.1",
|
|
4
4
|
"description": "A config driven wrapper for amqplib supporting multi-host connections, automatic error recovery, redelivery flood protection, transparent encryption / decryption, channel pooling and publication timeouts",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const debug = require('debug')('rascal:tasks:closeChannel');
|
|
2
|
-
const _ = require('lodash');
|
|
3
|
-
|
|
4
|
-
module.exports = _.curry((config, ctx, next) => {
|
|
5
|
-
debug('Closing channel');
|
|
6
|
-
|
|
7
|
-
ctx.channel.close((err) => {
|
|
8
|
-
if (err) return next(err, config, ctx);
|
|
9
|
-
delete ctx.channel;
|
|
10
|
-
next(null, config, ctx);
|
|
11
|
-
});
|
|
12
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const debug = require('debug')('rascal:tasks:createChannel');
|
|
2
|
-
const _ = require('lodash');
|
|
3
|
-
|
|
4
|
-
module.exports = _.curry((config, ctx, next) => {
|
|
5
|
-
debug('Creating channel');
|
|
6
|
-
|
|
7
|
-
ctx.connection.createChannel((err, channel) => {
|
|
8
|
-
if (err) return next(err, config, ctx);
|
|
9
|
-
ctx.channel = channel;
|
|
10
|
-
next(null, config, ctx);
|
|
11
|
-
});
|
|
12
|
-
});
|