@autofleet/rabbit 4.0.2-beta.8 → 4.1.0-beta.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/coverage/clover.xml +669 -0
- package/coverage/coverage-final.json +9 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +131 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/src/index.html +131 -0
- package/coverage/lcov-report/src/index.ts.html +3826 -0
- package/coverage/lcov-report/src/lib/celery.ts.html +352 -0
- package/coverage/lcov-report/src/lib/consts.ts.html +142 -0
- package/coverage/lcov-report/src/lib/index.html +191 -0
- package/coverage/lcov-report/src/lib/rabbitError.ts.html +103 -0
- package/coverage/lcov-report/src/lib/redis.ts.html +133 -0
- package/coverage/lcov-report/src/lib/types.ts.html +268 -0
- package/coverage/lcov-report/src/lib/utils.ts.html +142 -0
- package/coverage/lcov-report/src/logger.ts.html +100 -0
- package/coverage/lcov.info +1076 -0
- package/dist/index.d.ts +19 -33
- package/dist/index.js +217 -341
- package/dist/lib/celery.js +0 -1
- package/dist/lib/consts.d.ts +2 -10
- package/dist/lib/consts.js +3 -12
- package/dist/lib/rabbitError.js +0 -1
- package/dist/lib/redis.js +0 -1
- package/dist/lib/types.d.ts +0 -8
- package/dist/lib/types.js +0 -1
- package/dist/lib/utils.d.ts +0 -5
- package/dist/lib/utils.js +1 -9
- package/dist/logger.js +0 -1
- package/dist/{mock/index.d.ts → mock.d.ts} +1 -1
- package/dist/{mock/index.js → mock.js} +1 -2
- package/package.json +16 -23
- package/src/index.ts +243 -417
- package/src/lib/consts.ts +2 -11
- package/src/lib/types.ts +0 -10
- package/src/lib/utils.ts +0 -10
- package/src/{mock/index.ts → mock.ts} +2 -2
- package/tsconfig.json +2 -2
- package/dist/index.js.map +0 -1
- package/dist/lib/celery.js.map +0 -1
- package/dist/lib/consts.js.map +0 -1
- package/dist/lib/rabbitError.js.map +0 -1
- package/dist/lib/redis.js.map +0 -1
- package/dist/lib/types.js.map +0 -1
- package/dist/lib/utils.js.map +0 -1
- package/dist/logger.js.map +0 -1
- package/dist/mock/index.js.map +0 -1
- package/dist/mock/vitest.d.ts +0 -13
- package/dist/mock/vitest.js +0 -18
- package/dist/mock/vitest.js.map +0 -1
- package/src/mock/vitest.ts +0 -24
- package/tsconfig.build.json +0 -5
- package/vitest.config.ts +0 -17
package/dist/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/* eslint-disable no-empty,consistent-return,no-async-promise-executor,@typescript-eslint/no-unused-vars */
|
|
2
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
5
|
};
|
|
5
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
7
|
exports.sendCeleryTaskViaHttp = void 0;
|
|
7
|
-
/* eslint-disable no-empty,consistent-return,no-async-promise-executor,@typescript-eslint/no-unused-vars,no-param-reassign */
|
|
8
8
|
const events_1 = require("events");
|
|
9
9
|
const util_1 = require("util");
|
|
10
10
|
const moment_1 = __importDefault(require("moment"));
|
|
11
11
|
const redis_lock_1 = __importDefault(require("redis-lock"));
|
|
12
12
|
const amqp_connection_manager_1 = require("amqp-connection-manager");
|
|
13
|
-
const exponential_backoff_1 = require("exponential-backoff");
|
|
14
13
|
const zehut_1 = require("@autofleet/zehut");
|
|
15
14
|
const node_crypto_1 = require("node:crypto");
|
|
15
|
+
const axios_1 = __importDefault(require("axios"));
|
|
16
16
|
const logger_1 = __importDefault(require("./logger"));
|
|
17
17
|
const rabbitError_1 = __importDefault(require("./lib/rabbitError"));
|
|
18
18
|
const redis_1 = __importDefault(require("./lib/redis"));
|
|
@@ -22,8 +22,6 @@ const types_1 = require("./lib/types");
|
|
|
22
22
|
// const debug = nodeDebug('af-rabbitmq')
|
|
23
23
|
const debug = logger_1.default.debug.bind(logger_1.default);
|
|
24
24
|
const PUBLISH_TIMEOUT = 1000 * 10;
|
|
25
|
-
// TODO: [QUORUM-PHASE-3] Delete this env var
|
|
26
|
-
const { DISABLE_QUORUM_QUEUES_CONSUME, DISABLE_QUORUM_QUEUES_PUBLISH, } = process.env;
|
|
27
25
|
const HEARTBEAT = '60';
|
|
28
26
|
class RabbitMq {
|
|
29
27
|
static parseMsg(msg) {
|
|
@@ -62,52 +60,49 @@ class RabbitMq {
|
|
|
62
60
|
constructor(options = {}, redisConfig) {
|
|
63
61
|
this.DISCONNECT_MSG = 'rabbit: connection disconnect';
|
|
64
62
|
this.RECONNECT_MSG = 'rabbit: connection disconnect - reconnecting';
|
|
65
|
-
this.
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
68
|
-
this.gracefulShutdownStarted = false;
|
|
69
|
-
this.oldConsumersToRegister = [];
|
|
63
|
+
this.consumers = [];
|
|
64
|
+
this.isVHostExist = false;
|
|
65
|
+
this.oldConsumers = [];
|
|
70
66
|
this.assertVHost = async () => {
|
|
71
|
-
if (this.
|
|
67
|
+
if (this.isVHostExist) {
|
|
72
68
|
return;
|
|
73
69
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
if (!this.options?.vhost) {
|
|
71
|
+
throw new Error('vhost is not defined');
|
|
72
|
+
}
|
|
73
|
+
const { vhost } = this.options;
|
|
74
|
+
const auth = {
|
|
75
|
+
auth: {
|
|
76
|
+
username: process.env.RABBITMQ_USERNAME || 'guest',
|
|
77
|
+
password: process.env.RABBITMQ_PASSWORD || 'guest',
|
|
78
|
+
},
|
|
80
79
|
};
|
|
81
|
-
const rabbitHost = `http://${(this.options
|
|
82
|
-
const url = `${rabbitHost}/api/vhosts/${encodeURIComponent(this.vhost)}`;
|
|
80
|
+
const rabbitHost = `http://${(this.options.rabbitHost || process.env.RABBITMQ_SERVICE_HOST || 'localhost').split(':')[0]}:15672`;
|
|
83
81
|
try {
|
|
84
|
-
const response = await
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
});
|
|
88
|
-
if (response.status === 200) {
|
|
89
|
-
this.doesVHostExist = true;
|
|
90
|
-
logger_1.default.info('Vhost exists', { vhost: this.vhost });
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
if (response.status !== 404) {
|
|
94
|
-
logger_1.default.error('Failed to check vhost', { response });
|
|
95
|
-
throw new rabbitError_1.default('Failed to check vhost');
|
|
82
|
+
const response = await axios_1.default.get(`${rabbitHost}/api/vhosts/${encodeURIComponent(vhost)}`, auth);
|
|
83
|
+
if (response.status !== 200) {
|
|
84
|
+
throw new Error('Failed to check vhost');
|
|
96
85
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
headers,
|
|
100
|
-
body: JSON.stringify({ default_queue_type: 'quorum' }),
|
|
101
|
-
});
|
|
102
|
-
if (!createResponse.ok) {
|
|
103
|
-
logger_1.default.error('Failed to create vhost', { response: createResponse });
|
|
104
|
-
throw new rabbitError_1.default('Failed to create vhost');
|
|
105
|
-
}
|
|
106
|
-
this.doesVHostExist = true;
|
|
107
|
-
logger_1.default.info('Vhost created', { vhost: this.vhost });
|
|
86
|
+
this.isVHostExist = true;
|
|
87
|
+
logger_1.default.info('Vhost exists', { vhost });
|
|
108
88
|
}
|
|
109
89
|
catch (error) {
|
|
110
|
-
|
|
90
|
+
// If the vhost does not exist, create it
|
|
91
|
+
if (error instanceof axios_1.default.AxiosError && error.response?.status === 404) {
|
|
92
|
+
try {
|
|
93
|
+
await axios_1.default.put(`${rabbitHost}/api/vhosts/${encodeURIComponent(vhost)}`, {
|
|
94
|
+
default_queue_type: 'quorum',
|
|
95
|
+
}, auth);
|
|
96
|
+
this.isVHostExist = true;
|
|
97
|
+
logger_1.default.info('Vhost created', { vhost: this.options?.vhost });
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
catch (createError) {
|
|
101
|
+
logger_1.default.error('Failed to create vhost', { error: createError });
|
|
102
|
+
throw createError;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
logger_1.default.error('Failed to check vhost', { error });
|
|
111
106
|
throw error;
|
|
112
107
|
}
|
|
113
108
|
};
|
|
@@ -140,11 +135,11 @@ class RabbitMq {
|
|
|
140
135
|
await this.unlockRedisIfNeeded(releaseLock);
|
|
141
136
|
if (channel && msg) {
|
|
142
137
|
if (!skipRetry
|
|
143
|
-
&& (!msg.properties.headers
|
|
138
|
+
&& (!msg.properties.headers[consts_1.RETRY_HEADER]
|
|
144
139
|
|| parseInt(msg.properties.headers[consts_1.RETRY_HEADER], 10) < options.retries)) {
|
|
145
140
|
await this.sendToQueue(queue, RabbitMq.parseMsg(msg).content, options, {
|
|
146
141
|
...msg.properties.headers,
|
|
147
|
-
[consts_1.RETRY_HEADER]: msg.properties.headers
|
|
142
|
+
[consts_1.RETRY_HEADER]: msg.properties.headers[consts_1.RETRY_HEADER]
|
|
148
143
|
? msg.properties.headers[consts_1.RETRY_HEADER] + 1
|
|
149
144
|
: 1,
|
|
150
145
|
});
|
|
@@ -153,7 +148,7 @@ class RabbitMq {
|
|
|
153
148
|
const deadQueue = `${queue}-dead`;
|
|
154
149
|
await this.sendToQueue(deadQueue, RabbitMq.parseMsg(msg).content, deadQueueOptions, {
|
|
155
150
|
...msg.properties.headers,
|
|
156
|
-
[consts_1.RETRY_HEADER]: msg.properties.headers
|
|
151
|
+
[consts_1.RETRY_HEADER]: msg.properties.headers[consts_1.RETRY_HEADER]
|
|
157
152
|
? msg.properties.headers[consts_1.RETRY_HEADER] + 1
|
|
158
153
|
: 1,
|
|
159
154
|
});
|
|
@@ -167,46 +162,25 @@ class RabbitMq {
|
|
|
167
162
|
});
|
|
168
163
|
}
|
|
169
164
|
};
|
|
170
|
-
this.maskURL = (url) => {
|
|
171
|
-
try {
|
|
172
|
-
const urlObj = new URL(url);
|
|
173
|
-
urlObj.username = '***';
|
|
174
|
-
urlObj.password = '***';
|
|
175
|
-
return urlObj.toString();
|
|
176
|
-
}
|
|
177
|
-
catch {
|
|
178
|
-
return url;
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
165
|
this.em = new events_1.EventEmitter();
|
|
182
|
-
this.
|
|
166
|
+
this.channel = null;
|
|
183
167
|
this.publishChannelSetupPromise = null;
|
|
184
|
-
this.
|
|
185
|
-
amqpConnection: null,
|
|
186
|
-
creatingConnection: false,
|
|
187
|
-
connectionCreatedEventName: 'publishConnectionCreated',
|
|
188
|
-
connectionFailedEventName: 'publishConnectionFailed',
|
|
189
|
-
blockReconnect: false,
|
|
190
|
-
};
|
|
191
|
-
this.consumeConnection = {
|
|
192
|
-
amqpConnection: null,
|
|
193
|
-
creatingConnection: false,
|
|
194
|
-
connectionCreatedEventName: 'consumeConnectionCreated',
|
|
195
|
-
connectionFailedEventName: 'consumeConnectionFailed',
|
|
196
|
-
blockReconnect: false,
|
|
197
|
-
};
|
|
168
|
+
this.connection = null;
|
|
198
169
|
this.creatingConnection = false;
|
|
199
170
|
this.exchanges = {};
|
|
200
171
|
this.queues = {};
|
|
201
172
|
this.queueSetupPromises = {};
|
|
202
173
|
this.assertExchangePromises = {};
|
|
203
|
-
this.
|
|
174
|
+
this.consumers = [];
|
|
204
175
|
this.options = options;
|
|
176
|
+
if (!options?.vhost) {
|
|
177
|
+
this.options.vhost = process.env.VHOST_NAME || 'quorum-vhost';
|
|
178
|
+
}
|
|
205
179
|
this.redisClient = redisConfig && (0, redis_1.default)(redisConfig);
|
|
206
180
|
if (this.redisClient) {
|
|
207
181
|
this.redisLock = (0, util_1.promisify)((0, redis_lock_1.default)(this.redisClient));
|
|
208
182
|
}
|
|
209
|
-
this.consumersTags =
|
|
183
|
+
this.consumersTags = [];
|
|
210
184
|
logger_1.default.info(`rabbit: [gracefully-shutdown] adding gracefully shutdown for process.pid ${process.pid}`);
|
|
211
185
|
if (!this.options?.dontGracefulShutdown) {
|
|
212
186
|
process.on('SIGTERM', async () => {
|
|
@@ -216,57 +190,43 @@ class RabbitMq {
|
|
|
216
190
|
await this.gracefulShutdown('SIGINT');
|
|
217
191
|
});
|
|
218
192
|
}
|
|
219
|
-
// TODO:
|
|
193
|
+
// TODO: DELETE OLD PROPERTIES
|
|
220
194
|
this.oldEm = new events_1.EventEmitter();
|
|
221
|
-
this.
|
|
195
|
+
this.oldChannel = null;
|
|
222
196
|
this.oldPublishChannelSetupPromise = null;
|
|
223
|
-
this.
|
|
224
|
-
amqpConnection: null,
|
|
225
|
-
creatingConnection: false,
|
|
226
|
-
connectionCreatedEventName: 'oldPublishConnectionCreated',
|
|
227
|
-
connectionFailedEventName: 'oldPublishConnectionFailed',
|
|
228
|
-
blockReconnect: false,
|
|
229
|
-
};
|
|
230
|
-
this.oldConsumeConnection = {
|
|
231
|
-
amqpConnection: null,
|
|
232
|
-
creatingConnection: false,
|
|
233
|
-
connectionCreatedEventName: 'oldConsumeConnectionCreated',
|
|
234
|
-
connectionFailedEventName: 'oldConsumeConnectionFailed',
|
|
235
|
-
blockReconnect: false,
|
|
236
|
-
};
|
|
197
|
+
this.oldConnection = null;
|
|
237
198
|
this.oldCreatingConnection = false;
|
|
238
199
|
this.oldExchanges = {};
|
|
239
200
|
this.oldQueues = {};
|
|
240
201
|
this.oldQueueSetupPromises = {};
|
|
241
202
|
this.oldAssertExchangePromises = {};
|
|
242
|
-
this.
|
|
243
|
-
this.oldConsumersTags =
|
|
203
|
+
this.oldConsumers = [];
|
|
204
|
+
this.oldConsumersTags = [];
|
|
244
205
|
}
|
|
245
|
-
async getConnection(
|
|
206
|
+
async getConnection() {
|
|
246
207
|
return new Promise(async (resolve, reject) => {
|
|
247
|
-
|
|
248
|
-
if (blockReconnect) {
|
|
208
|
+
if (this.blockReconnect) {
|
|
249
209
|
debug('rabbit: block reconnect');
|
|
250
210
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
251
211
|
// @ts-ignore
|
|
252
212
|
return resolve();
|
|
253
213
|
}
|
|
254
|
-
if (
|
|
255
|
-
if (this.options?.disableReconnect ||
|
|
214
|
+
if (this.connection !== null) {
|
|
215
|
+
if (this.options?.disableReconnect || this.connection?.isConnected()) {
|
|
256
216
|
debug('rabbit: connection - is connected');
|
|
257
217
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
258
218
|
// @ts-ignore
|
|
259
|
-
return resolve(
|
|
219
|
+
return resolve(this.connection);
|
|
260
220
|
}
|
|
261
221
|
debug('rabbit: connection - reconnecting');
|
|
262
222
|
}
|
|
263
|
-
if (creatingConnection) {
|
|
223
|
+
if (this.creatingConnection) {
|
|
264
224
|
debug('rabbit: creating connection emi');
|
|
265
|
-
this.em.once(
|
|
266
|
-
this.em.once(
|
|
225
|
+
this.em.once(consts_1.CONNECTION_CREATED_CONST, resolve);
|
|
226
|
+
this.em.once(consts_1.CONNECTION_FAILED_CONST, reject);
|
|
267
227
|
return;
|
|
268
228
|
}
|
|
269
|
-
|
|
229
|
+
this.creatingConnection = true;
|
|
270
230
|
let isResolved = false;
|
|
271
231
|
// It is import to use it as a function and not as a variable
|
|
272
232
|
// because of k8s changes the env variables
|
|
@@ -276,63 +236,61 @@ class RabbitMq {
|
|
|
276
236
|
const password = process.env.RABBITMQ_PASSWORD || 'guest';
|
|
277
237
|
const host = this.options?.rabbitHost || process.env.RABBITMQ_SERVICE_HOST || 'localhost';
|
|
278
238
|
debug('rabbit: creating connection', { host, userName, HEARTBEAT });
|
|
279
|
-
return [`amqp://${userName}:${password}@${host}/${this.vhost}?heartbeat=${HEARTBEAT}`];
|
|
239
|
+
return [`amqp://${userName}:${password}@${host}/${this.options?.vhost}?heartbeat=${HEARTBEAT}`];
|
|
280
240
|
};
|
|
281
241
|
const defaultUrls = findServers();
|
|
282
|
-
const
|
|
242
|
+
const connection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
|
|
283
243
|
findServers,
|
|
284
244
|
});
|
|
285
|
-
connection
|
|
286
|
-
|
|
245
|
+
this.connection = connection;
|
|
246
|
+
this.connection.on('error', (err) => {
|
|
287
247
|
logger_1.default.error('rabbit: connection error', { err });
|
|
288
248
|
if (!isResolved) {
|
|
289
249
|
isResolved = true;
|
|
290
250
|
reject(err);
|
|
291
|
-
this.em.emit(
|
|
251
|
+
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
292
252
|
}
|
|
293
253
|
});
|
|
294
|
-
|
|
295
|
-
this.consumersTags
|
|
296
|
-
|
|
297
|
-
err.url = this.maskURL(err.url);
|
|
298
|
-
}
|
|
299
|
-
logger_1.default.error('rabbit: connection connectFailed', { err, advice: 'Check if the vhost exist', vhost: this.vhost });
|
|
254
|
+
this.connection.on('connectFailed', (err) => {
|
|
255
|
+
this.consumersTags = [];
|
|
256
|
+
logger_1.default.error('rabbit: connection connectFailed', { err, advice: 'Check if the vhost exist', vhost: this.options?.vhost });
|
|
300
257
|
if (!isResolved) {
|
|
301
258
|
isResolved = true;
|
|
302
259
|
reject(err);
|
|
303
|
-
this.em.emit(
|
|
260
|
+
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
304
261
|
}
|
|
305
262
|
});
|
|
306
|
-
|
|
307
|
-
this.
|
|
263
|
+
this.connection.on('disconnect', ({ err }) => {
|
|
264
|
+
// this.channel = null;
|
|
265
|
+
this.consumersTags = [];
|
|
308
266
|
debug('rabbit: connection closed');
|
|
309
267
|
if (this.options?.disableReconnect) {
|
|
310
268
|
logger_1.default.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
|
|
311
|
-
|
|
269
|
+
this.blockReconnect = true;
|
|
312
270
|
}
|
|
313
271
|
else {
|
|
314
272
|
logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
315
273
|
}
|
|
316
274
|
});
|
|
317
|
-
|
|
275
|
+
this.connection.once('connect', async () => {
|
|
318
276
|
debug('rabbit: connection established');
|
|
319
|
-
|
|
320
|
-
this.em.emit(
|
|
277
|
+
this.creatingConnection = false;
|
|
278
|
+
this.em.emit(consts_1.CONNECTION_CREATED_CONST, connection);
|
|
321
279
|
isResolved = true;
|
|
322
|
-
resolve(
|
|
280
|
+
resolve(connection);
|
|
323
281
|
});
|
|
324
282
|
});
|
|
325
283
|
}
|
|
326
|
-
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}
|
|
327
|
-
let
|
|
284
|
+
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
|
|
285
|
+
let connection;
|
|
328
286
|
try {
|
|
329
|
-
|
|
287
|
+
connection = await this.getConnection();
|
|
330
288
|
}
|
|
331
289
|
catch (e) {
|
|
332
290
|
logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
333
291
|
throw e;
|
|
334
292
|
}
|
|
335
|
-
const channel =
|
|
293
|
+
const channel = connection.createChannel({ ...options });
|
|
336
294
|
(0, events_1.once)(channel, 'close').then((args) => {
|
|
337
295
|
logger_1.default.error(`rabbit: channel ${name} closed`);
|
|
338
296
|
onClose?.(args);
|
|
@@ -347,20 +305,18 @@ class RabbitMq {
|
|
|
347
305
|
throw err;
|
|
348
306
|
}
|
|
349
307
|
}
|
|
350
|
-
async assertChannel({ force = false
|
|
308
|
+
async assertChannel({ force = false } = {}) {
|
|
351
309
|
if (!this.publishChannelSetupPromise) {
|
|
352
310
|
this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
|
|
353
|
-
if (this.
|
|
354
|
-
return resolve(this.
|
|
311
|
+
if (this.channel && !force) {
|
|
312
|
+
return resolve(this.channel);
|
|
355
313
|
}
|
|
356
314
|
try {
|
|
357
|
-
const channel = await this.getNewChannel({
|
|
315
|
+
const channel = await this.getNewChannel({});
|
|
358
316
|
channel.on('error', (err) => {
|
|
359
317
|
logger_1.default.error('rabbit: channel error', { err });
|
|
360
318
|
});
|
|
361
|
-
|
|
362
|
-
this.publishChannel = channel;
|
|
363
|
-
}
|
|
319
|
+
this.channel = channel;
|
|
364
320
|
resolve(channel);
|
|
365
321
|
}
|
|
366
322
|
catch (e) {
|
|
@@ -370,8 +326,8 @@ class RabbitMq {
|
|
|
370
326
|
}
|
|
371
327
|
return this.publishChannelSetupPromise;
|
|
372
328
|
}
|
|
373
|
-
async assertExchange(exchangeName,
|
|
374
|
-
const channel = await this.assertChannel(
|
|
329
|
+
async assertExchange(exchangeName, options) {
|
|
330
|
+
const channel = await this.assertChannel();
|
|
375
331
|
if (this.exchanges[exchangeName]) {
|
|
376
332
|
delete this.assertExchangePromises[exchangeName];
|
|
377
333
|
return this.exchanges[exchangeName];
|
|
@@ -385,29 +341,28 @@ class RabbitMq {
|
|
|
385
341
|
}
|
|
386
342
|
async getQueueLength(queue) {
|
|
387
343
|
RabbitMq.validateName('queue', queue);
|
|
388
|
-
const {
|
|
344
|
+
const { channel } = this;
|
|
389
345
|
if (!channel) {
|
|
390
|
-
throw new
|
|
346
|
+
throw new Error('channel is not defined');
|
|
391
347
|
}
|
|
392
|
-
debug('rabbit: getting queue length', { queue, connected: this.
|
|
348
|
+
debug('rabbit: getting queue length', { queue, connected: this.connection?.isConnected() });
|
|
393
349
|
return channel?.checkQueue(queue);
|
|
394
350
|
}
|
|
395
|
-
async deleteQueue(queue
|
|
351
|
+
async deleteQueue(queue) {
|
|
396
352
|
RabbitMq.validateName('queue', queue);
|
|
397
|
-
const channel = await this.assertChannel(
|
|
353
|
+
const channel = await this.assertChannel();
|
|
398
354
|
logger_1.default.info('rabbit: deleting queue', { queue });
|
|
399
355
|
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
400
356
|
debug('queue deleted', deleteQueueRes);
|
|
401
357
|
return deleteQueueRes;
|
|
402
358
|
}
|
|
403
359
|
async bindQueue(queue, exchange) {
|
|
404
|
-
const channel = await this.assertChannel(
|
|
360
|
+
const channel = await this.assertChannel();
|
|
405
361
|
await channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
|
|
406
362
|
return channel.bindQueue(queue, exchange, '');
|
|
407
363
|
}
|
|
408
364
|
async setupQueue(queueName, options) {
|
|
409
365
|
let queue;
|
|
410
|
-
const connection = this.publishConnection;
|
|
411
366
|
const localeOptions = {
|
|
412
367
|
...options,
|
|
413
368
|
durable: true,
|
|
@@ -418,7 +373,7 @@ class RabbitMq {
|
|
|
418
373
|
},
|
|
419
374
|
};
|
|
420
375
|
try {
|
|
421
|
-
const channel = await this.assertChannel(
|
|
376
|
+
const channel = await this.assertChannel();
|
|
422
377
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
423
378
|
await channel.addSetup(async (setupChannel) => {
|
|
424
379
|
await setupChannel.assertQueue(queueName, localeOptions);
|
|
@@ -430,8 +385,8 @@ class RabbitMq {
|
|
|
430
385
|
logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
431
386
|
if (!this.options?.dontRetryAssert) {
|
|
432
387
|
debug('retrying assertQueue', { queueName });
|
|
433
|
-
const channel = await this.assertChannel({ force: true
|
|
434
|
-
await this.deleteQueue(queueName
|
|
388
|
+
const channel = await this.assertChannel({ force: true });
|
|
389
|
+
await this.deleteQueue(queueName);
|
|
435
390
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
436
391
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
437
392
|
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
@@ -444,7 +399,7 @@ class RabbitMq {
|
|
|
444
399
|
this.queues[queueName] = queue;
|
|
445
400
|
return queue;
|
|
446
401
|
}
|
|
447
|
-
// TODO:
|
|
402
|
+
// TODO: Can be deleted after deleting the old consumers
|
|
448
403
|
static shouldUseQuorum(queueName) {
|
|
449
404
|
const envQuorumQueuesWhitelist = process.env.QUORUM_QUEUES_WHITELIST;
|
|
450
405
|
if (envQuorumQueuesWhitelist === '*') {
|
|
@@ -469,10 +424,10 @@ class RabbitMq {
|
|
|
469
424
|
return this.queueSetupPromises[queueName];
|
|
470
425
|
}
|
|
471
426
|
saveConsumer(queue, callback, options) {
|
|
472
|
-
const isConsumerExist = this.
|
|
427
|
+
const isConsumerExist = this.consumers.some((consumer) => consumer.queue === queue);
|
|
473
428
|
if (!isConsumerExist) {
|
|
474
429
|
logger_1.default.info(`rabbit: consumer: ${queue} saved in consumer array`);
|
|
475
|
-
this.
|
|
430
|
+
this.consumers.push({
|
|
476
431
|
queue,
|
|
477
432
|
callback,
|
|
478
433
|
options,
|
|
@@ -481,21 +436,18 @@ class RabbitMq {
|
|
|
481
436
|
}
|
|
482
437
|
// Used by the microservices to consume messages from the queue
|
|
483
438
|
async consume(queue, callback, options) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
this.saveConsumer(queue, callback, options);
|
|
488
|
-
const backoffConfig = (0, utils_1.getAssertVhostExponentialBackoffConfig)();
|
|
489
|
-
await (0, exponential_backoff_1.backOff)(() => this.assertVHost(), backoffConfig);
|
|
439
|
+
// TODO: USE THE IMPLEMENTATION OF THE NEW CONSUME AND DELETE THE NEW AND OLD
|
|
440
|
+
if (options?.isQuorumQueue !== false) {
|
|
441
|
+
await this.assertVHost();
|
|
490
442
|
await this.consumeNew(queue, callback, options);
|
|
491
443
|
}
|
|
492
444
|
await this.consumeOld(queue, callback, options);
|
|
493
445
|
}
|
|
494
|
-
// TODO:
|
|
446
|
+
// TODO: DELETE
|
|
495
447
|
async consumeNew(queue, callback, options) {
|
|
496
448
|
await this.consumeFromRabbit(queue, callback, options);
|
|
497
449
|
}
|
|
498
|
-
// TODO:
|
|
450
|
+
// TODO: DELETE
|
|
499
451
|
async consumeOld(queue, callback, options) {
|
|
500
452
|
await this.consumeFromRabbitOld(queue, callback, options);
|
|
501
453
|
}
|
|
@@ -516,15 +468,16 @@ class RabbitMq {
|
|
|
516
468
|
async consumeFromRabbit(queue, callback, options) {
|
|
517
469
|
const optionsWithDefaults = { ...consts_1.DEFAULT_OPTIONS, ...options };
|
|
518
470
|
RabbitMq.validateName('queue', queue);
|
|
471
|
+
this.saveConsumer(queue, callback, options);
|
|
519
472
|
const uniqueId = (0, node_crypto_1.randomUUID)();
|
|
520
473
|
const { limit, deadMessageTtl, useConsumeWithLock, lockTimeout, auditContext, enableRabbitTrace, } = optionsWithDefaults;
|
|
521
474
|
if (useConsumeWithLock) {
|
|
522
475
|
if (!this.redisLock) {
|
|
523
|
-
throw new
|
|
476
|
+
throw new Error('Usage of consumeWithLock requires RedisInstance');
|
|
524
477
|
}
|
|
525
478
|
logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
526
479
|
}
|
|
527
|
-
const channel = await this.getNewChannel({
|
|
480
|
+
const channel = await this.getNewChannel({});
|
|
528
481
|
return channel.addSetup(async (confirmChannel) => {
|
|
529
482
|
const q = await this.assertQueue(queue, optionsWithDefaults);
|
|
530
483
|
await confirmChannel.prefetch(limit, false);
|
|
@@ -598,7 +551,7 @@ class RabbitMq {
|
|
|
598
551
|
}
|
|
599
552
|
else {
|
|
600
553
|
logger_1.default.info(`rabbit: adding tag ${consumerTag} to the array.`);
|
|
601
|
-
this.consumersTags.
|
|
554
|
+
this.consumersTags.push([confirmChannel, consumerTag]);
|
|
602
555
|
}
|
|
603
556
|
});
|
|
604
557
|
}
|
|
@@ -608,15 +561,10 @@ class RabbitMq {
|
|
|
608
561
|
RabbitMq.validateName('exchange', exchange);
|
|
609
562
|
RabbitMq.validateName('queue', queue);
|
|
610
563
|
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
611
|
-
|
|
612
|
-
|
|
564
|
+
if (options?.isQuorumQueue !== false) {
|
|
565
|
+
await this.assertVHost();
|
|
613
566
|
await this.saveConsumer(queue, callback, options);
|
|
614
|
-
const
|
|
615
|
-
await (0, exponential_backoff_1.backOff)(() => this.assertVHost(), backoffConfig);
|
|
616
|
-
const channel = await this.getNewChannel({
|
|
617
|
-
name: `consume-exchange-${exchange}-queue-${queue}`,
|
|
618
|
-
connection: this.consumeConnection,
|
|
619
|
-
});
|
|
567
|
+
const channel = await this.getNewChannel({ name: `consume-exchange-${exchange}-queue-${queue}` });
|
|
620
568
|
await channel.addSetup(async (c) => {
|
|
621
569
|
const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
|
|
622
570
|
await c.assertQueue(queue);
|
|
@@ -628,12 +576,9 @@ class RabbitMq {
|
|
|
628
576
|
]);
|
|
629
577
|
});
|
|
630
578
|
}
|
|
631
|
-
// TODO:
|
|
579
|
+
// TODO: DELETE OLD
|
|
632
580
|
await this.saveConsumerOld(queue, callback, options);
|
|
633
|
-
const channelOld = await this.getNewChannelOld({
|
|
634
|
-
name: `consume-exchange-${exchange}-queue-${queue}-old`,
|
|
635
|
-
connection: this.oldConsumeConnection,
|
|
636
|
-
});
|
|
581
|
+
const channelOld = await this.getNewChannelOld({ name: `consume-exchange-${exchange}-queue-${queue}-old` });
|
|
637
582
|
await channelOld.addSetup(async (c) => {
|
|
638
583
|
const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
|
|
639
584
|
await c.assertQueue(queue);
|
|
@@ -646,32 +591,32 @@ class RabbitMq {
|
|
|
646
591
|
});
|
|
647
592
|
}
|
|
648
593
|
// Used by the microservices to publish messages to the exchange
|
|
649
|
-
// TODO: [QUORUM-PHASE-3] isQuorumQueue flag is not needed anymore because all the queues are created as quorum queues
|
|
650
594
|
async publish(exchange, content, customHeaders, isQuorumQueue = true) {
|
|
651
|
-
|
|
595
|
+
// TODO: DELETE THE IF
|
|
596
|
+
if (isQuorumQueue) {
|
|
652
597
|
return (0, utils_1.wrapSetImmediate)(async () => {
|
|
653
598
|
await this.assertVHost();
|
|
654
599
|
RabbitMq.validateName('exchange', exchange);
|
|
655
|
-
const channel = await this.assertChannel(
|
|
656
|
-
await this.assertExchange(exchange
|
|
600
|
+
const channel = await this.assertChannel();
|
|
601
|
+
await this.assertExchange(exchange);
|
|
657
602
|
await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
658
603
|
});
|
|
659
604
|
}
|
|
660
|
-
// TODO:
|
|
605
|
+
// TODO: DELETE THE OLD
|
|
661
606
|
return (0, utils_1.wrapSetImmediate)(async () => {
|
|
662
607
|
RabbitMq.validateName('exchange', exchange);
|
|
663
|
-
const channel = await this.assertChannelOld(
|
|
664
|
-
await this.assertExchangeOld(exchange
|
|
608
|
+
const channel = await this.assertChannelOld();
|
|
609
|
+
await this.assertExchangeOld(exchange);
|
|
665
610
|
await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
666
611
|
});
|
|
667
612
|
}
|
|
668
613
|
// Used by the microservices to send messages to the queue
|
|
669
|
-
// TODO: [QUORUM-PHASE-3] isQuorumQueue flag is not needed anymore because all the queues are created as quorum queues
|
|
670
614
|
async sendToQueue(queue, content, options, customHeaders, isQuorumQueue = true) {
|
|
671
|
-
|
|
615
|
+
// TODO: DELETE THE IF AND THE OLD
|
|
616
|
+
if (isQuorumQueue) {
|
|
672
617
|
try {
|
|
673
618
|
await this.assertVHost();
|
|
674
|
-
await this.assertChannel(
|
|
619
|
+
await this.assertChannel();
|
|
675
620
|
}
|
|
676
621
|
catch (e) {
|
|
677
622
|
logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
@@ -686,7 +631,7 @@ class RabbitMq {
|
|
|
686
631
|
throw e;
|
|
687
632
|
}
|
|
688
633
|
try {
|
|
689
|
-
const res = await this.
|
|
634
|
+
const res = await this.channel?.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
690
635
|
debug(`rabbit: sending to queue ${queue}`, { res });
|
|
691
636
|
return res;
|
|
692
637
|
}
|
|
@@ -698,85 +643,62 @@ class RabbitMq {
|
|
|
698
643
|
}
|
|
699
644
|
else {
|
|
700
645
|
try {
|
|
701
|
-
await this.assertChannelOld(
|
|
646
|
+
await this.assertChannelOld();
|
|
702
647
|
}
|
|
703
648
|
catch (e) {
|
|
704
649
|
logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
705
650
|
throw e;
|
|
706
651
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
652
|
+
}
|
|
653
|
+
try {
|
|
654
|
+
RabbitMq.validateName('queue', queue);
|
|
655
|
+
await this.assertQueueOld(queue, options);
|
|
656
|
+
}
|
|
657
|
+
catch (e) {
|
|
658
|
+
logger_1.default.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
|
|
659
|
+
throw e;
|
|
660
|
+
}
|
|
661
|
+
try {
|
|
662
|
+
const res = await this.oldChannel?.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
663
|
+
debug(`rabbit: sending to queue ${queue}`, { res });
|
|
664
|
+
return res;
|
|
665
|
+
}
|
|
666
|
+
catch (e) {
|
|
667
|
+
const isConnected = await this.isConnected();
|
|
668
|
+
logger_1.default.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
|
|
669
|
+
throw e;
|
|
725
670
|
}
|
|
726
671
|
}
|
|
727
672
|
async isConnected() {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
if (!
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
const doesConsumerExist = this.consumersTags.get(c.queue);
|
|
745
|
-
return !doesConsumerExist;
|
|
746
|
-
});
|
|
747
|
-
if (unRegisteredConsumers.length > 0) {
|
|
748
|
-
const queueNames = unRegisteredConsumers.map((c) => c.queue);
|
|
749
|
-
logger_1.default.error('rabbit: found unregistered consumers for queues', {
|
|
750
|
-
count: queueNames.length,
|
|
751
|
-
queues: queueNames,
|
|
752
|
-
});
|
|
753
|
-
throw new rabbitError_1.default('Found unregistered consumers');
|
|
754
|
-
}
|
|
755
|
-
const channel = await this.assertChannel({ connection: this.publishConnection });
|
|
756
|
-
await channel.waitForConnect();
|
|
757
|
-
await Promise.all(this.consumersToRegister.map((c) => channel.checkQueue(c.queue)));
|
|
758
|
-
}
|
|
759
|
-
catch (e) {
|
|
760
|
-
logger_1.default.error('rabbit: isConnected - false', { msg: e.message });
|
|
761
|
-
return false;
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
// TODO:[QUORUM-PHASE-3] Delete the old is connected and adjust the return value to return true
|
|
765
|
-
isConnected = await this.isConnectedOld();
|
|
673
|
+
const connection = await this.getConnection();
|
|
674
|
+
const isConnected = connection.isConnected();
|
|
675
|
+
if (!isConnected) {
|
|
676
|
+
logger_1.default.error('rabbit: isConnected - false');
|
|
677
|
+
return false;
|
|
678
|
+
}
|
|
679
|
+
const channel = await this.assertChannel();
|
|
680
|
+
try {
|
|
681
|
+
await Promise.all([
|
|
682
|
+
channel.waitForConnect(),
|
|
683
|
+
...this.consumers.map((c) => channel.checkQueue(c.queue)),
|
|
684
|
+
]);
|
|
685
|
+
}
|
|
686
|
+
catch (e) {
|
|
687
|
+
logger_1.default.error('rabbit: isConnected - false');
|
|
688
|
+
return false;
|
|
766
689
|
}
|
|
767
|
-
logger_1.default.
|
|
768
|
-
return
|
|
690
|
+
logger_1.default.info('rabbit: isConnected - true');
|
|
691
|
+
return true;
|
|
769
692
|
}
|
|
770
693
|
async gracefulShutdown(signal) {
|
|
771
|
-
// TODO:
|
|
772
|
-
this.
|
|
773
|
-
const tagsNumber = this.consumersTags.size + this.oldConsumersTags.size;
|
|
694
|
+
// TODO: DELETE OLD
|
|
695
|
+
const tagsNumber = this.consumersTags.length + this.oldConsumersTags.length;
|
|
774
696
|
logger_1.default.info(`rabbit: [gracefully-shutdown] received ${signal}! canceling #${tagsNumber} tags...`);
|
|
775
|
-
const cancelTagPromises =
|
|
776
|
-
const cancelTagPromisesOld =
|
|
697
|
+
const cancelTagPromises = this.consumersTags.map(([channel, tag]) => channel.cancel(tag));
|
|
698
|
+
const cancelTagPromisesOld = this.oldConsumersTags.map(([channel, tag]) => channel.cancel(tag));
|
|
777
699
|
// Clean the array to avoid race
|
|
778
|
-
this.consumersTags
|
|
779
|
-
this.oldConsumersTags
|
|
700
|
+
this.consumersTags = [];
|
|
701
|
+
this.oldConsumersTags = [];
|
|
780
702
|
const results = await Promise.allSettled([...cancelTagPromises, ...cancelTagPromisesOld]);
|
|
781
703
|
const rejected = results.filter((p) => p.status === 'rejected');
|
|
782
704
|
if (rejected.length > 0) {
|
|
@@ -789,15 +711,16 @@ class RabbitMq {
|
|
|
789
711
|
async consumeFromRabbitOld(queue, callback, options) {
|
|
790
712
|
const optionsWithDefaults = { ...consts_1.DEFAULT_OPTIONS, ...options };
|
|
791
713
|
RabbitMq.validateName('queue', queue);
|
|
714
|
+
this.saveConsumerOld(queue, callback, options);
|
|
792
715
|
const uniqueId = (0, node_crypto_1.randomUUID)();
|
|
793
716
|
const { limit, deadMessageTtl, useConsumeWithLock, lockTimeout, auditContext, enableRabbitTrace, } = optionsWithDefaults;
|
|
794
717
|
if (useConsumeWithLock) {
|
|
795
718
|
if (!this.redisLock) {
|
|
796
|
-
throw new
|
|
719
|
+
throw new Error('Usage of consumeWithLock requires RedisInstance');
|
|
797
720
|
}
|
|
798
721
|
logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
799
722
|
}
|
|
800
|
-
const channel = await this.getNewChannelOld({
|
|
723
|
+
const channel = await this.getNewChannelOld({});
|
|
801
724
|
return channel.addSetup(async (confirmChannel) => {
|
|
802
725
|
const q = await this.assertQueueOld(queue, optionsWithDefaults);
|
|
803
726
|
await confirmChannel.prefetch(limit, false);
|
|
@@ -867,28 +790,25 @@ class RabbitMq {
|
|
|
867
790
|
}
|
|
868
791
|
}, types_1.CONSUMER_DEFAULT_OPTIONS);
|
|
869
792
|
if (!consumerTag) {
|
|
870
|
-
logger_1.default.error(`rabbit: failed to consume from queue ${queue}
|
|
793
|
+
logger_1.default.error(`rabbit: failed to consume from queue ${queue}`);
|
|
871
794
|
}
|
|
872
795
|
else {
|
|
873
|
-
logger_1.default.info(`rabbit: adding tag ${consumerTag} to the array
|
|
874
|
-
this.oldConsumersTags.
|
|
796
|
+
logger_1.default.info(`rabbit: adding tag ${consumerTag} to the array.`);
|
|
797
|
+
this.oldConsumersTags.push([confirmChannel, consumerTag]);
|
|
875
798
|
}
|
|
876
799
|
});
|
|
877
800
|
}
|
|
878
|
-
// TODO:
|
|
879
|
-
async getNewChannelOld({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}
|
|
880
|
-
let
|
|
801
|
+
// TODO: DELETE OLD PROPERTIES UNDER THIS LINE
|
|
802
|
+
async getNewChannelOld({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
|
|
803
|
+
let connection;
|
|
881
804
|
try {
|
|
882
|
-
|
|
805
|
+
connection = await this.getConnectionOld();
|
|
883
806
|
}
|
|
884
807
|
catch (e) {
|
|
885
808
|
logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
886
809
|
throw e;
|
|
887
810
|
}
|
|
888
|
-
|
|
889
|
-
throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
|
|
890
|
-
}
|
|
891
|
-
const channel = localConnection?.createChannel({ ...options });
|
|
811
|
+
const channel = connection.createChannel({ ...options });
|
|
892
812
|
(0, events_1.once)(channel, 'close').then((args) => {
|
|
893
813
|
logger_1.default.error(`rabbit: channel ${name} closed`);
|
|
894
814
|
onClose?.(args);
|
|
@@ -903,31 +823,30 @@ class RabbitMq {
|
|
|
903
823
|
throw err;
|
|
904
824
|
}
|
|
905
825
|
}
|
|
906
|
-
async getConnectionOld(
|
|
826
|
+
async getConnectionOld() {
|
|
907
827
|
return new Promise(async (resolve, reject) => {
|
|
908
|
-
|
|
909
|
-
if (blockReconnect) {
|
|
828
|
+
if (this.oldBlockReconnect) {
|
|
910
829
|
debug('rabbit: block reconnect');
|
|
911
830
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
912
831
|
// @ts-ignore
|
|
913
832
|
return resolve();
|
|
914
833
|
}
|
|
915
|
-
if (
|
|
916
|
-
if (this.options?.disableReconnect ||
|
|
834
|
+
if (this.oldConnection !== null) {
|
|
835
|
+
if (this.options?.disableReconnect || this.oldConnection?.isConnected()) {
|
|
917
836
|
debug('rabbit: connection - is connected');
|
|
918
837
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
919
838
|
// @ts-ignore
|
|
920
|
-
return resolve(
|
|
839
|
+
return resolve(this.oldConnection);
|
|
921
840
|
}
|
|
922
841
|
debug('rabbit: connection - reconnecting');
|
|
923
842
|
}
|
|
924
|
-
if (
|
|
843
|
+
if (this.oldCreatingConnection) {
|
|
925
844
|
debug('rabbit: creating connection emi');
|
|
926
|
-
this.oldEm.once(
|
|
927
|
-
this.oldEm.once(
|
|
845
|
+
this.oldEm.once(consts_1.CONNECTION_CREATED_CONST, resolve);
|
|
846
|
+
this.oldEm.once(consts_1.CONNECTION_FAILED_CONST, reject);
|
|
928
847
|
return;
|
|
929
848
|
}
|
|
930
|
-
|
|
849
|
+
this.oldCreatingConnection = true;
|
|
931
850
|
let isResolved = false;
|
|
932
851
|
// It is import to use it as a function and not as a variable
|
|
933
852
|
// because of k8s changes the env variables
|
|
@@ -940,55 +859,52 @@ class RabbitMq {
|
|
|
940
859
|
return [`amqp://${userName}:${password}@${host}?heartbeat=${HEARTBEAT}`];
|
|
941
860
|
};
|
|
942
861
|
const defaultUrls = findServers();
|
|
943
|
-
const
|
|
862
|
+
const connection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
|
|
944
863
|
findServers,
|
|
945
864
|
});
|
|
946
|
-
|
|
947
|
-
|
|
865
|
+
this.oldConnection = connection;
|
|
866
|
+
this.oldConnection.on('error', (err) => {
|
|
948
867
|
logger_1.default.error('rabbit: connection error', { err });
|
|
949
868
|
if (!isResolved) {
|
|
950
869
|
isResolved = true;
|
|
951
870
|
reject(err);
|
|
952
|
-
this.oldEm.emit(
|
|
871
|
+
this.oldEm.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
953
872
|
}
|
|
954
873
|
});
|
|
955
|
-
|
|
956
|
-
this.oldConsumersTags
|
|
957
|
-
if (typeof err.url === 'string') {
|
|
958
|
-
err.url = this.maskURL(err.url);
|
|
959
|
-
}
|
|
874
|
+
this.oldConnection.on('connectFailed', (err) => {
|
|
875
|
+
this.oldConsumersTags = [];
|
|
960
876
|
logger_1.default.error('rabbit: connection connectFailed', { err });
|
|
961
877
|
if (!isResolved) {
|
|
962
878
|
isResolved = true;
|
|
963
879
|
reject(err);
|
|
964
|
-
this.oldEm.emit(
|
|
880
|
+
this.oldEm.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
965
881
|
}
|
|
966
882
|
});
|
|
967
|
-
|
|
968
|
-
this.oldConsumersTags
|
|
883
|
+
this.oldConnection.on('disconnect', ({ err }) => {
|
|
884
|
+
this.oldConsumersTags = [];
|
|
969
885
|
debug('rabbit: connection closed');
|
|
970
886
|
if (this.options?.disableReconnect) {
|
|
971
887
|
logger_1.default.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
|
|
972
|
-
|
|
888
|
+
this.oldBlockReconnect = true;
|
|
973
889
|
}
|
|
974
890
|
else {
|
|
975
891
|
logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
976
892
|
}
|
|
977
893
|
});
|
|
978
|
-
|
|
894
|
+
this.oldConnection.once('connect', async () => {
|
|
979
895
|
debug('rabbit: connection established');
|
|
980
|
-
|
|
981
|
-
this.oldEm.emit(
|
|
896
|
+
this.oldCreatingConnection = false;
|
|
897
|
+
this.oldEm.emit(consts_1.CONNECTION_CREATED_CONST, connection);
|
|
982
898
|
isResolved = true;
|
|
983
|
-
resolve(
|
|
899
|
+
resolve(connection);
|
|
984
900
|
});
|
|
985
901
|
});
|
|
986
902
|
}
|
|
987
903
|
saveConsumerOld(queue, callback, options) {
|
|
988
|
-
const isConsumerExist = this.
|
|
904
|
+
const isConsumerExist = this.oldConsumers.some((consumer) => consumer.queue === queue);
|
|
989
905
|
if (!isConsumerExist) {
|
|
990
906
|
logger_1.default.info(`rabbit: consumer: ${queue} saved in consumer array`);
|
|
991
|
-
this.
|
|
907
|
+
this.oldConsumers.push({
|
|
992
908
|
queue,
|
|
993
909
|
callback,
|
|
994
910
|
options,
|
|
@@ -1009,7 +925,6 @@ class RabbitMq {
|
|
|
1009
925
|
}
|
|
1010
926
|
async setupQueueOld(queueName, options) {
|
|
1011
927
|
let queue;
|
|
1012
|
-
const connection = this.oldPublishConnection;
|
|
1013
928
|
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
1014
929
|
const localeOptions = {
|
|
1015
930
|
...options,
|
|
@@ -1021,7 +936,7 @@ class RabbitMq {
|
|
|
1021
936
|
},
|
|
1022
937
|
};
|
|
1023
938
|
try {
|
|
1024
|
-
const channel = await this.assertChannelOld(
|
|
939
|
+
const channel = await this.assertChannelOld();
|
|
1025
940
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
1026
941
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
1027
942
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
@@ -1031,8 +946,8 @@ class RabbitMq {
|
|
|
1031
946
|
logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
1032
947
|
if (!this.options?.dontRetryAssert) {
|
|
1033
948
|
debug('retrying assertQueue', { queueName });
|
|
1034
|
-
const channel = await this.assertChannelOld({ force: true
|
|
1035
|
-
await this.deleteQueueOld(queueName
|
|
949
|
+
const channel = await this.assertChannelOld({ force: true });
|
|
950
|
+
await this.deleteQueueOld(queueName);
|
|
1036
951
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
1037
952
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
1038
953
|
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
@@ -1045,20 +960,18 @@ class RabbitMq {
|
|
|
1045
960
|
this.oldQueues[queueName] = queue;
|
|
1046
961
|
return queue;
|
|
1047
962
|
}
|
|
1048
|
-
async assertChannelOld({ force = false
|
|
963
|
+
async assertChannelOld({ force = false } = {}) {
|
|
1049
964
|
if (!this.oldPublishChannelSetupPromise) {
|
|
1050
965
|
this.oldPublishChannelSetupPromise = new Promise(async (resolve, reject) => {
|
|
1051
|
-
if (this.
|
|
1052
|
-
return resolve(this.
|
|
966
|
+
if (this.oldChannel && !force) {
|
|
967
|
+
return resolve(this.oldChannel);
|
|
1053
968
|
}
|
|
1054
969
|
try {
|
|
1055
|
-
const channel = await this.getNewChannelOld({
|
|
970
|
+
const channel = await this.getNewChannelOld({});
|
|
1056
971
|
channel.on('error', (err) => {
|
|
1057
972
|
logger_1.default.error('rabbit: channel error', { err });
|
|
1058
973
|
});
|
|
1059
|
-
|
|
1060
|
-
this.oldPublishChannel = channel;
|
|
1061
|
-
}
|
|
974
|
+
this.oldChannel = channel;
|
|
1062
975
|
resolve(channel);
|
|
1063
976
|
}
|
|
1064
977
|
catch (e) {
|
|
@@ -1068,16 +981,16 @@ class RabbitMq {
|
|
|
1068
981
|
}
|
|
1069
982
|
return this.oldPublishChannelSetupPromise;
|
|
1070
983
|
}
|
|
1071
|
-
async deleteQueueOld(queue
|
|
984
|
+
async deleteQueueOld(queue) {
|
|
1072
985
|
RabbitMq.validateName('queue', queue);
|
|
1073
|
-
const channel = await this.assertChannelOld(
|
|
986
|
+
const channel = await this.assertChannelOld();
|
|
1074
987
|
logger_1.default.info('rabbit: deleting queue', { queue });
|
|
1075
988
|
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
1076
989
|
debug('queue deleted', deleteQueueRes);
|
|
1077
990
|
return deleteQueueRes;
|
|
1078
991
|
}
|
|
1079
|
-
async assertExchangeOld(exchangeName,
|
|
1080
|
-
const channel = await this.assertChannelOld(
|
|
992
|
+
async assertExchangeOld(exchangeName, options) {
|
|
993
|
+
const channel = await this.assertChannelOld();
|
|
1081
994
|
if (this.oldExchanges[exchangeName]) {
|
|
1082
995
|
delete this.oldAssertExchangePromises[exchangeName];
|
|
1083
996
|
return this.oldExchanges[exchangeName];
|
|
@@ -1089,44 +1002,7 @@ class RabbitMq {
|
|
|
1089
1002
|
this.oldExchanges[exchangeName] = await this.oldAssertExchangePromises[exchangeName];
|
|
1090
1003
|
return this.oldExchanges[exchangeName];
|
|
1091
1004
|
}
|
|
1092
|
-
async isConnectedOld() {
|
|
1093
|
-
if (!this.gracefulShutdownStarted) {
|
|
1094
|
-
debug('rabbit: start is connected old');
|
|
1095
|
-
const [oldConsumeConnection, oldPublishConnection] = await Promise.all([
|
|
1096
|
-
this.getConnectionOld(this.oldConsumeConnection),
|
|
1097
|
-
this.getConnectionOld(this.oldPublishConnection),
|
|
1098
|
-
]);
|
|
1099
|
-
const isConnected = oldConsumeConnection.isConnected() && oldPublishConnection.isConnected();
|
|
1100
|
-
if (!isConnected) {
|
|
1101
|
-
logger_1.default.error('rabbit: isConnected old - false');
|
|
1102
|
-
return false;
|
|
1103
|
-
}
|
|
1104
|
-
try {
|
|
1105
|
-
const unRegisteredConsumersOld = this.consumersToRegister.filter((c) => {
|
|
1106
|
-
const doesConsumerExist = this.consumersTags.get(c.queue);
|
|
1107
|
-
return !doesConsumerExist;
|
|
1108
|
-
});
|
|
1109
|
-
if (unRegisteredConsumersOld.length > 0) {
|
|
1110
|
-
const queueNames = unRegisteredConsumersOld.map((c) => c.queue);
|
|
1111
|
-
logger_1.default.error('rabbit: found unregistered consumers for queues old', {
|
|
1112
|
-
count: queueNames.length,
|
|
1113
|
-
queues: queueNames,
|
|
1114
|
-
});
|
|
1115
|
-
throw new rabbitError_1.default('Found unregistered consumers old');
|
|
1116
|
-
}
|
|
1117
|
-
const channelOld = await this.assertChannelOld({ connection: this.oldPublishConnection });
|
|
1118
|
-
await channelOld.waitForConnect();
|
|
1119
|
-
await Promise.all(this.oldConsumersToRegister.map((c) => channelOld.checkQueue(c.queue)));
|
|
1120
|
-
}
|
|
1121
|
-
catch (e) {
|
|
1122
|
-
logger_1.default.error('rabbit: isConnected - false old', { msg: e.message });
|
|
1123
|
-
return false;
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
return true;
|
|
1127
|
-
}
|
|
1128
1005
|
}
|
|
1129
1006
|
exports.default = RabbitMq;
|
|
1130
1007
|
var celery_1 = require("./lib/celery");
|
|
1131
1008
|
Object.defineProperty(exports, "sendCeleryTaskViaHttp", { enumerable: true, get: function () { return celery_1.sendCeleryTaskViaHttp; } });
|
|
1132
|
-
//# sourceMappingURL=index.js.map
|