@autofleet/rabbit 3.2.19-beta.6 → 3.2.19-beta.7
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/dist/index.d.ts +21 -12
- package/dist/index.js +102 -73
- package/dist/lib/types.d.ts +4 -0
- package/dist/lib/types.js +6 -1
- package/package.json +1 -1
- package/src/index.ts +17 -4
- package/src/lib/types.ts +4 -1
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { EventEmitter } from 'events';
|
|
|
3
3
|
import { AmqpConnectionManager, ChannelWrapper, CreateChannelOpts } from 'amqp-connection-manager';
|
|
4
4
|
import { ConfirmChannel, ConsumeMessage, Options, Replies } from 'amqplib';
|
|
5
5
|
import { RedisConfig } from './lib/redis';
|
|
6
|
-
import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary } from './lib/types';
|
|
6
|
+
import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary, ConnectionRole } from './lib/types';
|
|
7
7
|
export interface IAfRabbitMq {
|
|
8
8
|
ack: any;
|
|
9
9
|
nack: any;
|
|
@@ -37,10 +37,12 @@ type newChannelOpts = {
|
|
|
37
37
|
name?: string;
|
|
38
38
|
onClose?: null | ((args: any | null) => void);
|
|
39
39
|
options?: CreateChannelOpts | undefined;
|
|
40
|
+
connectionRole: ConnectionRole;
|
|
40
41
|
};
|
|
41
42
|
type assertChannelOpts = {
|
|
42
43
|
channelName?: string;
|
|
43
44
|
force?: boolean;
|
|
45
|
+
connectionRole: ConnectionRole;
|
|
44
46
|
};
|
|
45
47
|
declare class RabbitMq implements IAfRabbitMq {
|
|
46
48
|
static parseMsg(msg: any): any;
|
|
@@ -58,10 +60,13 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
58
60
|
DISCONNECT_MSG: string;
|
|
59
61
|
RECONNECT_MSG: string;
|
|
60
62
|
channel: ChannelWrapper | null;
|
|
63
|
+
publishChannelSetupPromise: Promise<ChannelWrapper> | null;
|
|
61
64
|
blockReconnect: boolean | null | undefined;
|
|
62
|
-
|
|
65
|
+
consumeConnection: AmqpConnectionManager | null | undefined;
|
|
66
|
+
publishConnection: AmqpConnectionManager | null | undefined;
|
|
63
67
|
em: EventEmitter;
|
|
64
|
-
|
|
68
|
+
creatingConsumeConnection: boolean;
|
|
69
|
+
creatingPublishConnection: boolean;
|
|
65
70
|
exchanges: ExchangesCache;
|
|
66
71
|
queues: QueuesCache;
|
|
67
72
|
queueSetupPromises: QueueSetupPromisesDictionary;
|
|
@@ -75,15 +80,19 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
75
80
|
private shouldConsumeMessageByTimestamp;
|
|
76
81
|
ack: (channel: ConfirmChannel, msg: ConsumeMessageOrNull, shouldUpdateRedisTimestamp?: boolean, releaseLock?: null) => (userMsg: ConsumeMessage) => Promise<any>;
|
|
77
82
|
nack: (channel: ConfirmChannel, queue: string, options: any, deadQueueOptions: Options.AssertQueue, msg: ConsumeMessageOrNull, releaseLock: any) => (userMsg: ConsumeMessageOrNull, { skipRetry, }?: NackOptions) => Promise<any>;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
geConnectionByRole: (connectionRole: ConnectionRole) => {
|
|
84
|
+
connectionByRole: AmqpConnectionManager | null | undefined;
|
|
85
|
+
creatingConnectionByRole: boolean;
|
|
86
|
+
};
|
|
87
|
+
getConnection(connectionRole: ConnectionRole): Promise<AmqpConnectionManager | null | undefined>;
|
|
88
|
+
getNewChannel({ name, onClose, options, connectionRole, }?: newChannelOpts): Promise<ChannelWrapper>;
|
|
89
|
+
assertChannel({ force, connectionRole }?: assertChannelOpts): Promise<ChannelWrapper>;
|
|
81
90
|
assertExchange(exchangeName: string, options?: any): Promise<any>;
|
|
82
|
-
getQueueLength(queue: string): Promise<Replies.AssertQueue>;
|
|
91
|
+
getQueueLength(queue: string, connectionRole?: ConnectionRole): Promise<Replies.AssertQueue>;
|
|
83
92
|
private deleteQueue;
|
|
84
|
-
bindQueue(queue: string, exchange: string): Promise<void>;
|
|
85
|
-
setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
|
|
86
|
-
assertQueue(queueName: string, options?: Options.AssertQueue): Promise<any>;
|
|
93
|
+
bindQueue(queue: string, exchange: string, connectionRole: ConnectionRole): Promise<void>;
|
|
94
|
+
setupQueue(queueName: string, connectionRole: ConnectionRole, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
|
|
95
|
+
assertQueue(queueName: string, connectionRole: ConnectionRole, options?: Options.AssertQueue): Promise<any>;
|
|
87
96
|
private saveConsumer;
|
|
88
97
|
consume(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
|
|
89
98
|
private lockRedisIfNeeded;
|
|
@@ -91,8 +100,8 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
91
100
|
private consumeFromRabbit;
|
|
92
101
|
consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
|
|
93
102
|
publish(exchange: string, content: any, customHeaders?: any): Promise<boolean>;
|
|
94
|
-
sendToQueue(queue: string, content: any, options?: any, customHeaders?: any
|
|
95
|
-
isConnected(): Promise<boolean>;
|
|
103
|
+
sendToQueue(queue: string, content: any, options?: any, customHeaders?: any): Promise<boolean | undefined>;
|
|
104
|
+
isConnected(connectionRole: ConnectionRole): Promise<boolean>;
|
|
96
105
|
gracefulShutdown(signal: string): Promise<void>;
|
|
97
106
|
}
|
|
98
107
|
export default RabbitMq;
|
package/dist/index.js
CHANGED
|
@@ -115,10 +115,16 @@ class RabbitMq {
|
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
117
|
};
|
|
118
|
+
this.geConnectionByRole = (connectionRole) => (connectionRole === types_1.ConnectionRole.Consumer
|
|
119
|
+
? { connectionByRole: this.consumeConnection, creatingConnectionByRole: this.creatingConsumeConnection }
|
|
120
|
+
: { connectionByRole: this.publishConnection, creatingConnectionByRole: this.creatingPublishConnection });
|
|
118
121
|
this.em = new events_1.EventEmitter();
|
|
119
122
|
this.channel = null;
|
|
120
|
-
this.
|
|
121
|
-
this.
|
|
123
|
+
this.publishChannelSetupPromise = null;
|
|
124
|
+
this.consumeConnection = null;
|
|
125
|
+
this.publishConnection = null;
|
|
126
|
+
this.creatingPublishConnection = false;
|
|
127
|
+
this.creatingConsumeConnection = false;
|
|
122
128
|
this.exchanges = {};
|
|
123
129
|
this.queues = {};
|
|
124
130
|
this.queueSetupPromises = {};
|
|
@@ -139,30 +145,31 @@ class RabbitMq {
|
|
|
139
145
|
});
|
|
140
146
|
}
|
|
141
147
|
}
|
|
142
|
-
async getConnection() {
|
|
148
|
+
async getConnection(connectionRole) {
|
|
143
149
|
return new Promise(async (resolve, reject) => {
|
|
150
|
+
let { connectionByRole, creatingConnectionByRole } = this.geConnectionByRole(connectionRole);
|
|
144
151
|
if (this.blockReconnect) {
|
|
145
152
|
debug('rabbit: block reconnect');
|
|
146
153
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
147
154
|
// @ts-ignore
|
|
148
155
|
return resolve();
|
|
149
156
|
}
|
|
150
|
-
if (
|
|
151
|
-
if (this.options?.disableReconnect ||
|
|
157
|
+
if (connectionByRole !== null) {
|
|
158
|
+
if (this.options?.disableReconnect || connectionByRole?.isConnected()) {
|
|
152
159
|
debug('rabbit: connection - is connected');
|
|
153
160
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
154
161
|
// @ts-ignore
|
|
155
|
-
return resolve(
|
|
162
|
+
return resolve(connectionByRole);
|
|
156
163
|
}
|
|
157
164
|
debug('rabbit: connection - reconnecting');
|
|
158
165
|
}
|
|
159
|
-
if (
|
|
166
|
+
if (creatingConnectionByRole) {
|
|
160
167
|
debug('rabbit: creating connection emi');
|
|
161
168
|
this.em.once(consts_1.CONNECTION_CREATED_CONST, resolve);
|
|
162
169
|
this.em.once(consts_1.CONNECTION_FAILED_CONST, reject);
|
|
163
170
|
return;
|
|
164
171
|
}
|
|
165
|
-
|
|
172
|
+
creatingConnectionByRole = true;
|
|
166
173
|
let isResolved = false;
|
|
167
174
|
// It is import to use it as a function and not as a variable
|
|
168
175
|
// because of k8s changes the env variables
|
|
@@ -175,11 +182,15 @@ class RabbitMq {
|
|
|
175
182
|
return [`amqp://${userName}:${password}@${host}?heartbeat=${HEARTBEAT}`];
|
|
176
183
|
};
|
|
177
184
|
const defaultUrls = findServers();
|
|
178
|
-
const
|
|
185
|
+
const newConnection = await (0, amqp_connection_manager_1.connect)(defaultUrls, {
|
|
179
186
|
findServers,
|
|
180
187
|
});
|
|
181
|
-
|
|
182
|
-
|
|
188
|
+
if (!newConnection) {
|
|
189
|
+
logger_1.default.error('rabbit: couldnt create a connection');
|
|
190
|
+
return resolve(connectionByRole);
|
|
191
|
+
}
|
|
192
|
+
connectionByRole = newConnection;
|
|
193
|
+
connectionByRole.on('error', (err) => {
|
|
183
194
|
logger_1.default.error('rabbit: connection error', { err });
|
|
184
195
|
if (!isResolved) {
|
|
185
196
|
isResolved = true;
|
|
@@ -187,7 +198,7 @@ class RabbitMq {
|
|
|
187
198
|
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
188
199
|
}
|
|
189
200
|
});
|
|
190
|
-
|
|
201
|
+
connectionByRole.on('connectFailed', (err) => {
|
|
191
202
|
this.consumersTags = [];
|
|
192
203
|
logger_1.default.error('rabbit: connection connectFailed', { err });
|
|
193
204
|
if (!isResolved) {
|
|
@@ -196,7 +207,7 @@ class RabbitMq {
|
|
|
196
207
|
this.em.emit(consts_1.CONNECTION_FAILED_CONST, err);
|
|
197
208
|
}
|
|
198
209
|
});
|
|
199
|
-
|
|
210
|
+
connectionByRole.on('disconnect', ({ err }) => {
|
|
200
211
|
this.consumersTags = [];
|
|
201
212
|
debug('rabbit: connection closed');
|
|
202
213
|
if (this.options?.disableReconnect) {
|
|
@@ -207,24 +218,27 @@ class RabbitMq {
|
|
|
207
218
|
logger_1.default.error(`${this.RECONNECT_MSG}${err && ` - ${err}`}`);
|
|
208
219
|
}
|
|
209
220
|
});
|
|
210
|
-
|
|
221
|
+
connectionByRole.once('connect', async () => {
|
|
211
222
|
debug('rabbit: connection established');
|
|
212
|
-
|
|
213
|
-
this.em.emit(consts_1.CONNECTION_CREATED_CONST,
|
|
223
|
+
creatingConnectionByRole = false;
|
|
224
|
+
this.em.emit(consts_1.CONNECTION_CREATED_CONST, connectionByRole);
|
|
214
225
|
isResolved = true;
|
|
215
|
-
resolve(
|
|
226
|
+
resolve(connectionByRole);
|
|
216
227
|
});
|
|
217
228
|
});
|
|
218
229
|
}
|
|
219
|
-
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {} } = {}) {
|
|
230
|
+
async getNewChannel({ name = (0, utils_1.rand)().toString(), onClose = null, options = {}, connectionRole, } = { connectionRole: types_1.ConnectionRole.Consumer }) {
|
|
220
231
|
let connection;
|
|
221
232
|
try {
|
|
222
|
-
connection = await this.getConnection();
|
|
233
|
+
connection = await this.getConnection(connectionRole);
|
|
223
234
|
}
|
|
224
235
|
catch (e) {
|
|
225
236
|
logger_1.default.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
226
237
|
throw e;
|
|
227
238
|
}
|
|
239
|
+
if (!connection) {
|
|
240
|
+
throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
|
|
241
|
+
}
|
|
228
242
|
const channel = connection.createChannel({ ...options });
|
|
229
243
|
(0, events_1.once)(channel, 'close').then((args) => {
|
|
230
244
|
logger_1.default.error(`rabbit: channel ${name} closed`);
|
|
@@ -240,26 +254,29 @@ class RabbitMq {
|
|
|
240
254
|
throw err;
|
|
241
255
|
}
|
|
242
256
|
}
|
|
243
|
-
async assertChannel({ force = false } = {}) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
257
|
+
async assertChannel({ force = false, connectionRole } = { connectionRole: types_1.ConnectionRole.Consumer }) {
|
|
258
|
+
if (!this.publishChannelSetupPromise) {
|
|
259
|
+
this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
|
|
260
|
+
if (this.channel && !force) {
|
|
261
|
+
return resolve(this.channel);
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
const channel = await this.getNewChannel({ connectionRole });
|
|
265
|
+
channel.on('error', (err) => {
|
|
266
|
+
logger_1.default.error('rabbit: channel error', { err });
|
|
267
|
+
});
|
|
268
|
+
this.channel = channel;
|
|
269
|
+
resolve(channel);
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
reject(e);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return this.publishChannelSetupPromise;
|
|
260
277
|
}
|
|
261
278
|
async assertExchange(exchangeName, options) {
|
|
262
|
-
const channel = await this.assertChannel();
|
|
279
|
+
const channel = await this.assertChannel({ connectionRole: options.connectionRole });
|
|
263
280
|
if (this.exchanges[exchangeName]) {
|
|
264
281
|
return this.exchanges[exchangeName];
|
|
265
282
|
}
|
|
@@ -267,32 +284,33 @@ class RabbitMq {
|
|
|
267
284
|
this.exchanges[exchangeName] = exchange;
|
|
268
285
|
return exchange;
|
|
269
286
|
}
|
|
270
|
-
async getQueueLength(queue) {
|
|
287
|
+
async getQueueLength(queue, connectionRole = types_1.ConnectionRole.Consumer) {
|
|
271
288
|
RabbitMq.validateName('queue', queue);
|
|
289
|
+
const { connectionByRole } = this.geConnectionByRole(connectionRole);
|
|
272
290
|
const { channel } = this;
|
|
273
291
|
if (!channel) {
|
|
274
292
|
throw new Error('channel is not defined');
|
|
275
293
|
}
|
|
276
|
-
debug('rabbit: getting queue length', { queue, connected:
|
|
294
|
+
debug('rabbit: getting queue length', { queue, connected: connectionByRole?.isConnected() });
|
|
277
295
|
return channel?.checkQueue(queue);
|
|
278
296
|
}
|
|
279
|
-
async deleteQueue(queue) {
|
|
297
|
+
async deleteQueue(queue, connectionRole) {
|
|
280
298
|
RabbitMq.validateName('queue', queue);
|
|
281
|
-
const channel = await this.assertChannel();
|
|
299
|
+
const channel = await this.assertChannel({ connectionRole });
|
|
282
300
|
logger_1.default.info('rabbit: deleting queue', { queue });
|
|
283
301
|
const deleteQueueRes = await channel.deleteQueue(queue);
|
|
284
302
|
debug('queue deleted', deleteQueueRes);
|
|
285
303
|
return deleteQueueRes;
|
|
286
304
|
}
|
|
287
|
-
async bindQueue(queue, exchange) {
|
|
288
|
-
const channel = await this.assertChannel();
|
|
305
|
+
async bindQueue(queue, exchange, connectionRole) {
|
|
306
|
+
const channel = await this.assertChannel({ connectionRole });
|
|
289
307
|
await channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
|
|
290
308
|
return channel.bindQueue(queue, exchange, '');
|
|
291
309
|
}
|
|
292
|
-
async setupQueue(queueName, options) {
|
|
310
|
+
async setupQueue(queueName, connectionRole, options) {
|
|
293
311
|
let queue;
|
|
294
312
|
try {
|
|
295
|
-
const channel = await this.assertChannel();
|
|
313
|
+
const channel = await this.assertChannel({ connectionRole });
|
|
296
314
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
297
315
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
|
|
298
316
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
@@ -302,8 +320,8 @@ class RabbitMq {
|
|
|
302
320
|
logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
303
321
|
if (!this.options?.dontRetryAssert) {
|
|
304
322
|
debug('retrying assertQueue', { queueName });
|
|
305
|
-
const channel = await this.assertChannel({ force: true });
|
|
306
|
-
await this.deleteQueue(queueName);
|
|
323
|
+
const channel = await this.assertChannel({ force: true, connectionRole });
|
|
324
|
+
await this.deleteQueue(queueName, connectionRole);
|
|
307
325
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
308
326
|
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
|
|
309
327
|
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
@@ -316,7 +334,7 @@ class RabbitMq {
|
|
|
316
334
|
this.queues[queueName] = queueName;
|
|
317
335
|
return queue;
|
|
318
336
|
}
|
|
319
|
-
async assertQueue(queueName, options) {
|
|
337
|
+
async assertQueue(queueName, connectionRole, options) {
|
|
320
338
|
RabbitMq.validateName('queue', queueName);
|
|
321
339
|
if (this.queues[queueName]) {
|
|
322
340
|
delete this.queueSetupPromises[queueName];
|
|
@@ -325,7 +343,7 @@ class RabbitMq {
|
|
|
325
343
|
if (this.queueSetupPromises[queueName]) {
|
|
326
344
|
return this.queueSetupPromises[queueName];
|
|
327
345
|
}
|
|
328
|
-
this.queueSetupPromises[queueName] = this.setupQueue(queueName, options);
|
|
346
|
+
this.queueSetupPromises[queueName] = this.setupQueue(queueName, connectionRole, options);
|
|
329
347
|
return this.queueSetupPromises[queueName];
|
|
330
348
|
}
|
|
331
349
|
saveConsumer(queue, callback, options) {
|
|
@@ -368,7 +386,7 @@ class RabbitMq {
|
|
|
368
386
|
}
|
|
369
387
|
logger_1.default.info(`rabbit: Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
|
|
370
388
|
}
|
|
371
|
-
const channel = await this.getNewChannel({});
|
|
389
|
+
const channel = await this.getNewChannel({ connectionRole: types_1.ConnectionRole.Consumer });
|
|
372
390
|
return channel.addSetup(async (confirmChannel) => {
|
|
373
391
|
await confirmChannel.assertQueue(queue, options ? { messageTtl: options.messageTtl } : undefined);
|
|
374
392
|
await confirmChannel.prefetch(limit, true);
|
|
@@ -448,7 +466,7 @@ class RabbitMq {
|
|
|
448
466
|
RabbitMq.validateName('queue', queue);
|
|
449
467
|
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
450
468
|
await this.saveConsumer(queue, callback, options);
|
|
451
|
-
const channel = await this.getNewChannel({ name: `consume-exchange
|
|
469
|
+
const channel = await this.getNewChannel({ name: `consume - exchange - ${exchange} -queue - ${queue}`, connectionRole: types_1.ConnectionRole.Consumer });
|
|
452
470
|
return channel.addSetup(async (c) => {
|
|
453
471
|
const assertExchange = await (0, utils_1.assertExchangeFanout)(c, exchange);
|
|
454
472
|
await c.assertQueue(queue);
|
|
@@ -463,33 +481,44 @@ class RabbitMq {
|
|
|
463
481
|
async publish(exchange, content, customHeaders) {
|
|
464
482
|
return (0, utils_1.wrapSetImmediate)(async () => {
|
|
465
483
|
RabbitMq.validateName('exchange', exchange);
|
|
466
|
-
const channel = await this.assertChannel();
|
|
467
|
-
await this.assertExchange(exchange);
|
|
484
|
+
const channel = await this.assertChannel({ connectionRole: types_1.ConnectionRole.Publisher });
|
|
485
|
+
await this.assertExchange(exchange, { connectionRole: types_1.ConnectionRole.Publisher });
|
|
468
486
|
await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
469
487
|
});
|
|
470
488
|
}
|
|
471
|
-
async sendToQueue(queue, content, options, customHeaders
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
489
|
+
async sendToQueue(queue, content, options, customHeaders) {
|
|
490
|
+
try {
|
|
491
|
+
await this.assertChannel({ connectionRole: types_1.ConnectionRole.Publisher });
|
|
492
|
+
}
|
|
493
|
+
catch (e) {
|
|
494
|
+
logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
495
|
+
throw e;
|
|
496
|
+
}
|
|
497
|
+
try {
|
|
498
|
+
RabbitMq.validateName('queue', queue);
|
|
499
|
+
await this.assertQueue(queue, types_1.ConnectionRole.Publisher, options);
|
|
500
|
+
}
|
|
501
|
+
catch (e) {
|
|
502
|
+
logger_1.default.error(`rabbit sendToQueue: failed to assert queue ${queue}`, { e });
|
|
503
|
+
throw e;
|
|
504
|
+
}
|
|
505
|
+
try {
|
|
506
|
+
const res = await this.channel?.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
507
|
+
debug(`rabbit: sending to queue ${queue}`, { res });
|
|
508
|
+
return res;
|
|
509
|
+
}
|
|
510
|
+
catch (e) {
|
|
511
|
+
const isConnected = await this.isConnected(types_1.ConnectionRole.Publisher);
|
|
512
|
+
logger_1.default.error(`rabbit sendToQueue: failed to send to queue ${queue}, isConnected: ${isConnected}`, { e });
|
|
513
|
+
throw e;
|
|
488
514
|
}
|
|
489
|
-
return (0, utils_1.wrapSetImmediate)(callback);
|
|
490
515
|
}
|
|
491
|
-
async isConnected() {
|
|
492
|
-
const connection = await this.getConnection();
|
|
516
|
+
async isConnected(connectionRole) {
|
|
517
|
+
const connection = await this.getConnection(connectionRole);
|
|
518
|
+
if (!connection) {
|
|
519
|
+
logger_1.default.error('rabbit: isConnected - false');
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
493
522
|
const isConnected = connection.isConnected();
|
|
494
523
|
if (!isConnected) {
|
|
495
524
|
logger_1.default.error('rabbit: isConnected - false');
|
package/dist/lib/types.d.ts
CHANGED
package/dist/lib/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CONSUMER_DEFAULT_OPTIONS = void 0;
|
|
3
|
+
exports.ConnectionRole = exports.CONSUMER_DEFAULT_OPTIONS = void 0;
|
|
4
4
|
const HA_PROMOTE_ON_FAILURE = 'ha-promote-on-failure';
|
|
5
5
|
const HA_PROMOTE_ON_SHUTDOWN = 'ha-promote-on-shutdown';
|
|
6
6
|
exports.CONSUMER_DEFAULT_OPTIONS = {
|
|
@@ -9,3 +9,8 @@ exports.CONSUMER_DEFAULT_OPTIONS = {
|
|
|
9
9
|
[HA_PROMOTE_ON_SHUTDOWN]: 'always',
|
|
10
10
|
},
|
|
11
11
|
};
|
|
12
|
+
var ConnectionRole;
|
|
13
|
+
(function (ConnectionRole) {
|
|
14
|
+
ConnectionRole["Consumer"] = "consumer";
|
|
15
|
+
ConnectionRole["Publisher"] = "publisher";
|
|
16
|
+
})(ConnectionRole = exports.ConnectionRole || (exports.ConnectionRole = {}));
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -283,7 +283,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
283
283
|
: { connectionByRole: this.publishConnection, creatingConnectionByRole: this.creatingPublishConnection });
|
|
284
284
|
|
|
285
285
|
async getConnection(connectionRole: ConnectionRole) {
|
|
286
|
-
return new Promise<AmqpConnectionManager>(async (resolve, reject) => {
|
|
286
|
+
return new Promise<AmqpConnectionManager | undefined | null>(async (resolve, reject) => {
|
|
287
287
|
let { connectionByRole, creatingConnectionByRole } = this.geConnectionByRole(connectionRole);
|
|
288
288
|
if (this.blockReconnect) {
|
|
289
289
|
debug('rabbit: block reconnect');
|
|
@@ -296,7 +296,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
296
296
|
debug('rabbit: connection - is connected');
|
|
297
297
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
298
298
|
// @ts-ignore
|
|
299
|
-
return resolve(
|
|
299
|
+
return resolve(connectionByRole);
|
|
300
300
|
}
|
|
301
301
|
debug('rabbit: connection - reconnecting');
|
|
302
302
|
}
|
|
@@ -327,7 +327,13 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
327
327
|
findServers,
|
|
328
328
|
});
|
|
329
329
|
|
|
330
|
+
if (!newConnection) {
|
|
331
|
+
logger.error('rabbit: couldnt create a connection');
|
|
332
|
+
return resolve(connectionByRole);
|
|
333
|
+
}
|
|
334
|
+
|
|
330
335
|
connectionByRole = newConnection;
|
|
336
|
+
|
|
331
337
|
connectionByRole.on('error', (err) => {
|
|
332
338
|
logger.error('rabbit: connection error', { err });
|
|
333
339
|
if (!isResolved) {
|
|
@@ -370,13 +376,16 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
370
376
|
async getNewChannel({
|
|
371
377
|
name = rand().toString(), onClose = null, options = {}, connectionRole,
|
|
372
378
|
}: newChannelOpts = { connectionRole: ConnectionRole.Consumer }): Promise<ChannelWrapper> {
|
|
373
|
-
let connection!: AmqpConnectionManager;
|
|
379
|
+
let connection!: AmqpConnectionManager | undefined | null;
|
|
374
380
|
try {
|
|
375
381
|
connection = await this.getConnection(connectionRole);
|
|
376
382
|
} catch (e) {
|
|
377
383
|
logger.error(`rabbit: error on get connection for new channel ${name} `, { e });
|
|
378
384
|
throw e;
|
|
379
385
|
}
|
|
386
|
+
if (!connection) {
|
|
387
|
+
throw new Error(`rabbit: couldnt get connection for new channel ${name}`);
|
|
388
|
+
}
|
|
380
389
|
const channel = connection.createChannel({ ...options });
|
|
381
390
|
once(channel, 'close').then((args) => {
|
|
382
391
|
logger.error(`rabbit: channel ${name} closed`);
|
|
@@ -424,7 +433,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
424
433
|
return exchange;
|
|
425
434
|
}
|
|
426
435
|
|
|
427
|
-
async getQueueLength(queue: string, connectionRole: ConnectionRole) {
|
|
436
|
+
async getQueueLength(queue: string, connectionRole: ConnectionRole = ConnectionRole.Consumer): Promise<Replies.AssertQueue> {
|
|
428
437
|
RabbitMq.validateName('queue', queue);
|
|
429
438
|
const { connectionByRole } = this.geConnectionByRole(connectionRole);
|
|
430
439
|
const { channel } = this;
|
|
@@ -700,6 +709,10 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
700
709
|
|
|
701
710
|
async isConnected(connectionRole: ConnectionRole): Promise<boolean> {
|
|
702
711
|
const connection = await this.getConnection(connectionRole);
|
|
712
|
+
if (!connection) {
|
|
713
|
+
logger.error('rabbit: isConnected - false');
|
|
714
|
+
return false;
|
|
715
|
+
}
|
|
703
716
|
const isConnected = connection.isConnected();
|
|
704
717
|
if (!isConnected) {
|
|
705
718
|
logger.error('rabbit: isConnected - false');
|