@autofleet/rabbit 3.3.0-beta.3 → 3.3.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/.nvmrc +1 -1
- package/dist/index.d.ts +35 -13
- package/dist/index.js +485 -119
- package/dist/lib/consts.d.ts +2 -4
- package/dist/lib/consts.js +3 -6
- package/dist/lib/types.d.ts +1 -8
- package/package.json +1 -1
- package/src/index.ts +584 -153
- package/src/lib/consts.ts +2 -5
- package/src/lib/types.ts +2 -9
package/dist/index.js
CHANGED
|
@@ -56,10 +56,57 @@ class RabbitMq {
|
|
|
56
56
|
},
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
constructor(options, redisConfig) {
|
|
59
|
+
constructor(options = {}, redisConfig) {
|
|
60
60
|
this.DISCONNECT_MSG = 'rabbit: connection disconnect';
|
|
61
61
|
this.RECONNECT_MSG = 'rabbit: connection disconnect - reconnecting';
|
|
62
62
|
this.consumers = [];
|
|
63
|
+
this.doesVHostExist = false;
|
|
64
|
+
this.vhost = 'quorum-vhost';
|
|
65
|
+
this.oldConsumers = [];
|
|
66
|
+
this.assertVHost = async () => {
|
|
67
|
+
if (this.doesVHostExist) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const username = process.env.RABBITMQ_USERNAME || 'guest';
|
|
71
|
+
const password = process.env.RABBITMQ_PASSWORD || 'guest';
|
|
72
|
+
const credentials = Buffer.from(`${username}:${password}`).toString('base64');
|
|
73
|
+
const headers = {
|
|
74
|
+
Authorization: `Basic ${credentials}`,
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
};
|
|
77
|
+
const rabbitHost = `http://${(this.options?.rabbitHost || process.env.RABBITMQ_SERVICE_HOST || 'localhost').split(':')[0]}:15672`;
|
|
78
|
+
const url = `${rabbitHost}/api/vhosts/${encodeURIComponent(this.vhost)}`;
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(url, {
|
|
81
|
+
method: 'GET',
|
|
82
|
+
headers,
|
|
83
|
+
});
|
|
84
|
+
if (response.status === 200) {
|
|
85
|
+
this.doesVHostExist = true;
|
|
86
|
+
logger_1.default.info('Vhost exists', { vhost: this.vhost });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (response.status !== 404) {
|
|
90
|
+
logger_1.default.error('Failed to check vhost', { response });
|
|
91
|
+
throw new rabbitError_1.default('Failed to check vhost');
|
|
92
|
+
}
|
|
93
|
+
const createResponse = await fetch(url, {
|
|
94
|
+
method: 'PUT',
|
|
95
|
+
headers,
|
|
96
|
+
body: JSON.stringify({ default_queue_type: 'quorum' }),
|
|
97
|
+
});
|
|
98
|
+
if (!createResponse.ok) {
|
|
99
|
+
logger_1.default.error('Failed to create vhost', { response: createResponse });
|
|
100
|
+
throw new rabbitError_1.default('Failed to create vhost');
|
|
101
|
+
}
|
|
102
|
+
this.doesVHostExist = true;
|
|
103
|
+
logger_1.default.info('Vhost created', { vhost: this.vhost });
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
logger_1.default.error('Failed to check or create vhost', { error });
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
63
110
|
this.shouldConsumeMessageByTimestamp = async (msg) => {
|
|
64
111
|
if (msg) {
|
|
65
112
|
const { properties: { headers } } = msg;
|
|
@@ -117,24 +164,10 @@ class RabbitMq {
|
|
|
117
164
|
}
|
|
118
165
|
};
|
|
119
166
|
this.em = new events_1.EventEmitter();
|
|
120
|
-
this.
|
|
167
|
+
this.channel = null;
|
|
121
168
|
this.publishChannelSetupPromise = null;
|
|
122
|
-
this.
|
|
123
|
-
|
|
124
|
-
connection: null,
|
|
125
|
-
creatingConnection: false,
|
|
126
|
-
connectionCreatedEventName: 'consumeConnectionCreated',
|
|
127
|
-
connectionFailedEventName: 'consumeConnectionFailed',
|
|
128
|
-
blockReconnect: false,
|
|
129
|
-
},
|
|
130
|
-
[consts_1.ConnectionPurpose.Publish]: {
|
|
131
|
-
connection: null,
|
|
132
|
-
creatingConnection: false,
|
|
133
|
-
connectionCreatedEventName: 'publishConnectionCreated',
|
|
134
|
-
connectionFailedEventName: 'publishConnectionFailed',
|
|
135
|
-
blockReconnect: false,
|
|
136
|
-
},
|
|
137
|
-
};
|
|
169
|
+
this.connection = null;
|
|
170
|
+
this.creatingConnection = false;
|
|
138
171
|
this.exchanges = {};
|
|
139
172
|
this.queues = {};
|
|
140
173
|
this.queueSetupPromises = {};
|
|
@@ -155,32 +188,43 @@ class RabbitMq {
|
|
|
155
188
|
await this.gracefulShutdown('SIGINT');
|
|
156
189
|
});
|
|
157
190
|
}
|
|
191
|
+
// TODO: [QUORUM-PHASE-3] Delete the old properties that we use for the old consumers and publishers
|
|
192
|
+
this.oldEm = new events_1.EventEmitter();
|
|
193
|
+
this.oldChannel = null;
|
|
194
|
+
this.oldPublishChannelSetupPromise = null;
|
|
195
|
+
this.oldConnection = null;
|
|
196
|
+
this.oldCreatingConnection = false;
|
|
197
|
+
this.oldExchanges = {};
|
|
198
|
+
this.oldQueues = {};
|
|
199
|
+
this.oldQueueSetupPromises = {};
|
|
200
|
+
this.oldAssertExchangePromises = {};
|
|
201
|
+
this.oldConsumers = [];
|
|
202
|
+
this.oldConsumersTags = [];
|
|
158
203
|
}
|
|
159
|
-
async getConnection(
|
|
204
|
+
async getConnection() {
|
|
160
205
|
return new Promise(async (resolve, reject) => {
|
|
161
|
-
|
|
162
|
-
if (blockReconnect) {
|
|
206
|
+
if (this.blockReconnect) {
|
|
163
207
|
debug('rabbit: block reconnect');
|
|
164
208
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
165
209
|
// @ts-ignore
|
|
166
210
|
return resolve();
|
|
167
211
|
}
|
|
168
|
-
if (connection !== null) {
|
|
169
|
-
if (this.options?.disableReconnect || connection?.isConnected()) {
|
|
212
|
+
if (this.connection !== null) {
|
|
213
|
+
if (this.options?.disableReconnect || this.connection?.isConnected()) {
|
|
170
214
|
debug('rabbit: connection - is connected');
|
|
171
215
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
172
216
|
// @ts-ignore
|
|
173
|
-
return resolve(connection);
|
|
217
|
+
return resolve(this.connection);
|
|
174
218
|
}
|
|
175
219
|
debug('rabbit: connection - reconnecting');
|
|
176
220
|
}
|
|
177
|
-
if (creatingConnection) {
|
|
221
|
+
if (this.creatingConnection) {
|
|
178
222
|
debug('rabbit: creating connection emi');
|
|
179
|
-
this.em.once(
|
|
180
|
-
this.em.once(
|
|
223
|
+
this.em.once(consts_1.CONNECTION_CREATED_CONST, resolve);
|
|
224
|
+
this.em.once(consts_1.CONNECTION_FAILED_CONST, reject);
|
|
181
225
|
return;
|
|
182
226
|
}
|
|
183
|
-
this.
|
|
227
|
+
this.creatingConnection = true;
|
|
184
228
|
let isResolved = false;
|
|
185
229
|
// It is import to use it as a function and not as a variable
|
|
186
230
|
// because of k8s changes the env variables
|
|
@@ -190,62 +234,60 @@ class RabbitMq {
|
|
|
190
234
|
const password = process.env.RABBITMQ_PASSWORD || 'guest';
|
|
191
235
|
const host = this.options?.rabbitHost || process.env.RABBITMQ_SERVICE_HOST || 'localhost';
|
|
192
236
|
debug('rabbit: creating connection', { host, userName, HEARTBEAT });
|
|
193
|
-
return [`amqp://${userName}:${password}@${host}?heartbeat=${HEARTBEAT}`];
|
|
237
|
+
return [`amqp://${userName}:${password}@${host}/${this.vhost}?heartbeat=${HEARTBEAT}`];
|
|
194
238
|
};
|
|
195
239
|
const defaultUrls = findServers();
|
|
196
|
-
const
|
|
240
|
+
const connection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
|
|
197
241
|
findServers,
|
|
198
242
|
});
|
|
199
|
-
this.
|
|
200
|
-
|
|
201
|
-
newConnection.on('error', (err) => {
|
|
243
|
+
this.connection = connection;
|
|
244
|
+
this.connection.on('error', (err) => {
|
|
202
245
|
logger_1.default.error('rabbit: connection error', { err });
|
|
203
246
|
if (!isResolved) {
|
|
204
247
|
isResolved = true;
|
|
205
248
|
reject(err);
|
|
206
|
-
this.em.emit(
|
|
249
|
+
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
207
250
|
}
|
|
208
251
|
});
|
|
209
|
-
|
|
252
|
+
this.connection.on('connectFailed', (err) => {
|
|
210
253
|
this.consumersTags = [];
|
|
211
|
-
logger_1.default.error('rabbit: connection connectFailed', { err });
|
|
254
|
+
logger_1.default.error('rabbit: connection connectFailed', { err, advice: 'Check if the vhost exist', vhost: this.vhost });
|
|
212
255
|
if (!isResolved) {
|
|
213
256
|
isResolved = true;
|
|
214
257
|
reject(err);
|
|
215
|
-
this.em.emit(
|
|
258
|
+
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
216
259
|
}
|
|
217
260
|
});
|
|
218
|
-
|
|
261
|
+
this.connection.on('disconnect', ({ err }) => {
|
|
262
|
+
// this.channel = null;
|
|
219
263
|
this.consumersTags = [];
|
|
220
264
|
debug('rabbit: connection closed');
|
|
221
265
|
if (this.options?.disableReconnect) {
|
|
222
266
|
logger_1.default.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
|
|
223
|
-
this.
|
|
267
|
+
this.blockReconnect = true;
|
|
224
268
|
}
|
|
225
269
|
else {
|
|
226
270
|
logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
227
271
|
}
|
|
228
272
|
});
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
this.
|
|
273
|
+
this.connection.once('connect', async () => {
|
|
274
|
+
debug('rabbit: connection established');
|
|
275
|
+
this.creatingConnection = false;
|
|
276
|
+
this.em.emit(consts_1.CONNECTION_CREATED_CONST, connection);
|
|
232
277
|
isResolved = true;
|
|
233
|
-
resolve(
|
|
278
|
+
resolve(connection);
|
|
234
279
|
});
|
|
235
280
|
});
|
|
236
281
|
}
|
|
237
|
-
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}
|
|
282
|
+
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
|
|
238
283
|
let connection;
|
|
239
284
|
try {
|
|
240
|
-
connection = await this.getConnection(
|
|
285
|
+
connection = await this.getConnection();
|
|
241
286
|
}
|
|
242
287
|
catch (e) {
|
|
243
288
|
logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
244
289
|
throw e;
|
|
245
290
|
}
|
|
246
|
-
if (!connection) {
|
|
247
|
-
throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
|
|
248
|
-
}
|
|
249
291
|
const channel = connection.createChannel({ ...options });
|
|
250
292
|
(0, events_1.once)(channel, 'close').then((args) => {
|
|
251
293
|
logger_1.default.error(`rabbit: channel ${name} closed`);
|
|
@@ -261,22 +303,18 @@ class RabbitMq {
|
|
|
261
303
|
throw err;
|
|
262
304
|
}
|
|
263
305
|
}
|
|
264
|
-
async assertChannel({ force = false
|
|
265
|
-
debug('rabbit: start assert channel', { connectionPurpose, publishPromise: this.publishChannelSetupPromise, channel: this.publishChannel });
|
|
306
|
+
async assertChannel({ force = false } = {}) {
|
|
266
307
|
if (!this.publishChannelSetupPromise) {
|
|
267
308
|
this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
|
|
268
|
-
if (this.
|
|
269
|
-
return resolve(this.
|
|
309
|
+
if (this.channel && !force) {
|
|
310
|
+
return resolve(this.channel);
|
|
270
311
|
}
|
|
271
312
|
try {
|
|
272
|
-
const channel = await this.getNewChannel({
|
|
273
|
-
debug('rabbit: new channel got', { connectionPurpose, channel: this.publishChannel });
|
|
313
|
+
const channel = await this.getNewChannel({});
|
|
274
314
|
channel.on('error', (err) => {
|
|
275
315
|
logger_1.default.error('rabbit: channel error', { err });
|
|
276
316
|
});
|
|
277
|
-
|
|
278
|
-
this.publishChannel = channel;
|
|
279
|
-
}
|
|
317
|
+
this.channel = channel;
|
|
280
318
|
resolve(channel);
|
|
281
319
|
}
|
|
282
320
|
catch (e) {
|
|
@@ -286,8 +324,8 @@ class RabbitMq {
|
|
|
286
324
|
}
|
|
287
325
|
return this.publishChannelSetupPromise;
|
|
288
326
|
}
|
|
289
|
-
async assertExchange(exchangeName, options
|
|
290
|
-
const channel = await this.assertChannel(
|
|
327
|
+
async assertExchange(exchangeName, options) {
|
|
328
|
+
const channel = await this.assertChannel();
|
|
291
329
|
if (this.exchanges[exchangeName]) {
|
|
292
330
|
delete this.assertExchangePromises[exchangeName];
|
|
293
331
|
return this.exchanges[exchangeName];
|
|
@@ -299,46 +337,47 @@ class RabbitMq {
|
|
|
299
337
|
this.exchanges[exchangeName] = await this.assertExchangePromises[exchangeName];
|
|
300
338
|
return this.exchanges[exchangeName];
|
|
301
339
|
}
|
|
302
|
-
|
|
340
|
+
// TODO: [QUORUM-PHASE-2] Change the implementation to the new one
|
|
341
|
+
async getQueueLength(queue) {
|
|
303
342
|
RabbitMq.validateName('queue', queue);
|
|
304
|
-
const {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
throw new Error('channel is not defined');
|
|
343
|
+
const { oldChannel: channel } = this;
|
|
344
|
+
if (!channel) {
|
|
345
|
+
throw new rabbitError_1.default('channel is not defined');
|
|
308
346
|
}
|
|
309
|
-
debug('rabbit: getting queue length', { queue, connected: connection?.isConnected() });
|
|
310
|
-
return
|
|
347
|
+
debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
|
|
348
|
+
return channel?.checkQueue(queue);
|
|
311
349
|
}
|
|
312
|
-
async deleteQueue(queue
|
|
350
|
+
async deleteQueue(queue) {
|
|
313
351
|
RabbitMq.validateName('queue', queue);
|
|
314
|
-
const channel = await this.assertChannel(
|
|
352
|
+
const channel = await this.assertChannel();
|
|
315
353
|
logger_1.default.info('rabbit: deleting queue', { queue });
|
|
316
354
|
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
317
355
|
debug('queue deleted', deleteQueueRes);
|
|
318
356
|
return deleteQueueRes;
|
|
319
357
|
}
|
|
358
|
+
// TODO: [QUORUM-PHASE-2] Change the implementation to the new one
|
|
320
359
|
async bindQueue(queue, exchange) {
|
|
321
|
-
const channel = await this.
|
|
360
|
+
const channel = await this.assertChannelOld();
|
|
322
361
|
await channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
|
|
323
362
|
return channel.bindQueue(queue, exchange, '');
|
|
324
363
|
}
|
|
325
364
|
async setupQueue(queueName, options) {
|
|
326
365
|
let queue;
|
|
327
|
-
const connectionPurpose = consts_1.ConnectionPurpose.Publish;
|
|
328
|
-
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
329
366
|
const localeOptions = {
|
|
330
367
|
...options,
|
|
331
368
|
durable: true,
|
|
332
369
|
arguments: {
|
|
333
370
|
...options?.arguments,
|
|
334
371
|
'x-consumer-timeout': 1000 * 60 * 60 * 24,
|
|
335
|
-
'x-queue-type':
|
|
372
|
+
'x-queue-type': 'quorum',
|
|
336
373
|
},
|
|
337
374
|
};
|
|
338
375
|
try {
|
|
339
|
-
const channel = await this.assertChannel(
|
|
376
|
+
const channel = await this.assertChannel();
|
|
340
377
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
341
|
-
await channel.addSetup((setupChannel) =>
|
|
378
|
+
await channel.addSetup(async (setupChannel) => {
|
|
379
|
+
await setupChannel.assertQueue(queueName, localeOptions);
|
|
380
|
+
});
|
|
342
381
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
343
382
|
queue = await channel.assertQueue(queueName, localeOptions);
|
|
344
383
|
}
|
|
@@ -346,8 +385,8 @@ class RabbitMq {
|
|
|
346
385
|
logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
347
386
|
if (!this.options?.dontRetryAssert) {
|
|
348
387
|
debug('retrying assertQueue', { queueName });
|
|
349
|
-
const channel = await this.assertChannel({ force: true
|
|
350
|
-
await this.deleteQueue(queueName
|
|
388
|
+
const channel = await this.assertChannel({ force: true });
|
|
389
|
+
await this.deleteQueue(queueName);
|
|
351
390
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
352
391
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
353
392
|
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
@@ -360,6 +399,7 @@ class RabbitMq {
|
|
|
360
399
|
this.queues[queueName] = queue;
|
|
361
400
|
return queue;
|
|
362
401
|
}
|
|
402
|
+
// TODO: [QUORUM-PHASE-3] Can be deleted after deleting the old consumers and publishers because all the queues are created us quorum queues
|
|
363
403
|
static shouldUseQuorum(queueName) {
|
|
364
404
|
const envQuorumQueuesWhitelist = process.env.QUORUM_QUEUES_WHITELIST;
|
|
365
405
|
if (envQuorumQueuesWhitelist === '*') {
|
|
@@ -372,7 +412,6 @@ class RabbitMq {
|
|
|
372
412
|
return false;
|
|
373
413
|
}
|
|
374
414
|
async assertQueue(queueName, options) {
|
|
375
|
-
debug('rabbit: start assert queue', { queueName });
|
|
376
415
|
RabbitMq.validateName('queue', queueName);
|
|
377
416
|
if (this.queues[queueName]) {
|
|
378
417
|
delete this.queueSetupPromises[queueName];
|
|
@@ -382,7 +421,6 @@ class RabbitMq {
|
|
|
382
421
|
return this.queueSetupPromises[queueName];
|
|
383
422
|
}
|
|
384
423
|
this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
|
|
385
|
-
debug('rabbit: done assert queue', { queueName });
|
|
386
424
|
return this.queueSetupPromises[queueName];
|
|
387
425
|
}
|
|
388
426
|
saveConsumer(queue, callback, options) {
|
|
@@ -396,9 +434,23 @@ class RabbitMq {
|
|
|
396
434
|
});
|
|
397
435
|
}
|
|
398
436
|
}
|
|
437
|
+
// Used by the microservices to consume messages from the queue
|
|
399
438
|
async consume(queue, callback, options) {
|
|
439
|
+
// TODO: [QUORUM-PHASE-3] Use only the implementation of consumeNew and delete consumeNew and consumeOld
|
|
440
|
+
if (options?.isQuorumQueue !== false) {
|
|
441
|
+
await this.assertVHost();
|
|
442
|
+
await this.consumeNew(queue, callback, options);
|
|
443
|
+
}
|
|
444
|
+
await this.consumeOld(queue, callback, options);
|
|
445
|
+
}
|
|
446
|
+
// TODO: [QUORUM-PHASE-3] Delete consumeNew we do not use it anymore
|
|
447
|
+
async consumeNew(queue, callback, options) {
|
|
400
448
|
await this.consumeFromRabbit(queue, callback, options);
|
|
401
449
|
}
|
|
450
|
+
// TODO: [QUORUM-PHASE-3] Delete consumeOld we do not use it anymore
|
|
451
|
+
async consumeOld(queue, callback, options) {
|
|
452
|
+
await this.consumeFromRabbitOld(queue, callback, options);
|
|
453
|
+
}
|
|
402
454
|
async lockRedisIfNeeded(msg, options) {
|
|
403
455
|
const { properties: { headers } } = msg;
|
|
404
456
|
const timestamp = headers?.creationTimestamp;
|
|
@@ -421,11 +473,11 @@ class RabbitMq {
|
|
|
421
473
|
const { limit, deadMessageTtl, useConsumeWithLock, lockTimeout, auditContext, enableRabbitTrace, } = optionsWithDefaults;
|
|
422
474
|
if (useConsumeWithLock) {
|
|
423
475
|
if (!this.redisLock) {
|
|
424
|
-
throw new
|
|
476
|
+
throw new rabbitError_1.default('Usage of consumeWithLock requires RedisInstance');
|
|
425
477
|
}
|
|
426
478
|
logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
427
479
|
}
|
|
428
|
-
const channel = await this.getNewChannel({
|
|
480
|
+
const channel = await this.getNewChannel({});
|
|
429
481
|
return channel.addSetup(async (confirmChannel) => {
|
|
430
482
|
const q = await this.assertQueue(queue, optionsWithDefaults);
|
|
431
483
|
await confirmChannel.prefetch(limit, false);
|
|
@@ -503,36 +555,57 @@ class RabbitMq {
|
|
|
503
555
|
}
|
|
504
556
|
});
|
|
505
557
|
}
|
|
558
|
+
// Used by the microservices to consume messages from the exchange
|
|
506
559
|
async consumeFromExchange(queue, exchange, callback, options) {
|
|
507
560
|
const optionsWithDefaults = { ...consts_1.DEFAULT_OPTIONS, ...options };
|
|
508
561
|
RabbitMq.validateName('exchange', exchange);
|
|
509
562
|
RabbitMq.validateName('queue', queue);
|
|
510
563
|
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
564
|
+
// TODO: [QUORUM-PHASE-3] Delete the if statement after all the queues are created as quorum queues
|
|
565
|
+
if (options?.isQuorumQueue !== false) {
|
|
566
|
+
await this.assertVHost();
|
|
567
|
+
await this.saveConsumer(queue, callback, options);
|
|
568
|
+
const channel = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
|
|
569
|
+
await channel.addSetup(async (c) => {
|
|
570
|
+
const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
|
|
571
|
+
await c.assertQueue(queue);
|
|
572
|
+
this.exchanges[exchange] = assertExchange;
|
|
573
|
+
await c.prefetch(limit, false);
|
|
574
|
+
return Promise.all([
|
|
575
|
+
c.bindQueue(queue, exchange, ''),
|
|
576
|
+
this.consumeNew(queue, callback, options),
|
|
577
|
+
]);
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
// TODO: [QUORUM-PHASE-3] Delete the old implementation
|
|
581
|
+
await this.saveConsumerOld(queue, callback, options);
|
|
582
|
+
const channelOld = await this.getNewChannelOld({ name: `consume-exchange-${exchange}-queue-${queue}-old` });
|
|
583
|
+
await channelOld.addSetup(async (c) => {
|
|
514
584
|
const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
|
|
515
585
|
await c.assertQueue(queue);
|
|
516
|
-
this.
|
|
586
|
+
this.oldExchanges[exchange] = assertExchange;
|
|
517
587
|
await c.prefetch(limit, false);
|
|
518
588
|
return Promise.all([
|
|
519
589
|
c.bindQueue(queue, exchange, ''),
|
|
520
|
-
this.
|
|
590
|
+
this.consumeOld(queue, callback, options),
|
|
521
591
|
]);
|
|
522
592
|
});
|
|
523
593
|
}
|
|
594
|
+
// Used by the microservices to publish messages to the exchange
|
|
595
|
+
// TODO: [QUORUM-PHASE-2] Change the implementation to the new one
|
|
524
596
|
async publish(exchange, content, customHeaders) {
|
|
525
|
-
debug('rabbit: start publish msg');
|
|
526
597
|
return (0, utils_1.wrapSetImmediate)(async () => {
|
|
527
598
|
RabbitMq.validateName('exchange', exchange);
|
|
528
|
-
const channel = await this.
|
|
529
|
-
await this.
|
|
599
|
+
const channel = await this.assertChannelOld();
|
|
600
|
+
await this.assertExchangeOld(exchange);
|
|
530
601
|
await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
531
602
|
});
|
|
532
603
|
}
|
|
604
|
+
// Used by the microservices to send messages to the queue
|
|
605
|
+
// TODO: [QUORUM-PHASE-2] Change the implementation to the new one
|
|
533
606
|
async sendToQueue(queue, content, options, customHeaders) {
|
|
534
607
|
try {
|
|
535
|
-
await this.
|
|
608
|
+
await this.assertChannelOld();
|
|
536
609
|
}
|
|
537
610
|
catch (e) {
|
|
538
611
|
logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
@@ -540,56 +613,55 @@ class RabbitMq {
|
|
|
540
613
|
}
|
|
541
614
|
try {
|
|
542
615
|
RabbitMq.validateName('queue', queue);
|
|
543
|
-
await this.
|
|
616
|
+
await this.assertQueueOld(queue, options);
|
|
544
617
|
}
|
|
545
618
|
catch (e) {
|
|
546
619
|
logger_1.default.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
|
|
547
620
|
throw e;
|
|
548
621
|
}
|
|
549
622
|
try {
|
|
550
|
-
const res = await this.
|
|
623
|
+
const res = await this.oldChannel?.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
551
624
|
debug(`rabbit: sending to queue ${queue}`, { res });
|
|
552
625
|
return res;
|
|
553
626
|
}
|
|
554
627
|
catch (e) {
|
|
555
|
-
|
|
628
|
+
const isConnected = await this.isConnected();
|
|
629
|
+
logger_1.default.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
|
|
556
630
|
throw e;
|
|
557
631
|
}
|
|
558
632
|
}
|
|
633
|
+
// TODO: [QUORUM-PHASE-2] After changing the publish from old to new change from the old to the new implementation
|
|
559
634
|
async isConnected() {
|
|
560
|
-
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
logger_1.default.info('rabbit: isConnected - true', { connectionPurpose });
|
|
582
|
-
return true;
|
|
583
|
-
}));
|
|
584
|
-
return isEachConnectionConnected.every((isConnected) => isConnected === true);
|
|
635
|
+
const connection = await this.getConnectionOld();
|
|
636
|
+
const isConnected = connection.isConnected();
|
|
637
|
+
if (!isConnected) {
|
|
638
|
+
logger_1.default.error('rabbit: isConnected - false');
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
const channel = await this.assertChannelOld();
|
|
642
|
+
try {
|
|
643
|
+
await Promise.all([
|
|
644
|
+
channel.waitForConnect(),
|
|
645
|
+
...this.oldConsumers.map((c) => channel.checkQueue(c.queue)),
|
|
646
|
+
]);
|
|
647
|
+
}
|
|
648
|
+
catch (e) {
|
|
649
|
+
logger_1.default.error('rabbit: isConnected - false');
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
logger_1.default.info('rabbit: isConnected - true');
|
|
653
|
+
return true;
|
|
585
654
|
}
|
|
586
655
|
async gracefulShutdown(signal) {
|
|
587
|
-
|
|
656
|
+
// TODO: [QUORUM-PHASE-2] After changing the publish from old to new change from the old to the new implementation
|
|
657
|
+
const tagsNumber = this.consumersTags.length + this.oldConsumersTags.length;
|
|
588
658
|
logger_1.default.info(`rabbit: [gracefully-shutdown] received ${signal}! canceling #${tagsNumber} tags...`);
|
|
589
659
|
const cancelTagPromises = this.consumersTags.map(([channel, tag]) => channel.cancel(tag));
|
|
660
|
+
const cancelTagPromisesOld = this.oldConsumersTags.map(([channel, tag]) => channel.cancel(tag));
|
|
590
661
|
// Clean the array to avoid race
|
|
591
662
|
this.consumersTags = [];
|
|
592
|
-
|
|
663
|
+
this.oldConsumersTags = [];
|
|
664
|
+
const results = await Promise.allSettled([...cancelTagPromises, ...cancelTagPromisesOld]);
|
|
593
665
|
const rejected = results.filter((p) => p.status === 'rejected');
|
|
594
666
|
if (rejected.length > 0) {
|
|
595
667
|
logger_1.default.warn(`rabbit: [gracefully-shutdown] #${rejected.length}/${tagsNumber} tags failed to cancel: ${rejected}`);
|
|
@@ -598,6 +670,300 @@ class RabbitMq {
|
|
|
598
670
|
logger_1.default.info('rabbit: [gracefully-shutdown] all tags successfully canceled.');
|
|
599
671
|
}
|
|
600
672
|
}
|
|
673
|
+
async consumeFromRabbitOld(queue, callback, options) {
|
|
674
|
+
const optionsWithDefaults = { ...consts_1.DEFAULT_OPTIONS, ...options };
|
|
675
|
+
RabbitMq.validateName('queue', queue);
|
|
676
|
+
this.saveConsumerOld(queue, callback, options);
|
|
677
|
+
const uniqueId = (0, node_crypto_1.randomUUID)();
|
|
678
|
+
const { limit, deadMessageTtl, useConsumeWithLock, lockTimeout, auditContext, enableRabbitTrace, } = optionsWithDefaults;
|
|
679
|
+
if (useConsumeWithLock) {
|
|
680
|
+
if (!this.redisLock) {
|
|
681
|
+
throw new rabbitError_1.default('Usage of consumeWithLock requires RedisInstance');
|
|
682
|
+
}
|
|
683
|
+
logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
684
|
+
}
|
|
685
|
+
const channel = await this.getNewChannelOld({});
|
|
686
|
+
return channel.addSetup(async (confirmChannel) => {
|
|
687
|
+
const q = await this.assertQueueOld(queue, optionsWithDefaults);
|
|
688
|
+
await confirmChannel.prefetch(limit, false);
|
|
689
|
+
const { consumerTag } = await confirmChannel.consume(queue, async (msg) => {
|
|
690
|
+
if (!msg) {
|
|
691
|
+
return null;
|
|
692
|
+
}
|
|
693
|
+
const traceId = msg.properties.headers[consts_1.TRACING_HEADER];
|
|
694
|
+
const userId = msg.properties.headers[consts_1.USER_TRACING_HEADER];
|
|
695
|
+
const automationId = msg.properties.headers[consts_1.AUTOMATION_ID_HEADER];
|
|
696
|
+
const parsedMessage = RabbitMq.parseMsg(msg);
|
|
697
|
+
const releaseLock = await this.lockRedisIfNeeded(parsedMessage, optionsWithDefaults);
|
|
698
|
+
const trace = (0, zehut_1.newTrace)(zehut_1.traceTypes.RABBIT);
|
|
699
|
+
// setting also outbreak trace as part of legacy code
|
|
700
|
+
const outbreakTrace = zehut_1.outbreak.newTrace(zehut_1.traceTypes.RABBIT);
|
|
701
|
+
// enableRabbitTrace is a flag to protect from different flows that doesn't work with permission
|
|
702
|
+
// and we don't want to fail the flow because of it
|
|
703
|
+
if (userId && enableRabbitTrace) {
|
|
704
|
+
try {
|
|
705
|
+
await Promise.all([
|
|
706
|
+
(0, zehut_1.createOrSetRabbitTrace)(trace, userId),
|
|
707
|
+
(0, zehut_1.createOrSetRabbitTrace)(outbreakTrace, userId),
|
|
708
|
+
]);
|
|
709
|
+
}
|
|
710
|
+
catch (e) {
|
|
711
|
+
logger_1.default.error('rabbit: failed to setRabbitTrace', { userId, e });
|
|
712
|
+
return this.nack(confirmChannel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock)(msg);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
if (traceId) {
|
|
716
|
+
trace?.context?.set(consts_1.TRACING_HEADER, traceId);
|
|
717
|
+
outbreakTrace?.context.set(consts_1.TRACING_HEADER, traceId);
|
|
718
|
+
}
|
|
719
|
+
if (auditContext) {
|
|
720
|
+
await auditContext(queue, {
|
|
721
|
+
userId,
|
|
722
|
+
automationId,
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
const shouldConsume = await this.shouldConsumeMessageByTimestamp(parsedMessage);
|
|
726
|
+
if (!shouldConsume) {
|
|
727
|
+
await this.unlockRedisIfNeeded(releaseLock);
|
|
728
|
+
return this.ack(confirmChannel, msg)(msg);
|
|
729
|
+
}
|
|
730
|
+
let messageAcked = false;
|
|
731
|
+
// setting the localAck function to be used in the callback
|
|
732
|
+
const localAck = async () => {
|
|
733
|
+
if (messageAcked) {
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
messageAcked = true;
|
|
737
|
+
return this.ack(confirmChannel, msg, true, releaseLock)(msg);
|
|
738
|
+
};
|
|
739
|
+
const localNack = async (_, nackOptions = {}) => {
|
|
740
|
+
if (messageAcked) {
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
debug('rabbit localNack', { messageAcked, uniqueId, deliveryTag: msg.fields.deliveryTag });
|
|
744
|
+
messageAcked = true;
|
|
745
|
+
return this.nack(confirmChannel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock)(msg, nackOptions);
|
|
746
|
+
};
|
|
747
|
+
try {
|
|
748
|
+
await callback(parsedMessage, localAck, localNack);
|
|
749
|
+
}
|
|
750
|
+
catch (e) {
|
|
751
|
+
await localNack(msg);
|
|
752
|
+
}
|
|
753
|
+
}, types_1.CONSUMER_DEFAULT_OPTIONS);
|
|
754
|
+
if (!consumerTag) {
|
|
755
|
+
logger_1.default.error(`rabbit: failed to consume from queue ${queue}`);
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
logger_1.default.info(`rabbit: adding tag ${consumerTag} to the array.`);
|
|
759
|
+
this.oldConsumersTags.push([confirmChannel, consumerTag]);
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
// TODO: [QUORUM-PHASE-3] Delete all the function under this line (getNewChannelOld, getConnectionOld, assertQueueOld, setupQueueOld, saveConsumerOld)
|
|
764
|
+
async getNewChannelOld({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
|
|
765
|
+
let connection;
|
|
766
|
+
try {
|
|
767
|
+
connection = await this.getConnectionOld();
|
|
768
|
+
}
|
|
769
|
+
catch (e) {
|
|
770
|
+
logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
771
|
+
throw e;
|
|
772
|
+
}
|
|
773
|
+
const channel = connection.createChannel({ ...options });
|
|
774
|
+
(0, events_1.once)(channel, 'close').then((args) => {
|
|
775
|
+
logger_1.default.error(`rabbit: channel ${name} closed`);
|
|
776
|
+
onClose?.(args);
|
|
777
|
+
});
|
|
778
|
+
try {
|
|
779
|
+
await (0, events_1.once)(channel, 'connect');
|
|
780
|
+
debug(`rabbit: channel ${name} CONNECTED`);
|
|
781
|
+
return channel;
|
|
782
|
+
}
|
|
783
|
+
catch (err) {
|
|
784
|
+
logger_1.default.error(`rabbit: channel error ${name} error`, { err });
|
|
785
|
+
throw err;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
async getConnectionOld() {
|
|
789
|
+
return new Promise(async (resolve, reject) => {
|
|
790
|
+
if (this.oldBlockReconnect) {
|
|
791
|
+
debug('rabbit: block reconnect');
|
|
792
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
793
|
+
// @ts-ignore
|
|
794
|
+
return resolve();
|
|
795
|
+
}
|
|
796
|
+
if (this.oldConnection !== null) {
|
|
797
|
+
if (this.options?.disableReconnect || this.oldConnection?.isConnected()) {
|
|
798
|
+
debug('rabbit: connection - is connected');
|
|
799
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
800
|
+
// @ts-ignore
|
|
801
|
+
return resolve(this.oldConnection);
|
|
802
|
+
}
|
|
803
|
+
debug('rabbit: connection - reconnecting');
|
|
804
|
+
}
|
|
805
|
+
if (this.oldCreatingConnection) {
|
|
806
|
+
debug('rabbit: creating connection emi');
|
|
807
|
+
this.oldEm.once(consts_1.CONNECTION_CREATED_CONST, resolve);
|
|
808
|
+
this.oldEm.once(consts_1.CONNECTION_FAILED_CONST, reject);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
this.oldCreatingConnection = true;
|
|
812
|
+
let isResolved = false;
|
|
813
|
+
// It is import to use it as a function and not as a variable
|
|
814
|
+
// because of k8s changes the env variables
|
|
815
|
+
// and we want to use the new values
|
|
816
|
+
const findServers = () => {
|
|
817
|
+
const userName = process.env.RABBITMQ_USERNAME || 'guest';
|
|
818
|
+
const password = process.env.RABBITMQ_PASSWORD || 'guest';
|
|
819
|
+
const host = this.options?.rabbitHost || process.env.RABBITMQ_SERVICE_HOST || 'localhost';
|
|
820
|
+
debug('rabbit: creating connection', { host, userName, HEARTBEAT });
|
|
821
|
+
return [`amqp://${userName}:${password}@${host}?heartbeat=${HEARTBEAT}`];
|
|
822
|
+
};
|
|
823
|
+
const defaultUrls = findServers();
|
|
824
|
+
const connection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
|
|
825
|
+
findServers,
|
|
826
|
+
});
|
|
827
|
+
this.oldConnection = connection;
|
|
828
|
+
this.oldConnection.on('error', (err) => {
|
|
829
|
+
logger_1.default.error('rabbit: connection error', { err });
|
|
830
|
+
if (!isResolved) {
|
|
831
|
+
isResolved = true;
|
|
832
|
+
reject(err);
|
|
833
|
+
this.oldEm.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
this.oldConnection.on('connectFailed', (err) => {
|
|
837
|
+
this.oldConsumersTags = [];
|
|
838
|
+
logger_1.default.error('rabbit: connection connectFailed', { err });
|
|
839
|
+
if (!isResolved) {
|
|
840
|
+
isResolved = true;
|
|
841
|
+
reject(err);
|
|
842
|
+
this.oldEm.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
this.oldConnection.on('disconnect', ({ err }) => {
|
|
846
|
+
this.oldConsumersTags = [];
|
|
847
|
+
debug('rabbit: connection closed');
|
|
848
|
+
if (this.options?.disableReconnect) {
|
|
849
|
+
logger_1.default.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
|
|
850
|
+
this.oldBlockReconnect = true;
|
|
851
|
+
}
|
|
852
|
+
else {
|
|
853
|
+
logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
this.oldConnection.once('connect', async () => {
|
|
857
|
+
debug('rabbit: connection established');
|
|
858
|
+
this.oldCreatingConnection = false;
|
|
859
|
+
this.oldEm.emit(consts_1.CONNECTION_CREATED_CONST, connection);
|
|
860
|
+
isResolved = true;
|
|
861
|
+
resolve(connection);
|
|
862
|
+
});
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
saveConsumerOld(queue, callback, options) {
|
|
866
|
+
const isConsumerExist = this.oldConsumers.some((consumer) => consumer.queue === queue);
|
|
867
|
+
if (!isConsumerExist) {
|
|
868
|
+
logger_1.default.info(`rabbit: consumer: ${queue} saved in consumer array`);
|
|
869
|
+
this.oldConsumers.push({
|
|
870
|
+
queue,
|
|
871
|
+
callback,
|
|
872
|
+
options,
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
async assertQueueOld(queueName, options) {
|
|
877
|
+
RabbitMq.validateName('queue', queueName);
|
|
878
|
+
if (this.oldQueues[queueName]) {
|
|
879
|
+
delete this.oldQueueSetupPromises[queueName];
|
|
880
|
+
return this.oldQueues[queueName];
|
|
881
|
+
}
|
|
882
|
+
if (this.oldQueueSetupPromises[queueName]) {
|
|
883
|
+
return this.oldQueueSetupPromises[queueName];
|
|
884
|
+
}
|
|
885
|
+
this.oldQueueSetupPromises[queueName] = this.setupQueueOld(queueName, options);
|
|
886
|
+
return this.oldQueueSetupPromises[queueName];
|
|
887
|
+
}
|
|
888
|
+
async setupQueueOld(queueName, options) {
|
|
889
|
+
let queue;
|
|
890
|
+
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
891
|
+
const localeOptions = {
|
|
892
|
+
...options,
|
|
893
|
+
durable: true,
|
|
894
|
+
arguments: {
|
|
895
|
+
...options?.arguments,
|
|
896
|
+
'x-consumer-timeout': 1000 * 60 * 60 * 24,
|
|
897
|
+
'x-queue-type': shouldUseQuorum ? 'quorum' : 'classic',
|
|
898
|
+
},
|
|
899
|
+
};
|
|
900
|
+
try {
|
|
901
|
+
const channel = await this.assertChannelOld();
|
|
902
|
+
debug('assertQueue->channel.addSetup', { queueName });
|
|
903
|
+
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
904
|
+
debug('assertQueue->channel.assertQueue', { queueName });
|
|
905
|
+
queue = await channel.assertQueue(queueName, localeOptions);
|
|
906
|
+
}
|
|
907
|
+
catch (e) {
|
|
908
|
+
logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
909
|
+
if (!this.options?.dontRetryAssert) {
|
|
910
|
+
debug('retrying assertQueue', { queueName });
|
|
911
|
+
const channel = await this.assertChannelOld({ force: true });
|
|
912
|
+
await this.deleteQueueOld(queueName);
|
|
913
|
+
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
914
|
+
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
915
|
+
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
916
|
+
queue = await channel.assertQueue(queueName, localeOptions);
|
|
917
|
+
}
|
|
918
|
+
else {
|
|
919
|
+
throw e;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
this.oldQueues[queueName] = queue;
|
|
923
|
+
return queue;
|
|
924
|
+
}
|
|
925
|
+
async assertChannelOld({ force = false } = {}) {
|
|
926
|
+
if (!this.oldPublishChannelSetupPromise) {
|
|
927
|
+
this.oldPublishChannelSetupPromise = new Promise(async (resolve, reject) => {
|
|
928
|
+
if (this.oldChannel && !force) {
|
|
929
|
+
return resolve(this.oldChannel);
|
|
930
|
+
}
|
|
931
|
+
try {
|
|
932
|
+
const channel = await this.getNewChannelOld({});
|
|
933
|
+
channel.on('error', (err) => {
|
|
934
|
+
logger_1.default.error('rabbit: channel error', { err });
|
|
935
|
+
});
|
|
936
|
+
this.oldChannel = channel;
|
|
937
|
+
resolve(channel);
|
|
938
|
+
}
|
|
939
|
+
catch (e) {
|
|
940
|
+
reject(e);
|
|
941
|
+
}
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
return this.oldPublishChannelSetupPromise;
|
|
945
|
+
}
|
|
946
|
+
async deleteQueueOld(queue) {
|
|
947
|
+
RabbitMq.validateName('queue', queue);
|
|
948
|
+
const channel = await this.assertChannelOld();
|
|
949
|
+
logger_1.default.info('rabbit: deleting queue', { queue });
|
|
950
|
+
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
951
|
+
debug('queue deleted', deleteQueueRes);
|
|
952
|
+
return deleteQueueRes;
|
|
953
|
+
}
|
|
954
|
+
async assertExchangeOld(exchangeName, options) {
|
|
955
|
+
const channel = await this.assertChannelOld();
|
|
956
|
+
if (this.oldExchanges[exchangeName]) {
|
|
957
|
+
delete this.oldAssertExchangePromises[exchangeName];
|
|
958
|
+
return this.oldExchanges[exchangeName];
|
|
959
|
+
}
|
|
960
|
+
if (this.oldAssertExchangePromises[exchangeName]) {
|
|
961
|
+
return this.oldAssertExchangePromises[exchangeName];
|
|
962
|
+
}
|
|
963
|
+
this.oldAssertExchangePromises[exchangeName] = (0, utils_1.assertExchangeFanout)(channel, exchangeName);
|
|
964
|
+
this.oldExchanges[exchangeName] = await this.oldAssertExchangePromises[exchangeName];
|
|
965
|
+
return this.oldExchanges[exchangeName];
|
|
966
|
+
}
|
|
601
967
|
}
|
|
602
968
|
exports.default = RabbitMq;
|
|
603
969
|
var celery_1 = require("./lib/celery");
|