amqplib 0.8.0 → 0.9.0
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 +36 -0
- package/Makefile +5 -6
- package/bin/generate-defs.js +0 -1
- package/examples/tutorials/README.md +6 -6
- package/lib/bitset.js +99 -72
- package/lib/channel.js +0 -1
- package/lib/channel_model.js +268 -287
- package/lib/connect.js +5 -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/package.json +4 -6
- 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
package/lib/channel_model.js
CHANGED
|
@@ -4,264 +4,259 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
7
|
+
const EventEmitter = require('events');
|
|
8
|
+
const Promise = require('bluebird');
|
|
9
|
+
const defs = require('./defs');
|
|
10
|
+
const {BaseChannel} = require('./channel');
|
|
11
|
+
const {acceptMessage} = require('./channel');
|
|
12
|
+
const Args = require('./api_args');
|
|
13
|
+
const {inspect} = require('./format');
|
|
14
|
+
|
|
15
|
+
class ChannelModel extends EventEmitter {
|
|
16
|
+
constructor(connection) {
|
|
17
|
+
super();
|
|
18
|
+
this.connection = connection;
|
|
19
|
+
|
|
20
|
+
['error', 'close', 'blocked', 'unblocked'].forEach(ev => {
|
|
21
|
+
connection.on(ev, this.emit.bind(this, ev));
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
close() {
|
|
26
|
+
return Promise.fromCallback(this.connection.close.bind(this.connection));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async createChannel() {
|
|
30
|
+
const channel = new Channel(this.connection);
|
|
31
|
+
await channel.open();
|
|
32
|
+
return channel;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async createConfirmChannel() {
|
|
36
|
+
const channel = new ConfirmChannel(this.connection);
|
|
37
|
+
await channel.open();
|
|
38
|
+
await channel.rpc(defs.ConfirmSelect, {nowait: false}, defs.ConfirmSelectOk);
|
|
39
|
+
return channel;
|
|
40
|
+
}
|
|
24
41
|
}
|
|
25
|
-
inherits(ChannelModel, EventEmitter);
|
|
26
|
-
|
|
27
|
-
module.exports.ChannelModel = ChannelModel;
|
|
28
|
-
|
|
29
|
-
var CM = ChannelModel.prototype;
|
|
30
|
-
|
|
31
|
-
CM.close = function() {
|
|
32
|
-
return Promise.fromCallback(this.connection.close.bind(this.connection));
|
|
33
|
-
};
|
|
34
42
|
|
|
35
43
|
// Channels
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
class Channel extends BaseChannel {
|
|
46
|
+
constructor(connection) {
|
|
47
|
+
super(connection);
|
|
48
|
+
this.on('delivery', this.handleDelivery.bind(this));
|
|
49
|
+
this.on('cancel', this.handleCancel.bind(this));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// An RPC that returns a 'proper' promise, which resolves to just the
|
|
53
|
+
// response's fields; this is intended to be suitable for implementing
|
|
54
|
+
// API procedures.
|
|
55
|
+
async rpc(method, fields, expect) {
|
|
56
|
+
const f = await Promise.fromCallback(cb => {
|
|
57
|
+
return this._rpc(method, fields, expect, cb);
|
|
58
|
+
})
|
|
45
59
|
|
|
46
|
-
CM.createChannel = function() {
|
|
47
|
-
var c = new Channel(this.connection);
|
|
48
|
-
return c.open().then(function(openOk) { return c; });
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
var C = Channel.prototype;
|
|
52
|
-
|
|
53
|
-
// An RPC that returns a 'proper' promise, which resolves to just the
|
|
54
|
-
// response's fields; this is intended to be suitable for implementing
|
|
55
|
-
// API procedures.
|
|
56
|
-
C.rpc = function(method, fields, expect) {
|
|
57
|
-
var self = this;
|
|
58
|
-
return Promise.fromCallback(function(cb) {
|
|
59
|
-
return self._rpc(method, fields, expect, cb);
|
|
60
|
-
})
|
|
61
|
-
.then(function(f) {
|
|
62
60
|
return f.fields;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Do the remarkably simple channel open handshake
|
|
64
|
+
open() {
|
|
65
|
+
return Promise.try(this.allocate.bind(this)).then(
|
|
66
|
+
ch => {
|
|
67
|
+
return ch.rpc(defs.ChannelOpen, {outOfBand: ""},
|
|
68
|
+
defs.ChannelOpenOk);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
close() {
|
|
73
|
+
return Promise.fromCallback(cb => {
|
|
74
|
+
return this.closeBecause("Goodbye", defs.constants.REPLY_SUCCESS,
|
|
75
|
+
cb);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// === Public API, declaring queues and stuff ===
|
|
80
|
+
|
|
81
|
+
assertQueue(queue, options) {
|
|
82
|
+
return this.rpc(defs.QueueDeclare,
|
|
83
|
+
Args.assertQueue(queue, options),
|
|
84
|
+
defs.QueueDeclareOk);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
checkQueue(queue) {
|
|
88
|
+
return this.rpc(defs.QueueDeclare,
|
|
89
|
+
Args.checkQueue(queue),
|
|
90
|
+
defs.QueueDeclareOk);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
deleteQueue(queue, options) {
|
|
94
|
+
return this.rpc(defs.QueueDelete,
|
|
95
|
+
Args.deleteQueue(queue, options),
|
|
96
|
+
defs.QueueDeleteOk);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
purgeQueue(queue) {
|
|
100
|
+
return this.rpc(defs.QueuePurge,
|
|
101
|
+
Args.purgeQueue(queue),
|
|
102
|
+
defs.QueuePurgeOk);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
bindQueue(queue, source, pattern, argt) {
|
|
106
|
+
return this.rpc(defs.QueueBind,
|
|
107
|
+
Args.bindQueue(queue, source, pattern, argt),
|
|
108
|
+
defs.QueueBindOk);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
unbindQueue(queue, source, pattern, argt) {
|
|
112
|
+
return this.rpc(defs.QueueUnbind,
|
|
113
|
+
Args.unbindQueue(queue, source, pattern, argt),
|
|
114
|
+
defs.QueueUnbindOk);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
assertExchange(exchange, type, options) {
|
|
118
|
+
// The server reply is an empty set of fields, but it's convenient
|
|
119
|
+
// to have the exchange name handed to the continuation.
|
|
120
|
+
return this.rpc(defs.ExchangeDeclare,
|
|
121
|
+
Args.assertExchange(exchange, type, options),
|
|
122
|
+
defs.ExchangeDeclareOk)
|
|
123
|
+
.then(_ok => { return { exchange }; });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
checkExchange(exchange) {
|
|
127
|
+
return this.rpc(defs.ExchangeDeclare,
|
|
128
|
+
Args.checkExchange(exchange),
|
|
129
|
+
defs.ExchangeDeclareOk);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
deleteExchange(name, options) {
|
|
133
|
+
return this.rpc(defs.ExchangeDelete,
|
|
134
|
+
Args.deleteExchange(name, options),
|
|
135
|
+
defs.ExchangeDeleteOk);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
bindExchange(dest, source, pattern, argt) {
|
|
139
|
+
return this.rpc(defs.ExchangeBind,
|
|
140
|
+
Args.bindExchange(dest, source, pattern, argt),
|
|
141
|
+
defs.ExchangeBindOk);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
unbindExchange(dest, source, pattern, argt) {
|
|
145
|
+
return this.rpc(defs.ExchangeUnbind,
|
|
146
|
+
Args.unbindExchange(dest, source, pattern, argt),
|
|
147
|
+
defs.ExchangeUnbindOk);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Working with messages
|
|
151
|
+
|
|
152
|
+
publish(exchange, routingKey, content, options) {
|
|
153
|
+
const fieldsAndProps = Args.publish(exchange, routingKey, options);
|
|
154
|
+
return this.sendMessage(fieldsAndProps, fieldsAndProps, content);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
sendToQueue(queue, content, options) {
|
|
158
|
+
return this.publish('', queue, content, options);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
consume(queue, callback, options) {
|
|
162
|
+
// NB we want the callback to be run synchronously, so that we've
|
|
163
|
+
// registered the consumerTag before any messages can arrive.
|
|
164
|
+
const fields = Args.consume(queue, options);
|
|
165
|
+
return Promise.fromCallback(cb => {
|
|
166
|
+
this._rpc(defs.BasicConsume, fields, defs.BasicConsumeOk, cb);
|
|
167
|
+
})
|
|
168
|
+
.then(ok => {
|
|
169
|
+
this.registerConsumer(ok.fields.consumerTag, callback);
|
|
170
|
+
return ok.fields;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async cancel(consumerTag) {
|
|
175
|
+
const ok = await Promise.fromCallback(cb => {
|
|
176
|
+
this._rpc(defs.BasicCancel, Args.cancel(consumerTag),
|
|
177
|
+
defs.BasicCancelOk,
|
|
178
|
+
cb);
|
|
179
|
+
})
|
|
180
|
+
.then(ok => {
|
|
181
|
+
this.unregisterConsumer(consumerTag);
|
|
182
|
+
return ok.fields;
|
|
72
183
|
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
C.checkQueue = function(queue) {
|
|
92
|
-
return this.rpc(defs.QueueDeclare,
|
|
93
|
-
Args.checkQueue(queue),
|
|
94
|
-
defs.QueueDeclareOk);
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
C.deleteQueue = function(queue, options) {
|
|
98
|
-
return this.rpc(defs.QueueDelete,
|
|
99
|
-
Args.deleteQueue(queue, options),
|
|
100
|
-
defs.QueueDeleteOk);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
C.purgeQueue = function(queue) {
|
|
104
|
-
return this.rpc(defs.QueuePurge,
|
|
105
|
-
Args.purgeQueue(queue),
|
|
106
|
-
defs.QueuePurgeOk);
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
C.bindQueue = function(queue, source, pattern, argt) {
|
|
110
|
-
return this.rpc(defs.QueueBind,
|
|
111
|
-
Args.bindQueue(queue, source, pattern, argt),
|
|
112
|
-
defs.QueueBindOk);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
C.unbindQueue = function(queue, source, pattern, argt) {
|
|
116
|
-
return this.rpc(defs.QueueUnbind,
|
|
117
|
-
Args.unbindQueue(queue, source, pattern, argt),
|
|
118
|
-
defs.QueueUnbindOk);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
C.assertExchange = function(exchange, type, options) {
|
|
122
|
-
// The server reply is an empty set of fields, but it's convenient
|
|
123
|
-
// to have the exchange name handed to the continuation.
|
|
124
|
-
return this.rpc(defs.ExchangeDeclare,
|
|
125
|
-
Args.assertExchange(exchange, type, options),
|
|
126
|
-
defs.ExchangeDeclareOk)
|
|
127
|
-
.then(function(_ok) { return { exchange: exchange }; });
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
C.checkExchange = function(exchange) {
|
|
131
|
-
return this.rpc(defs.ExchangeDeclare,
|
|
132
|
-
Args.checkExchange(exchange),
|
|
133
|
-
defs.ExchangeDeclareOk);
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
C.deleteExchange = function(name, options) {
|
|
137
|
-
return this.rpc(defs.ExchangeDelete,
|
|
138
|
-
Args.deleteExchange(name, options),
|
|
139
|
-
defs.ExchangeDeleteOk);
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
C.bindExchange = function(dest, source, pattern, argt) {
|
|
143
|
-
return this.rpc(defs.ExchangeBind,
|
|
144
|
-
Args.bindExchange(dest, source, pattern, argt),
|
|
145
|
-
defs.ExchangeBindOk);
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
C.unbindExchange = function(dest, source, pattern, argt) {
|
|
149
|
-
return this.rpc(defs.ExchangeUnbind,
|
|
150
|
-
Args.unbindExchange(dest, source, pattern, argt),
|
|
151
|
-
defs.ExchangeUnbindOk);
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
// Working with messages
|
|
155
|
-
|
|
156
|
-
C.publish = function(exchange, routingKey, content, options) {
|
|
157
|
-
var fieldsAndProps = Args.publish(exchange, routingKey, options);
|
|
158
|
-
return this.sendMessage(fieldsAndProps, fieldsAndProps, content);
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
C.sendToQueue = function(queue, content, options) {
|
|
162
|
-
return this.publish('', queue, content, options);
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
C.consume = function(queue, callback, options) {
|
|
166
|
-
var self = this;
|
|
167
|
-
// NB we want the callback to be run synchronously, so that we've
|
|
168
|
-
// registered the consumerTag before any messages can arrive.
|
|
169
|
-
var fields = Args.consume(queue, options);
|
|
170
|
-
return Promise.fromCallback(function(cb) {
|
|
171
|
-
self._rpc(defs.BasicConsume, fields, defs.BasicConsumeOk, cb);
|
|
172
|
-
})
|
|
173
|
-
.then(function(ok) {
|
|
174
|
-
self.registerConsumer(ok.fields.consumerTag, callback);
|
|
175
|
-
return ok.fields;
|
|
176
|
-
});
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
C.cancel = function(consumerTag) {
|
|
180
|
-
var self = this;
|
|
181
|
-
return Promise.fromCallback(function(cb) {
|
|
182
|
-
self._rpc(defs.BasicCancel, Args.cancel(consumerTag),
|
|
183
|
-
defs.BasicCancelOk,
|
|
184
|
-
cb);
|
|
185
|
-
})
|
|
186
|
-
.then(function(ok) {
|
|
187
|
-
self.unregisterConsumer(consumerTag);
|
|
188
|
-
return ok.fields;
|
|
189
|
-
});
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
C.get = function(queue, options) {
|
|
193
|
-
var self = this;
|
|
194
|
-
var fields = Args.get(queue, options);
|
|
195
|
-
return Promise.fromCallback(function(cb) {
|
|
196
|
-
return self.sendOrEnqueue(defs.BasicGet, fields, cb);
|
|
197
|
-
})
|
|
198
|
-
.then(function(f) {
|
|
199
|
-
if (f.id === defs.BasicGetEmpty) {
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
else if (f.id === defs.BasicGetOk) {
|
|
203
|
-
var fields = f.fields;
|
|
204
|
-
return new Promise(function(resolve) {
|
|
205
|
-
self.handleMessage = acceptMessage(function(m) {
|
|
206
|
-
m.fields = fields;
|
|
207
|
-
resolve(m);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
get(queue, options) {
|
|
187
|
+
const fields = Args.get(queue, options);
|
|
188
|
+
return Promise.fromCallback(cb => {
|
|
189
|
+
return this.sendOrEnqueue(defs.BasicGet, fields, cb);
|
|
190
|
+
})
|
|
191
|
+
.then(f => {
|
|
192
|
+
if (f.id === defs.BasicGetEmpty) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
else if (f.id === defs.BasicGetOk) {
|
|
196
|
+
const fields = f.fields;
|
|
197
|
+
return new Promise(resolve => {
|
|
198
|
+
this.handleMessage = acceptMessage(m => {
|
|
199
|
+
m.fields = fields;
|
|
200
|
+
resolve(m);
|
|
201
|
+
});
|
|
208
202
|
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
// `Basic.
|
|
240
|
-
//
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
throw new Error(`Unexpected response to BasicGet: ${inspect(f)}`);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
ack(message, allUpTo) {
|
|
211
|
+
this.sendImmediately(
|
|
212
|
+
defs.BasicAck,
|
|
213
|
+
Args.ack(message.fields.deliveryTag, allUpTo));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
ackAll() {
|
|
217
|
+
this.sendImmediately(defs.BasicAck, Args.ack(0, true));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
nack(message, allUpTo, requeue) {
|
|
221
|
+
this.sendImmediately(
|
|
222
|
+
defs.BasicNack,
|
|
223
|
+
Args.nack(message.fields.deliveryTag, allUpTo, requeue));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
nackAll(requeue) {
|
|
227
|
+
this.sendImmediately(defs.BasicNack,
|
|
228
|
+
Args.nack(0, true, requeue));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// `Basic.Nack` is not available in older RabbitMQ versions (or in the
|
|
232
|
+
// AMQP specification), so you have to use the one-at-a-time
|
|
233
|
+
// `Basic.Reject`. This is otherwise synonymous with
|
|
234
|
+
// `#nack(message, false, requeue)`.
|
|
235
|
+
reject(message, requeue) {
|
|
236
|
+
this.sendImmediately(
|
|
237
|
+
defs.BasicReject,
|
|
238
|
+
Args.reject(message.fields.deliveryTag, requeue));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
recover() {
|
|
242
|
+
return this.rpc(defs.BasicRecover,
|
|
243
|
+
Args.recover(),
|
|
244
|
+
defs.BasicRecoverOk);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
qos(count, global) {
|
|
248
|
+
return this.rpc(defs.BasicQos,
|
|
249
|
+
Args.prefetch(count, global),
|
|
250
|
+
defs.BasicQosOk);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
248
253
|
|
|
249
254
|
// There are more options in AMQP than exposed here; RabbitMQ only
|
|
250
255
|
// implements prefetch based on message count, and only for individual
|
|
251
256
|
// channels or consumers. RabbitMQ v3.3.0 and after treat prefetch
|
|
252
257
|
// (without `global` set) as per-consumer (for consumers following),
|
|
253
258
|
// and prefetch with `global` set as per-channel.
|
|
254
|
-
|
|
255
|
-
return this.rpc(defs.BasicQos,
|
|
256
|
-
Args.prefetch(count, global),
|
|
257
|
-
defs.BasicQosOk);
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
C.recover = function() {
|
|
261
|
-
return this.rpc(defs.BasicRecover,
|
|
262
|
-
Args.recover(),
|
|
263
|
-
defs.BasicRecoverOk);
|
|
264
|
-
};
|
|
259
|
+
Channel.prototype.prefetch = Channel.prototype.qos
|
|
265
260
|
|
|
266
261
|
// Confirm channel. This is a channel with confirms 'switched on',
|
|
267
262
|
// meaning sent messages will provoke a responding 'ack' or 'nack'
|
|
@@ -270,49 +265,35 @@ C.recover = function() {
|
|
|
270
265
|
// with `null` as its argument to signify 'ack', or an exception as
|
|
271
266
|
// its argument to signify 'nack'.
|
|
272
267
|
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
class ConfirmChannel extends Channel {
|
|
269
|
+
publish(exchange, routingKey, content, options, cb) {
|
|
270
|
+
this.pushConfirmCallback(cb);
|
|
271
|
+
return Channel.prototype.publish.call(this, exchange, routingKey, content, options);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
sendToQueue(queue, content, options, cb) {
|
|
275
|
+
return this.publish('', queue, content, options, cb);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
waitForConfirms() {
|
|
279
|
+
const awaiting = [];
|
|
280
|
+
const unconfirmed = this.unconfirmed;
|
|
281
|
+
unconfirmed.forEach((val, index) => {
|
|
282
|
+
if (val !== null) {
|
|
283
|
+
const confirmed = new Promise((resolve, reject) => {
|
|
284
|
+
unconfirmed[index] = err => {
|
|
285
|
+
if (val) val(err);
|
|
286
|
+
if (err === null) resolve();
|
|
287
|
+
else reject(err);
|
|
288
|
+
};
|
|
289
|
+
});
|
|
290
|
+
awaiting.push(confirmed);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
return Promise.all(awaiting);
|
|
294
|
+
}
|
|
275
295
|
}
|
|
276
|
-
inherits(ConfirmChannel, Channel);
|
|
277
296
|
|
|
278
297
|
module.exports.ConfirmChannel = ConfirmChannel;
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
var c = new ConfirmChannel(this.connection);
|
|
282
|
-
return c.open()
|
|
283
|
-
.then(function(openOk) {
|
|
284
|
-
return c.rpc(defs.ConfirmSelect, {nowait: false},
|
|
285
|
-
defs.ConfirmSelectOk)
|
|
286
|
-
})
|
|
287
|
-
.then(function() { return c; });
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
var CC = ConfirmChannel.prototype;
|
|
291
|
-
|
|
292
|
-
CC.publish = function(exchange, routingKey, content, options, cb) {
|
|
293
|
-
this.pushConfirmCallback(cb);
|
|
294
|
-
return C.publish.call(this, exchange, routingKey, content, options);
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
CC.sendToQueue = function(queue, content, options, cb) {
|
|
298
|
-
return this.publish('', queue, content, options, cb);
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
CC.waitForConfirms = function() {
|
|
302
|
-
var awaiting = [];
|
|
303
|
-
var unconfirmed = this.unconfirmed;
|
|
304
|
-
unconfirmed.forEach(function(val, index) {
|
|
305
|
-
if (val === null); // already confirmed
|
|
306
|
-
else {
|
|
307
|
-
var confirmed = new Promise(function(resolve, reject) {
|
|
308
|
-
unconfirmed[index] = function(err) {
|
|
309
|
-
if (val) val(err);
|
|
310
|
-
if (err === null) resolve();
|
|
311
|
-
else reject(err);
|
|
312
|
-
};
|
|
313
|
-
});
|
|
314
|
-
awaiting.push(confirmed);
|
|
315
|
-
}
|
|
316
|
-
});
|
|
317
|
-
return Promise.all(awaiting);
|
|
318
|
-
};
|
|
298
|
+
module.exports.Channel = Channel;
|
|
299
|
+
module.exports.ChannelModel = ChannelModel;
|
package/lib/connect.js
CHANGED
|
@@ -152,8 +152,12 @@ function connect(url, socketOptions, openCallback) {
|
|
|
152
152
|
if (timeout) sock.setTimeout(0);
|
|
153
153
|
if (err === null) {
|
|
154
154
|
openCallback(null, c);
|
|
155
|
+
} else {
|
|
156
|
+
// The connection isn't closed by the server on e.g. wrong password
|
|
157
|
+
sock.end();
|
|
158
|
+
sock.destroy();
|
|
159
|
+
openCallback(err);
|
|
155
160
|
}
|
|
156
|
-
else openCallback(err);
|
|
157
161
|
});
|
|
158
162
|
}
|
|
159
163
|
|
package/lib/connection.js
CHANGED
|
@@ -9,7 +9,6 @@ var constants = defs.constants;
|
|
|
9
9
|
var frame = require('./frame');
|
|
10
10
|
var HEARTBEAT = frame.HEARTBEAT;
|
|
11
11
|
var Mux = require('./mux').Mux;
|
|
12
|
-
var Buffer = require('safe-buffer').Buffer
|
|
13
12
|
|
|
14
13
|
var Duplex =
|
|
15
14
|
require('stream').Duplex ||
|
|
@@ -179,8 +178,7 @@ C.open = function(allFields, openCallback0) {
|
|
|
179
178
|
function send(Method) {
|
|
180
179
|
// This can throw an exception if there's some problem with the
|
|
181
180
|
// options; e.g., something is a string instead of a number.
|
|
182
|
-
|
|
183
|
-
catch (err) { bail(err); }
|
|
181
|
+
self.sendMethod(0, Method, tunedOptions);
|
|
184
182
|
}
|
|
185
183
|
|
|
186
184
|
function negotiate(server, desired) {
|
|
@@ -206,7 +204,12 @@ C.open = function(allFields, openCallback0) {
|
|
|
206
204
|
return;
|
|
207
205
|
}
|
|
208
206
|
self.serverProperties = start.fields.serverProperties;
|
|
209
|
-
|
|
207
|
+
try {
|
|
208
|
+
send(defs.ConnectionStartOk);
|
|
209
|
+
} catch (err) {
|
|
210
|
+
bail(err);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
210
213
|
wait(afterStartOk);
|
|
211
214
|
}
|
|
212
215
|
|
|
@@ -228,8 +231,13 @@ C.open = function(allFields, openCallback0) {
|
|
|
228
231
|
negotiate(fields.channelMax, allFields.channelMax);
|
|
229
232
|
tunedOptions.heartbeat =
|
|
230
233
|
negotiate(fields.heartbeat, allFields.heartbeat);
|
|
231
|
-
|
|
232
|
-
|
|
234
|
+
try {
|
|
235
|
+
send(defs.ConnectionTuneOk);
|
|
236
|
+
send(defs.ConnectionOpen);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
bail(err);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
233
241
|
expect(defs.ConnectionOpenOk, onOpenOk);
|
|
234
242
|
break;
|
|
235
243
|
default:
|
package/lib/credentials.js
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
// * PLAIN (send username and password in the plain)
|
|
9
9
|
// * EXTERNAL (assume the server will figure out who you are from
|
|
10
10
|
// context, i.e., your SSL certificate)
|
|
11
|
-
var Buffer = require('safe-buffer').Buffer
|
|
12
11
|
var codec = require('./codec')
|
|
13
12
|
|
|
14
13
|
module.exports.plain = function(user, passwd) {
|
package/lib/defs.js
CHANGED
|
@@ -3059,7 +3059,7 @@ function decodeBasicProperties(buffer) {
|
|
|
3059
3059
|
return fields;
|
|
3060
3060
|
}
|
|
3061
3061
|
|
|
3062
|
-
var
|
|
3062
|
+
var codec = require("./codec"), ints = require("buffer-more-ints"), encodeTable = codec.encodeTable, decodeFields = codec.decodeFields, SCRATCH = Buffer.alloc(65536), EMPTY_OBJECT = Object.freeze({});
|
|
3063
3063
|
|
|
3064
3064
|
module.exports.constants = {
|
|
3065
3065
|
FRAME_METHOD: 1,
|