amqplib 0.7.1 → 0.9.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/.github/workflows/test.yml +38 -0
- package/CHANGELOG.md +64 -0
- package/Makefile +6 -7
- package/README.md +67 -67
- package/bin/generate-defs.js +0 -1
- package/examples/tutorials/README.md +6 -6
- package/lib/bitset.js +99 -72
- package/lib/channel.js +7 -6
- package/lib/channel_model.js +268 -287
- package/lib/connect.js +7 -1
- package/lib/connection.js +14 -6
- package/lib/credentials.js +0 -1
- package/lib/defs.js +1 -1
- package/lib/frame.js +0 -1
- package/lib/mux.js +1 -3
- package/package.json +7 -8
- package/test/bitset.js +22 -21
- package/test/callback_api.js +0 -1
- package/test/channel.js +0 -1
- package/test/channel_api.js +0 -1
- package/test/codec.js +0 -1
- package/test/connect.js +47 -2
- package/test/connection.js +0 -1
- package/test/data.js +0 -1
- package/test/frame.js +2 -3
- package/.npmignore +0 -8
- package/package-lock.json +0 -1623
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
|
2
|
+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
|
3
|
+
|
|
4
|
+
name: Node.js CI
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [main]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [main]
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
services:
|
|
16
|
+
rabbitmq:
|
|
17
|
+
image: rabbitmq
|
|
18
|
+
ports:
|
|
19
|
+
- 5672:5672
|
|
20
|
+
|
|
21
|
+
strategy:
|
|
22
|
+
matrix:
|
|
23
|
+
node-version: [10.x, 12.x, 14.x, 16.x, 18.x]
|
|
24
|
+
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v2
|
|
28
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
29
|
+
uses: actions/setup-node@v2
|
|
30
|
+
with:
|
|
31
|
+
node-version: ${{ matrix.node-version }}
|
|
32
|
+
cache: "npm"
|
|
33
|
+
|
|
34
|
+
# Install all prerequisites
|
|
35
|
+
- run: npm ci
|
|
36
|
+
|
|
37
|
+
# Run the tests
|
|
38
|
+
- run: make test
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
# Change log for amqplib
|
|
2
2
|
|
|
3
|
+
## Changes in v0.9.1
|
|
4
|
+
|
|
5
|
+
git log v0.9.0..v0.9.1
|
|
6
|
+
|
|
7
|
+
* Assorted readme changes
|
|
8
|
+
* Use Array.prototype.push.apply instead of concat in Mux ([PR
|
|
9
|
+
658](https://github.com/squaremo/amqp.node/pull/658), thank you
|
|
10
|
+
@Uzlopak and @kibertoad)
|
|
11
|
+
* Use Map instead of Object for BaseChannel.consumers ([PR
|
|
12
|
+
660](https://github.com/squaremo/amqp.node/pull/660), thank you
|
|
13
|
+
@Uzlopak)
|
|
14
|
+
* Delete consumer callback after cancellation to free memory ([PR
|
|
15
|
+
659](https://github.com/squaremo/amqp.node/pull/659), thank you
|
|
16
|
+
@Uzlopak and @kibertoad)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## Changes in v0.9.0
|
|
20
|
+
|
|
21
|
+
git log v0.8.0..v0.9.0
|
|
22
|
+
|
|
23
|
+
* Update mocha and replace the deprecated istanbul with nyc ([PR
|
|
24
|
+
681](https://github.com/squaremo/amqp.node/pull/681)
|
|
25
|
+
* Update url-parse ([PR
|
|
26
|
+
675](https://github.com/squaremo/amqp.node/pull/675), thank you
|
|
27
|
+
@suhail-n and @kibertoad)
|
|
28
|
+
* fix: done called twice on invalid options ([PR
|
|
29
|
+
667](https://github.com/squaremo/amqp.node/pull/667), thank you
|
|
30
|
+
@luddd3 and @kibertoad)
|
|
31
|
+
* Close connection to server on connect errors ([PR
|
|
32
|
+
647](https://github.com/squaremo/amqp.node/pull/647), thank you
|
|
33
|
+
@luddd3 and @kibertoad)
|
|
34
|
+
* Modernise channel_model.js ([PR
|
|
35
|
+
635](https://github.com/squaremo/amqp.node/pull/635), thank you
|
|
36
|
+
@kibertoad and @jimmywarting)
|
|
37
|
+
* Bring package-lock.json up to date ([PR
|
|
38
|
+
653](https://github.com/squaremo/amqp.node/pull/653)
|
|
39
|
+
* Update url-parse ([PR
|
|
40
|
+
652](https://github.com/squaremo/amqp.node/pull/652), thank you
|
|
41
|
+
@giorgioatanasov and @buffolander)
|
|
42
|
+
* Modernise channel_model.js ([PR
|
|
43
|
+
651](https://github.com/squaremo/amqp.node/pull/651), thank you
|
|
44
|
+
for the review @kibertoad)
|
|
45
|
+
* Modernise bitset.js ([PR
|
|
46
|
+
634](https://github.com/squaremo/amqp.node/pull/634), thank you
|
|
47
|
+
@kibertoad and @jimmywarting)
|
|
48
|
+
* :warning: Drop CI for node versions below 10 ([PR
|
|
49
|
+
631](https://github.com/squaremo/amqp.node/pull/631), thank you
|
|
50
|
+
for the review @kibertoad)
|
|
51
|
+
* Replace safe-buffer dependency with native buffers ([PR
|
|
52
|
+
628](https://github.com/squaremo/amqp.node/pull/628), thank you
|
|
53
|
+
@kibertoad and @jimmywarting)
|
|
54
|
+
|
|
55
|
+
## Changes in v0.8.0
|
|
56
|
+
|
|
57
|
+
git log v0.7.1..v0.8.0
|
|
58
|
+
|
|
59
|
+
* :warning: Support for NodeJS prior to v10 is dropped :warning: ([PR
|
|
60
|
+
615](https://github.com/squaremo/amqp.node/pull/615), thank you
|
|
61
|
+
@xamgore and everyone who helped there)
|
|
62
|
+
* Use hostname as TLS servername, to help with using servers behind
|
|
63
|
+
load balancers ([PR
|
|
64
|
+
567](https://github.com/squaremo/amqp.node/pull/567), thanks to
|
|
65
|
+
@carlhoerberg and commenters)
|
|
66
|
+
|
|
3
67
|
## Changes in v0.7.1
|
|
4
68
|
|
|
5
69
|
git log v0.7.0..v0.7.1
|
package/Makefile
CHANGED
|
@@ -3,12 +3,12 @@ JSON=amqp-rabbitmq-0.9.1.json
|
|
|
3
3
|
RABBITMQ_CODEGEN=https://raw.githubusercontent.com/rabbitmq/rabbitmq-codegen
|
|
4
4
|
AMQP_JSON=$(RABBITMQ_CODEGEN)/$(RABBITMQ_SRC_VERSION)/$(JSON)
|
|
5
5
|
|
|
6
|
-
NODEJS_VERSIONS='
|
|
6
|
+
NODEJS_VERSIONS='10.21' '11.15' '12.18' '13.14' '14.5' '15.8' '16.3.0' '18.1.0'
|
|
7
7
|
|
|
8
8
|
MOCHA=./node_modules/.bin/mocha
|
|
9
9
|
_MOCHA=./node_modules/.bin/_mocha
|
|
10
10
|
UGLIFY=./node_modules/.bin/uglifyjs
|
|
11
|
-
|
|
11
|
+
NYC=./node_modules/.bin/nyc
|
|
12
12
|
|
|
13
13
|
.PHONY: test test-all-nodejs all clean coverage
|
|
14
14
|
|
|
@@ -25,17 +25,16 @@ lib/defs.js: $(UGLIFY) bin/generate-defs.js bin/amqp-rabbitmq-0.9.1.json
|
|
|
25
25
|
-b 'indent-level=2' 2>&1 | (grep -v 'WARN' || true)
|
|
26
26
|
|
|
27
27
|
test: lib/defs.js
|
|
28
|
-
$(MOCHA) --check-leaks -u tdd test/
|
|
28
|
+
$(MOCHA) --check-leaks -u tdd --exit test/
|
|
29
29
|
|
|
30
30
|
test-all-nodejs: lib/defs.js
|
|
31
31
|
for v in $(NODEJS_VERSIONS); \
|
|
32
32
|
do echo "-- Node version $$v --"; \
|
|
33
|
-
nave use $$v $(MOCHA) -u tdd -R progress test; \
|
|
33
|
+
nave use $$v $(MOCHA) -u tdd --exit -R progress test; \
|
|
34
34
|
done
|
|
35
35
|
|
|
36
|
-
coverage: $(
|
|
37
|
-
$(
|
|
38
|
-
$(ISTANBUL) report
|
|
36
|
+
coverage: $(NYC) lib/defs.js
|
|
37
|
+
$(NYC) --reporter=lcov --reporter=text $(_MOCHA) -u tdd -R progress test/
|
|
39
38
|
@echo "HTML report at file://$$(pwd)/coverage/lcov-report/index.html"
|
|
40
39
|
|
|
41
40
|
bin/amqp-rabbitmq-0.9.1.json:
|
package/README.md
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
# AMQP 0-9-1 library and client for Node.JS
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/amqplib)
|
|
4
|
+
[](https://www.npmjs.com/package/amqplib)
|
|
5
|
+
[](https://github.com/amqp-node/amqplib/actions?query=workflow%3A%22Node.js+CI%22)
|
|
6
|
+
[](https://snyk.io/advisor/npm-package/amqplib)
|
|
4
7
|
|
|
5
8
|
npm install amqplib
|
|
6
9
|
|
|
7
10
|
* [Change log][changelog]
|
|
8
11
|
* [GitHub pages][gh-pages]
|
|
9
12
|
* [API reference][gh-pages-apiref]
|
|
13
|
+
* [Troubleshooting][gh-pages-trouble]
|
|
10
14
|
* [Examples from RabbitMQ tutorials][tutes]
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
releases.
|
|
16
|
+
|
|
17
|
+
A library for making AMQP 0-9-1 clients for Node.JS, and an AMQP 0-9-1 client for Node.JS v10+.
|
|
15
18
|
|
|
16
19
|
This library does not implement [AMQP
|
|
17
20
|
1.0](https://github.com/squaremo/amqp.node/issues/63) or [AMQP
|
|
@@ -34,75 +37,71 @@ Still working on:
|
|
|
34
37
|
## Callback API example
|
|
35
38
|
|
|
36
39
|
```javascript
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
ch.sendToQueue(q, Buffer.from('something to do'));
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Consumer
|
|
55
|
-
function consumer(conn) {
|
|
56
|
-
var ok = conn.createChannel(on_open);
|
|
57
|
-
function on_open(err, ch) {
|
|
58
|
-
if (err != null) bail(err);
|
|
59
|
-
ch.assertQueue(q);
|
|
60
|
-
ch.consume(q, function(msg) {
|
|
40
|
+
const amqplib = require('amqplib/callback_api');
|
|
41
|
+
const queue = 'tasks';
|
|
42
|
+
|
|
43
|
+
amqplib.connect('amqp://localhost', (err, conn) => {
|
|
44
|
+
if (err) throw err;
|
|
45
|
+
|
|
46
|
+
// Listener
|
|
47
|
+
conn.createChannel((err, ch2) => {
|
|
48
|
+
if (err) throw err;
|
|
49
|
+
|
|
50
|
+
ch2.assertQueue(queue);
|
|
51
|
+
|
|
52
|
+
ch2.consume(queue, (msg) => {
|
|
61
53
|
if (msg !== null) {
|
|
62
54
|
console.log(msg.content.toString());
|
|
63
|
-
|
|
55
|
+
ch2.ack(msg);
|
|
56
|
+
} else {
|
|
57
|
+
console.log('Consumer cancelled by server');
|
|
64
58
|
}
|
|
65
59
|
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
require('amqplib/callback_api')
|
|
70
|
-
.connect('amqp://localhost', function(err, conn) {
|
|
71
|
-
if (err != null) bail(err);
|
|
72
|
-
consumer(conn);
|
|
73
|
-
publisher(conn);
|
|
74
60
|
});
|
|
61
|
+
|
|
62
|
+
// Sender
|
|
63
|
+
conn.createChannel((err, ch1) => {
|
|
64
|
+
if (err) throw err;
|
|
65
|
+
|
|
66
|
+
ch1.assertQueue(queue);
|
|
67
|
+
|
|
68
|
+
setInterval(() => {
|
|
69
|
+
ch1.sendToQueue(queue, Buffer.from('something to do'));
|
|
70
|
+
}, 1000);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
75
73
|
```
|
|
76
74
|
|
|
77
|
-
## Promise API example
|
|
75
|
+
## Promise/Async API example
|
|
78
76
|
|
|
79
77
|
```javascript
|
|
80
|
-
|
|
78
|
+
const amqplib = require('amqplib');
|
|
79
|
+
|
|
80
|
+
(async () => {
|
|
81
|
+
const queue = 'tasks';
|
|
82
|
+
const conn = await amqplib.connect('amqp://localhost');
|
|
83
|
+
|
|
84
|
+
const ch1 = await conn.createChannel();
|
|
85
|
+
await ch1.assertQueue(queue);
|
|
86
|
+
|
|
87
|
+
// Listener
|
|
88
|
+
ch1.consume(queue, (msg) => {
|
|
89
|
+
if (msg !== null) {
|
|
90
|
+
console.log('Recieved:', msg.content.toString());
|
|
91
|
+
ch1.ack(msg);
|
|
92
|
+
} else {
|
|
93
|
+
console.log('Consumer cancelled by server');
|
|
94
|
+
}
|
|
95
|
+
});
|
|
81
96
|
|
|
82
|
-
|
|
97
|
+
// Sender
|
|
98
|
+
const ch2 = await conn.createChannel();
|
|
99
|
+
|
|
100
|
+
setInterval(() => {
|
|
101
|
+
ch2.sendToQueue(queue, Buffer.from('something to do'));
|
|
102
|
+
}, 1000);
|
|
103
|
+
})();
|
|
83
104
|
|
|
84
|
-
// Publisher
|
|
85
|
-
open.then(function(conn) {
|
|
86
|
-
return conn.createChannel();
|
|
87
|
-
}).then(function(ch) {
|
|
88
|
-
return ch.assertQueue(q).then(function(ok) {
|
|
89
|
-
return ch.sendToQueue(q, Buffer.from('something to do'));
|
|
90
|
-
});
|
|
91
|
-
}).catch(console.warn);
|
|
92
|
-
|
|
93
|
-
// Consumer
|
|
94
|
-
open.then(function(conn) {
|
|
95
|
-
return conn.createChannel();
|
|
96
|
-
}).then(function(ch) {
|
|
97
|
-
return ch.assertQueue(q).then(function(ok) {
|
|
98
|
-
return ch.consume(q, function(msg) {
|
|
99
|
-
if (msg !== null) {
|
|
100
|
-
console.log(msg.content.toString());
|
|
101
|
-
ch.ack(msg);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
}).catch(console.warn);
|
|
106
105
|
```
|
|
107
106
|
|
|
108
107
|
## Running tests
|
|
@@ -129,7 +128,7 @@ dev.rabbitmq.com instance.
|
|
|
129
128
|
|
|
130
129
|
You can run it under different versions of Node.JS using [nave][]:
|
|
131
130
|
|
|
132
|
-
nave use
|
|
131
|
+
nave use 10 npm test
|
|
133
132
|
|
|
134
133
|
or run the tests on all supported versions of Node.JS in one go:
|
|
135
134
|
|
|
@@ -148,10 +147,11 @@ really only useful for checking the kind and formatting of the errors.
|
|
|
148
147
|
make coverage
|
|
149
148
|
open file://`pwd`/coverage/lcov-report/index.html
|
|
150
149
|
|
|
151
|
-
[gh-pages]:
|
|
152
|
-
[gh-pages-apiref]:
|
|
150
|
+
[gh-pages]: https://amqp-node.github.io/amqplib/
|
|
151
|
+
[gh-pages-apiref]: https://amqp-node.github.io/amqplib/channel_api.html
|
|
152
|
+
[gh-pages-trouble]: https://amqp-node.github.io/amqplib/#troubleshooting
|
|
153
153
|
[nave]: https://github.com/isaacs/nave
|
|
154
|
-
[tutes]: https://github.com/
|
|
154
|
+
[tutes]: https://github.com/amqp-node/amqplib/tree/main/examples/tutorials
|
|
155
155
|
[rabbitmq-tutes]: http://www.rabbitmq.com/getstarted.html
|
|
156
|
-
[changelog]: https://github.com/
|
|
156
|
+
[changelog]: https://github.com/amqp-node/amqplib/blob/main/CHANGELOG.md
|
|
157
157
|
[docker]: https://www.docker.com/
|
package/bin/generate-defs.js
CHANGED
|
@@ -85,9 +85,9 @@ some needless object-orientation (in the Python code; you don't get a
|
|
|
85
85
|
choice about needless object-orientation in Java).
|
|
86
86
|
|
|
87
87
|
[rabbitmq-tutes]: http://github.com/rabbitmq/rabbitmq-tutorials
|
|
88
|
-
[tute-one]: http://www.rabbitmq.com/tutorials/tutorial-one-
|
|
89
|
-
[tute-two]: http://www.rabbitmq.com/tutorials/tutorial-two-
|
|
90
|
-
[tute-three]: http://www.rabbitmq.com/tutorials/tutorial-three-
|
|
91
|
-
[tute-four]: http://www.rabbitmq.com/tutorials/tutorial-four-
|
|
92
|
-
[tute-five]: http://www.rabbitmq.com/tutorials/tutorial-five-
|
|
93
|
-
[tute-six]: http://www.rabbitmq.com/tutorials/tutorial-six-
|
|
88
|
+
[tute-one]: http://www.rabbitmq.com/tutorials/tutorial-one-javascript.html
|
|
89
|
+
[tute-two]: http://www.rabbitmq.com/tutorials/tutorial-two-javascript.html
|
|
90
|
+
[tute-three]: http://www.rabbitmq.com/tutorials/tutorial-three-javascript.html
|
|
91
|
+
[tute-four]: http://www.rabbitmq.com/tutorials/tutorial-four-javascript.html
|
|
92
|
+
[tute-five]: http://www.rabbitmq.com/tutorials/tutorial-five-javascript.html
|
|
93
|
+
[tute-six]: http://www.rabbitmq.com/tutorials/tutorial-six-javascript.html
|
package/lib/bitset.js
CHANGED
|
@@ -2,67 +2,124 @@
|
|
|
2
2
|
//
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
// A bitset implementation, after that in java.util. Yes there
|
|
6
|
-
// already exist such things, but none implement next{Clear|Set}Bit or
|
|
7
|
-
// equivalent, and none involved me tooling about for an evening.
|
|
8
|
-
|
|
9
5
|
'use strict';
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
/**
|
|
8
|
+
* A bitset implementation, after that in java.util. Yes there
|
|
9
|
+
* already exist such things, but none implement next{Clear|Set}Bit or
|
|
10
|
+
* equivalent, and none involved me tooling about for an evening.
|
|
11
|
+
*/
|
|
12
|
+
class BitSet {
|
|
13
|
+
/**
|
|
14
|
+
* @param {number} [size]
|
|
15
|
+
*/
|
|
16
|
+
constructor(size) {
|
|
17
|
+
if (size) {
|
|
18
|
+
const numWords = Math.ceil(size / 32);
|
|
19
|
+
this.words = new Array(numWords);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.words = [];
|
|
23
|
+
}
|
|
24
|
+
this.wordsInUse = 0; // = number, not index
|
|
15
25
|
}
|
|
16
|
-
|
|
17
|
-
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {number} numWords
|
|
29
|
+
*/
|
|
30
|
+
ensureSize(numWords) {
|
|
31
|
+
const wordsPresent = this.words.length;
|
|
32
|
+
if (wordsPresent < numWords) {
|
|
33
|
+
this.words = this.words.concat(new Array(numWords - wordsPresent));
|
|
34
|
+
}
|
|
18
35
|
}
|
|
19
|
-
this.wordsInUse = 0; // = number, not index
|
|
20
|
-
}
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
/**
|
|
38
|
+
* @param {number} bitIndex
|
|
39
|
+
*/
|
|
40
|
+
set(bitIndex) {
|
|
41
|
+
const w = wordIndex(bitIndex);
|
|
42
|
+
if (w >= this.wordsInUse) {
|
|
43
|
+
this.ensureSize(w + 1);
|
|
44
|
+
this.wordsInUse = w + 1;
|
|
45
|
+
}
|
|
46
|
+
const bit = 1 << bitIndex;
|
|
47
|
+
this.words[w] |= bit;
|
|
48
|
+
}
|
|
23
49
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @param {number} bitIndex
|
|
52
|
+
*/
|
|
53
|
+
clear(bitIndex) {
|
|
54
|
+
const w = wordIndex(bitIndex);
|
|
55
|
+
if (w >= this.wordsInUse) return;
|
|
56
|
+
const mask = ~(1 << bitIndex);
|
|
57
|
+
this.words[w] &= mask;
|
|
58
|
+
}
|
|
27
59
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
60
|
+
/**
|
|
61
|
+
* @param {number} bitIndex
|
|
62
|
+
*/
|
|
63
|
+
get(bitIndex) {
|
|
64
|
+
const w = wordIndex(bitIndex);
|
|
65
|
+
if (w >= this.wordsInUse) return false; // >= since index vs size
|
|
66
|
+
const bit = 1 << bitIndex;
|
|
67
|
+
return !!(this.words[w] & bit);
|
|
33
68
|
}
|
|
34
|
-
}
|
|
35
69
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Give the next bit that is set on or after fromIndex, or -1 if no such bit
|
|
72
|
+
*
|
|
73
|
+
* @param {number} fromIndex
|
|
74
|
+
*/
|
|
75
|
+
nextSetBit(fromIndex) {
|
|
76
|
+
let w = wordIndex(fromIndex);
|
|
77
|
+
if (w >= this.wordsInUse) return -1;
|
|
78
|
+
|
|
79
|
+
// the right-hand side is shifted to only test the bits of the first
|
|
80
|
+
// word that are > fromIndex
|
|
81
|
+
let word = this.words[w] & (0xffffffff << fromIndex);
|
|
82
|
+
while (true) {
|
|
83
|
+
if (word) return (w * 32) + trailingZeros(word);
|
|
84
|
+
w++;
|
|
85
|
+
if (w === this.wordsInUse) return -1;
|
|
86
|
+
word = this.words[w];
|
|
87
|
+
}
|
|
41
88
|
}
|
|
42
|
-
var bit = 1 << bitIndex;
|
|
43
|
-
this.words[w] |= bit;
|
|
44
|
-
};
|
|
45
89
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
90
|
+
/**
|
|
91
|
+
* @param {number} fromIndex
|
|
92
|
+
*/
|
|
93
|
+
nextClearBit(fromIndex) {
|
|
94
|
+
let w = wordIndex(fromIndex);
|
|
95
|
+
if (w >= this.wordsInUse) return fromIndex;
|
|
52
96
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
97
|
+
let word = ~(this.words[w]) & (0xffffffff << fromIndex);
|
|
98
|
+
while (true) {
|
|
99
|
+
if (word) return (w * 32) + trailingZeros(word);
|
|
100
|
+
w++;
|
|
101
|
+
if (w == this.wordsInUse) return w * 32;
|
|
102
|
+
word = ~(this.words[w]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
58
105
|
}
|
|
59
106
|
|
|
107
|
+
/**
|
|
108
|
+
* @param {number} bitIndex
|
|
109
|
+
*/
|
|
110
|
+
function wordIndex(bitIndex) {
|
|
111
|
+
return Math.floor(bitIndex / 32);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {number} i
|
|
116
|
+
*/
|
|
60
117
|
function trailingZeros(i) {
|
|
61
118
|
// From Hacker's Delight, via JDK. Probably far less effective here,
|
|
62
119
|
// since bit ops are not necessarily the quick way to do things in
|
|
63
120
|
// JS.
|
|
64
121
|
if (i === 0) return 32;
|
|
65
|
-
|
|
122
|
+
let y, n = 31;
|
|
66
123
|
y = i << 16; if (y != 0) { n = n -16; i = y; }
|
|
67
124
|
y = i << 8; if (y != 0) { n = n - 8; i = y; }
|
|
68
125
|
y = i << 4; if (y != 0) { n = n - 4; i = y; }
|
|
@@ -70,34 +127,4 @@ function trailingZeros(i) {
|
|
|
70
127
|
return n - ((i << 1) >>> 31);
|
|
71
128
|
}
|
|
72
129
|
|
|
73
|
-
// Give the next bit that's set on or after fromIndex, or -1 if no such
|
|
74
|
-
// bit
|
|
75
|
-
P.nextSetBit = function(fromIndex) {
|
|
76
|
-
var w = wordIndex(fromIndex);
|
|
77
|
-
if (w >= this.wordsInUse) return -1;
|
|
78
|
-
|
|
79
|
-
// the right-hand side is shifted to only test the bits of the first
|
|
80
|
-
// word that are > fromIndex
|
|
81
|
-
var word = this.words[w] & (0xffffffff << fromIndex);
|
|
82
|
-
while (true) {
|
|
83
|
-
if (word) return (w * 32) + trailingZeros(word);
|
|
84
|
-
w++;
|
|
85
|
-
if (w === this.wordsInUse) return -1;
|
|
86
|
-
word = this.words[w];
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
P.nextClearBit = function(fromIndex) {
|
|
91
|
-
var w = wordIndex(fromIndex);
|
|
92
|
-
if (w >= this.wordsInUse) return fromIndex;
|
|
93
|
-
|
|
94
|
-
var word = ~(this.words[w]) & (0xffffffff << fromIndex);
|
|
95
|
-
while (true) {
|
|
96
|
-
if (word) return (w * 32) + trailingZeros(word);
|
|
97
|
-
w++;
|
|
98
|
-
if (w == this.wordsInUse) return w * 32;
|
|
99
|
-
word = ~(this.words[w]);
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
|
|
103
130
|
module.exports.BitSet = BitSet;
|
package/lib/channel.js
CHANGED
|
@@ -16,7 +16,6 @@ var EventEmitter = require('events').EventEmitter;
|
|
|
16
16
|
var fmt = require('util').format;
|
|
17
17
|
var IllegalOperationError = require('./error').IllegalOperationError;
|
|
18
18
|
var stackCapture = require('./error').stackCapture;
|
|
19
|
-
var Buffer = require('safe-buffer').Buffer
|
|
20
19
|
function Channel(connection) {
|
|
21
20
|
EventEmitter.call( this );
|
|
22
21
|
this.connection = connection;
|
|
@@ -461,7 +460,7 @@ C.onBufferDrain = function() {
|
|
|
461
460
|
// low-level machinery.
|
|
462
461
|
function BaseChannel(connection) {
|
|
463
462
|
Channel.call(this, connection);
|
|
464
|
-
this.consumers =
|
|
463
|
+
this.consumers = new Map();
|
|
465
464
|
}
|
|
466
465
|
inherits(BaseChannel, Channel);
|
|
467
466
|
|
|
@@ -470,16 +469,16 @@ module.exports.BaseChannel = BaseChannel;
|
|
|
470
469
|
// Not sure I like the ff, it's going to be changing hidden classes
|
|
471
470
|
// all over the place. On the other hand, whaddya do.
|
|
472
471
|
BaseChannel.prototype.registerConsumer = function(tag, callback) {
|
|
473
|
-
this.consumers
|
|
472
|
+
this.consumers.set(tag, callback);
|
|
474
473
|
};
|
|
475
474
|
|
|
476
475
|
BaseChannel.prototype.unregisterConsumer = function(tag) {
|
|
477
|
-
|
|
476
|
+
this.consumers.delete(tag);
|
|
478
477
|
};
|
|
479
478
|
|
|
480
479
|
BaseChannel.prototype.dispatchMessage = function(fields, message) {
|
|
481
480
|
var consumerTag = fields.consumerTag;
|
|
482
|
-
var consumer = this.consumers
|
|
481
|
+
var consumer = this.consumers.get(consumerTag);
|
|
483
482
|
if (consumer) {
|
|
484
483
|
return consumer(message);
|
|
485
484
|
}
|
|
@@ -494,5 +493,7 @@ BaseChannel.prototype.handleDelivery = function(message) {
|
|
|
494
493
|
};
|
|
495
494
|
|
|
496
495
|
BaseChannel.prototype.handleCancel = function(fields) {
|
|
497
|
-
|
|
496
|
+
var result = this.dispatchMessage(fields, null);
|
|
497
|
+
this.unregisterConsumer(fields.consumerTag);
|
|
498
|
+
return result;
|
|
498
499
|
};
|