rascal 13.1.1 → 14.0.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/.husky/pre-commit +1 -1
- package/.prettierrc.json +4 -0
- package/CHANGELOG.md +213 -1
- package/README.md +597 -381
- package/examples/advanced/cluster.js +8 -8
- package/examples/advanced/config.js +121 -123
- package/examples/advanced/handlers/deleteUser.js +16 -17
- package/examples/advanced/handlers/saveUser.js +32 -33
- package/examples/advanced/index.js +85 -80
- package/examples/busy-publisher/config.js +19 -22
- package/examples/busy-publisher/index.js +11 -12
- package/examples/default-exchange/config.js +13 -13
- package/examples/default-exchange/index.js +22 -18
- package/examples/mocha/config.js +13 -15
- package/examples/mocha/test.js +34 -35
- package/examples/promises/config.js +15 -17
- package/examples/promises/index.js +14 -12
- package/examples/simple/config.js +21 -23
- package/examples/simple/index.js +20 -22
- package/index.js +1 -1
- package/lib/amqp/Broker.js +105 -82
- package/lib/amqp/BrokerAsPromised.js +40 -28
- package/lib/amqp/Publication.js +15 -14
- package/lib/amqp/PublicationSession.js +6 -7
- package/lib/amqp/SubscriberError.js +159 -124
- package/lib/amqp/SubscriberSession.js +87 -68
- package/lib/amqp/SubscriberSessionAsPromised.js +1 -3
- package/lib/amqp/Subscription.js +25 -24
- package/lib/amqp/Vhost.js +93 -67
- package/lib/amqp/tasks/applyBindings.js +9 -6
- package/lib/amqp/tasks/assertExchanges.js +9 -5
- package/lib/amqp/tasks/assertQueues.js +9 -5
- package/lib/amqp/tasks/assertVhost.js +17 -13
- package/lib/amqp/tasks/bounceVhost.js +1 -1
- package/lib/amqp/tasks/checkExchanges.js +9 -5
- package/lib/amqp/tasks/checkQueues.js +9 -5
- package/lib/amqp/tasks/checkVhost.js +17 -13
- package/lib/amqp/tasks/closeChannel.js +0 -1
- package/lib/amqp/tasks/createChannel.js +0 -1
- package/lib/amqp/tasks/createConnection.js +18 -15
- package/lib/amqp/tasks/deleteExchanges.js +9 -5
- package/lib/amqp/tasks/deleteQueues.js +9 -5
- package/lib/amqp/tasks/deleteVhost.js +17 -13
- package/lib/amqp/tasks/forewarnVhost.js +1 -1
- package/lib/amqp/tasks/initCounters.js +12 -8
- package/lib/amqp/tasks/initPublications.js +13 -9
- package/lib/amqp/tasks/initShovels.js +9 -5
- package/lib/amqp/tasks/initSubscriptions.js +12 -8
- package/lib/amqp/tasks/initVhosts.js +16 -12
- package/lib/amqp/tasks/nukeVhost.js +1 -1
- package/lib/amqp/tasks/purgeQueues.js +9 -5
- package/lib/amqp/tasks/purgeVhost.js +1 -1
- package/lib/amqp/tasks/shutdownVhost.js +1 -1
- package/lib/backoff/exponential.js +1 -2
- package/lib/backoff/index.js +1 -1
- package/lib/backoff/linear.js +2 -4
- package/lib/config/baseline.js +12 -23
- package/lib/config/configure.js +89 -41
- package/lib/config/tests.js +30 -27
- package/lib/config/validate.js +22 -3
- package/lib/counters/inMemoryCluster.js +33 -22
- package/lib/counters/index.js +1 -1
- package/lib/counters/stub.js +2 -3
- package/lib/management/client.js +3 -9
- package/lib/utils/setTimeoutUnref.js +1 -1
- package/package.json +12 -4
package/lib/config/tests.js
CHANGED
|
@@ -1,41 +1,44 @@
|
|
|
1
1
|
const _ = require('lodash').runInContext();
|
|
2
2
|
const defaultConfig = require('./defaults');
|
|
3
3
|
|
|
4
|
-
module.exports = _.defaultsDeep(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
module.exports = _.defaultsDeep(
|
|
5
|
+
{
|
|
6
|
+
defaults: {
|
|
7
|
+
vhosts: {
|
|
8
|
+
connection: {
|
|
9
|
+
options: {
|
|
10
|
+
heartbeat: 50,
|
|
11
|
+
},
|
|
10
12
|
},
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
namespace: true,
|
|
14
|
+
exchanges: {
|
|
15
|
+
options: {
|
|
16
|
+
durable: false,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
queues: {
|
|
20
|
+
purge: true,
|
|
21
|
+
options: {
|
|
22
|
+
durable: false,
|
|
23
|
+
},
|
|
16
24
|
},
|
|
17
25
|
},
|
|
18
|
-
|
|
19
|
-
purge: true,
|
|
26
|
+
publications: {
|
|
20
27
|
options: {
|
|
21
|
-
|
|
28
|
+
persistent: false,
|
|
22
29
|
},
|
|
23
30
|
},
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
options: {
|
|
27
|
-
persistent: false,
|
|
31
|
+
subscriptions: {
|
|
32
|
+
closeTimeout: 500,
|
|
28
33
|
},
|
|
29
34
|
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"counters": {
|
|
36
|
-
"inMemory": {
|
|
37
|
-
"size": 1000,
|
|
35
|
+
redeliveries: {
|
|
36
|
+
counters: {
|
|
37
|
+
inMemory: {
|
|
38
|
+
size: 1000,
|
|
39
|
+
},
|
|
38
40
|
},
|
|
39
41
|
},
|
|
40
42
|
},
|
|
41
|
-
|
|
43
|
+
defaultConfig
|
|
44
|
+
);
|
package/lib/config/validate.js
CHANGED
|
@@ -59,7 +59,6 @@ module.exports = _.curry((config, next) => {
|
|
|
59
59
|
if (invalid.length) throw new Error(format('%s: %s in vhost: %s refers to an unsupported attribute: %s', type, childName, vhostName, invalid[0]));
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
63
62
|
function validateExchanges(vhost, vhostName, exchanges) {
|
|
64
63
|
_.each(exchanges, validateExchange.bind(null, vhost, vhostName));
|
|
65
64
|
}
|
|
@@ -104,7 +103,7 @@ module.exports = _.curry((config, next) => {
|
|
|
104
103
|
validateAttributes('Publication', publication, publicationName, ['name', 'vhost', 'exchange', 'queue', 'routingKey', 'confirm', 'options', 'destination', 'autoCreated', 'deprecated', 'encryption', 'timeout']);
|
|
105
104
|
if (!publication.vhost) throw new Error(format('Publication: %s is missing a vhost', publicationName));
|
|
106
105
|
if (!(Object.prototype.hasOwnProperty.call(publication, 'exchange') || publication.queue)) throw new Error(format('Publication: %s is missing an exchange or a queue', publicationName));
|
|
107
|
-
if (
|
|
106
|
+
if (Object.prototype.hasOwnProperty.call(publication, 'exchange') && publication.queue) throw new Error(format('Publication: %s has an exchange and a queue', publicationName));
|
|
108
107
|
|
|
109
108
|
if (!config.vhosts) throw new Error(format('Publication: %s refers to an unknown vhost: %s', publicationName, publication.vhost));
|
|
110
109
|
if (!config.vhosts[publication.vhost]) throw new Error(format('Publication: %s refers to an unknown vhost: %s', publicationName, publication.vhost));
|
|
@@ -125,7 +124,27 @@ module.exports = _.curry((config, next) => {
|
|
|
125
124
|
}
|
|
126
125
|
|
|
127
126
|
function validateSubscription(subscription, subscriptionName) {
|
|
128
|
-
validateAttributes('Subscription', subscription, subscriptionName, [
|
|
127
|
+
validateAttributes('Subscription', subscription, subscriptionName, [
|
|
128
|
+
'name',
|
|
129
|
+
'vhost',
|
|
130
|
+
'queue',
|
|
131
|
+
'contentType',
|
|
132
|
+
'options',
|
|
133
|
+
'prefetch',
|
|
134
|
+
'retry',
|
|
135
|
+
'source',
|
|
136
|
+
'recovery',
|
|
137
|
+
'workflow',
|
|
138
|
+
'handler',
|
|
139
|
+
'workflows',
|
|
140
|
+
'handlers',
|
|
141
|
+
'redeliveries',
|
|
142
|
+
'autoCreated',
|
|
143
|
+
'deprecated',
|
|
144
|
+
'closeTimeout',
|
|
145
|
+
'encryption',
|
|
146
|
+
'promisifyAckOrNack',
|
|
147
|
+
]);
|
|
129
148
|
|
|
130
149
|
if (!subscription.vhost) throw new Error(format('Subscription: %s is missing a vhost', subscriptionName));
|
|
131
150
|
if (!subscription.queue) throw new Error(format('Subscription: %s is missing a queue', subscriptionName));
|
|
@@ -12,23 +12,30 @@ module.exports = {
|
|
|
12
12
|
function handleMessage(worker, message) {
|
|
13
13
|
if (message.sender !== 'rascal-in-memory-cluster-counter' || message.cmd !== 'incrementAndGet') return;
|
|
14
14
|
counter.incrementAndGet(message.key, (err, value) => {
|
|
15
|
-
worker.send({
|
|
15
|
+
worker.send({
|
|
16
|
+
sender: 'rascal-in-memory-cluster-counter',
|
|
17
|
+
correlationId: message.correlationId,
|
|
18
|
+
value: err ? 1 : value,
|
|
19
|
+
});
|
|
16
20
|
});
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
cluster
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
cluster
|
|
24
|
+
.on('fork', (worker) => {
|
|
25
|
+
workers[worker.id] = worker;
|
|
26
|
+
worker.on('message', (message) => {
|
|
27
|
+
handleMessage(worker, message);
|
|
28
|
+
});
|
|
29
|
+
})
|
|
30
|
+
.on('disconnect', (worker) => {
|
|
31
|
+
delete workers[worker.id];
|
|
32
|
+
})
|
|
33
|
+
.on('exit', (worker) => {
|
|
34
|
+
delete workers[worker.id];
|
|
23
35
|
});
|
|
24
|
-
}).on('disconnect', (worker) => {
|
|
25
|
-
delete workers[worker.id];
|
|
26
|
-
}).on('exit', (worker) => {
|
|
27
|
-
delete workers[worker.id];
|
|
28
|
-
});
|
|
29
36
|
},
|
|
30
37
|
worker: function worker(options) {
|
|
31
|
-
if (!cluster.isWorker) throw new Error(
|
|
38
|
+
if (!cluster.isWorker) throw new Error("You cannot use Rascal's in memmory cluster counter outside of a cluster");
|
|
32
39
|
if (!options) return worker({});
|
|
33
40
|
const timeout = options.timeout || 100;
|
|
34
41
|
const stashback = Stashback({ timeout });
|
|
@@ -41,18 +48,22 @@ module.exports = {
|
|
|
41
48
|
});
|
|
42
49
|
|
|
43
50
|
return {
|
|
44
|
-
incrementAndGet
|
|
51
|
+
incrementAndGet(key, cb) {
|
|
45
52
|
const correlationId = uuid();
|
|
46
|
-
stashback.stash(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
stashback.stash(
|
|
54
|
+
correlationId,
|
|
55
|
+
(err, value) => {
|
|
56
|
+
err ? cb(null, 1) : cb(null, value);
|
|
57
|
+
},
|
|
58
|
+
(err) => {
|
|
59
|
+
if (err) return cb(null, 1);
|
|
60
|
+
process.send({
|
|
61
|
+
sender: 'rascal-in-memory-cluster-counter',
|
|
62
|
+
correlationId,
|
|
63
|
+
cmd: 'incrementAndGet',
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
);
|
|
56
67
|
},
|
|
57
68
|
};
|
|
58
69
|
},
|
package/lib/counters/index.js
CHANGED
package/lib/counters/stub.js
CHANGED
package/lib/management/client.js
CHANGED
|
@@ -8,9 +8,7 @@ function assertVhost(name, config, next) {
|
|
|
8
8
|
const options = getVhostOptions(name, config);
|
|
9
9
|
request('put', options.url, options.timeout, (err) => {
|
|
10
10
|
if (!err) return next();
|
|
11
|
-
const message = err.status
|
|
12
|
-
? format('Failed to assert vhost: %s. %s returned status %d', name, config.loggableUrl, err.status)
|
|
13
|
-
: format('Failed to assert vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
11
|
+
const message = err.status ? format('Failed to assert vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to assert vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
14
12
|
return next(new Error(message));
|
|
15
13
|
});
|
|
16
14
|
}
|
|
@@ -20,9 +18,7 @@ function checkVhost(name, config, next) {
|
|
|
20
18
|
const options = getVhostOptions(name, config);
|
|
21
19
|
request('get', options.url, options.timeout, (err) => {
|
|
22
20
|
if (!err) return next();
|
|
23
|
-
const message = err.status
|
|
24
|
-
? format('Failed to check vhost: %s. %s returned status %d', name, config.loggableUrl, err.status)
|
|
25
|
-
: format('Failed to check vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
21
|
+
const message = err.status ? format('Failed to check vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to check vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
26
22
|
return next(new Error(message));
|
|
27
23
|
});
|
|
28
24
|
}
|
|
@@ -32,9 +28,7 @@ function deleteVhost(name, config, next) {
|
|
|
32
28
|
const options = getVhostOptions(name, config);
|
|
33
29
|
request('delete', options.url, options.timeout, (err) => {
|
|
34
30
|
if (!err) return next();
|
|
35
|
-
const message = err.status
|
|
36
|
-
? format('Failed to delete vhost: %s. %s returned status %d', name, config.loggableUrl, err.status)
|
|
37
|
-
: format('Failed to delete vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
31
|
+
const message = err.status ? format('Failed to delete vhost: %s. %s returned status %d', name, config.loggableUrl, err.status) : format('Failed to delete vhost: %s. %s errored with: %s', name, config.loggableUrl, err.message);
|
|
38
32
|
return next(new Error(message));
|
|
39
33
|
});
|
|
40
34
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rascal",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.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": {
|
|
7
|
-
"async": "^3.2.
|
|
7
|
+
"async": "^3.2.1",
|
|
8
8
|
"debug": "^4.1.1",
|
|
9
9
|
"deep-freeze": "0.0.1",
|
|
10
10
|
"forward-emitter": "^0.1.1",
|
|
@@ -21,10 +21,13 @@
|
|
|
21
21
|
"amqplib": "^0.8.0",
|
|
22
22
|
"chalk": "^4.0.0",
|
|
23
23
|
"chance": "^1.1.4",
|
|
24
|
-
"eslint": "^
|
|
25
|
-
"eslint-config-
|
|
24
|
+
"eslint": "^7.32.0",
|
|
25
|
+
"eslint-config-prettier": "^8.3.0",
|
|
26
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
26
27
|
"husky": "^6.0.0",
|
|
28
|
+
"lint-staged": "^11.2.4",
|
|
27
29
|
"nyc": "^15.1.0",
|
|
30
|
+
"prettier": "2.4.1",
|
|
28
31
|
"random-readable": "^1.0.1",
|
|
29
32
|
"zunit": "^3.0.8"
|
|
30
33
|
},
|
|
@@ -36,11 +39,16 @@
|
|
|
36
39
|
},
|
|
37
40
|
"scripts": {
|
|
38
41
|
"test": "zUnit",
|
|
42
|
+
"prettier": "prettier --check .",
|
|
39
43
|
"lint": "eslint .",
|
|
44
|
+
"lint-staged": "lint-staged",
|
|
40
45
|
"coverage": "nyc --report html --reporter lcov --reporter text-summary zUnit",
|
|
41
46
|
"docker": "docker run -d --name rascal-rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management",
|
|
42
47
|
"prepare": "husky install"
|
|
43
48
|
},
|
|
49
|
+
"lint-staged": {
|
|
50
|
+
"**/*": "prettier --write --ignore-unknown"
|
|
51
|
+
},
|
|
44
52
|
"keywords": [
|
|
45
53
|
"amqplib",
|
|
46
54
|
"amqp",
|