@autofleet/rabbit 1.5.7 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +8 -7
- package/dist/index.js +32 -16
- package/dist/index.test.js +30 -15
- package/package.json +1 -1
- package/src/index.test.ts +34 -15
- package/src/index.ts +39 -21
package/dist/index.d.ts
CHANGED
|
@@ -5,24 +5,25 @@ import { EventEmitter } from 'events';
|
|
|
5
5
|
interface ExchangesCache {
|
|
6
6
|
[key: string]: any;
|
|
7
7
|
}
|
|
8
|
+
export interface AfRabbitOptions {
|
|
9
|
+
reconnect: boolean;
|
|
10
|
+
}
|
|
8
11
|
declare class RabbitMq {
|
|
9
12
|
static parseMsg(msg: any): any;
|
|
10
13
|
static validateName(type: string, name: string): void;
|
|
11
|
-
static consumeOptions(options?: any): {
|
|
12
|
-
limit: number;
|
|
13
|
-
deadMessageTtl: number;
|
|
14
|
-
};
|
|
15
14
|
PUBLISH_TIMEOUT: number;
|
|
16
15
|
PUBLISH_ERROR_MSG: string;
|
|
17
16
|
DISCONNECT_MSG: string;
|
|
17
|
+
RESCONNECT_MSG: string;
|
|
18
18
|
channel: ChannelWrapper | null;
|
|
19
19
|
connection: AmqpConnectionManager | null;
|
|
20
20
|
em: EventEmitter;
|
|
21
21
|
creatingConnection: boolean;
|
|
22
22
|
exchanges: ExchangesCache;
|
|
23
|
-
|
|
23
|
+
options: AfRabbitOptions | undefined;
|
|
24
|
+
constructor(options?: AfRabbitOptions);
|
|
24
25
|
ack: (msg: any) => Promise<void>;
|
|
25
|
-
nack: (queue: string, options
|
|
26
|
+
nack: (queue: string, options: any, deadQueueOptions: Options.AssertQueue) => (msg: any) => Promise<void>;
|
|
26
27
|
getConnection(): Promise<AmqpConnectionManager>;
|
|
27
28
|
assertChannel(): Promise<ChannelWrapper>;
|
|
28
29
|
assertExchange(exchangeName: string, options?: any): Promise<any>;
|
|
@@ -32,6 +33,6 @@ declare class RabbitMq {
|
|
|
32
33
|
consume(queue: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
|
|
33
34
|
consumeFromExchange(queue: string, exchange: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
|
|
34
35
|
publish(exchange: string, content: any): Promise<unknown>;
|
|
35
|
-
sendToQueue(queue: string, content: any): Promise<void>;
|
|
36
|
+
sendToQueue(queue: string, content: any, options?: any): Promise<void>;
|
|
36
37
|
}
|
|
37
38
|
export default RabbitMq;
|
package/dist/index.js
CHANGED
|
@@ -38,28 +38,35 @@ const amqp_connection_manager_1 = require("amqp-connection-manager");
|
|
|
38
38
|
const events_1 = require("events");
|
|
39
39
|
const outbreak_1 = require("@autofleet/outbreak");
|
|
40
40
|
const rabbitError_1 = __importDefault(require("./rabbitError"));
|
|
41
|
+
const DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 48;
|
|
42
|
+
const defaultOptions = {
|
|
43
|
+
limit: 1,
|
|
44
|
+
retries: 1,
|
|
45
|
+
deadMessageTtl: DEFAULT_DEAD_TTL_TWO_DAYS,
|
|
46
|
+
};
|
|
41
47
|
const assertExchangeFanout = (c, exchangeName) => c.assertExchange(exchangeName, 'fanout');
|
|
42
48
|
const connectionCreatedConst = 'connectionCreated';
|
|
43
49
|
class RabbitMq {
|
|
44
|
-
constructor() {
|
|
50
|
+
constructor(options) {
|
|
45
51
|
this.PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
|
|
46
52
|
this.PUBLISH_ERROR_MSG = `rabbit: publish timeout(${this.PUBLISH_TIMEOUT}ms) has pass, exchange: `;
|
|
47
53
|
this.DISCONNECT_MSG = 'rabbit: connection disconnect';
|
|
54
|
+
this.RESCONNECT_MSG = 'rabbit: reconnecting';
|
|
48
55
|
this.ack = (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
49
56
|
if (this.channel) {
|
|
50
57
|
yield this.channel.ack(msg);
|
|
51
58
|
}
|
|
52
59
|
});
|
|
53
|
-
this.nack = (queue, options) => (msg
|
|
60
|
+
this.nack = (queue, options, deadQueueOptions) => (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
54
61
|
if (this.channel) {
|
|
55
|
-
if (!msg.content['x-retry-count'] || msg.content['x-retry-count']
|
|
62
|
+
if (!msg.content['x-retry-count'] || msg.content['x-retry-count'] < options.retries) {
|
|
56
63
|
msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
|
|
57
64
|
yield this.sendToQueue(queue, msg.content);
|
|
58
65
|
}
|
|
59
66
|
else {
|
|
60
67
|
const deadQueue = `${queue}-dead`;
|
|
61
|
-
yield this.assertQueue(deadQueue,
|
|
62
|
-
yield this.sendToQueue(deadQueue, msg.content);
|
|
68
|
+
yield this.assertQueue(deadQueue, deadQueueOptions);
|
|
69
|
+
yield this.sendToQueue(deadQueue, msg.content, deadQueueOptions);
|
|
63
70
|
}
|
|
64
71
|
yield this.channel.ack(msg);
|
|
65
72
|
}
|
|
@@ -69,6 +76,7 @@ class RabbitMq {
|
|
|
69
76
|
this.connection = null;
|
|
70
77
|
this.creatingConnection = false;
|
|
71
78
|
this.exchanges = {};
|
|
79
|
+
this.options = options;
|
|
72
80
|
}
|
|
73
81
|
static parseMsg(msg) {
|
|
74
82
|
let { content } = msg;
|
|
@@ -84,9 +92,6 @@ class RabbitMq {
|
|
|
84
92
|
throw new rabbitError_1.default(`error while using ${type} with no name`);
|
|
85
93
|
}
|
|
86
94
|
}
|
|
87
|
-
static consumeOptions(options) {
|
|
88
|
-
return Object.assign({ limit: 1, deadMessageTtl: null }, options);
|
|
89
|
-
}
|
|
90
95
|
getConnection() {
|
|
91
96
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
97
|
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -101,7 +106,16 @@ class RabbitMq {
|
|
|
101
106
|
const host = process.env.RABBITMQ_SERVICE_HOST || '';
|
|
102
107
|
const connection = yield amqp_connection_manager_1.connect([`amqp://${host}`]);
|
|
103
108
|
this.connection = connection;
|
|
104
|
-
this.connection.on('disconnect', ({ err }) =>
|
|
109
|
+
this.connection.on('disconnect', ({ err }) => {
|
|
110
|
+
var _a;
|
|
111
|
+
if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.reconnect) {
|
|
112
|
+
console.error(`${this.RESCONNECT_MSG}${err && ` - ${err}`}`);
|
|
113
|
+
this.connection = null;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
console.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
105
119
|
this.creatingConnection = false;
|
|
106
120
|
this.em.emit(connectionCreatedConst, connection);
|
|
107
121
|
resolve(connection);
|
|
@@ -164,8 +178,9 @@ class RabbitMq {
|
|
|
164
178
|
}
|
|
165
179
|
consume(queue, callback, options) {
|
|
166
180
|
return __awaiter(this, void 0, void 0, function* () {
|
|
181
|
+
const optionsWithDefaults = Object.assign(Object.assign({}, defaultOptions), options);
|
|
167
182
|
RabbitMq.validateName('queue', queue);
|
|
168
|
-
const { limit, deadMessageTtl } =
|
|
183
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
169
184
|
const channel = yield this.assertChannel();
|
|
170
185
|
return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
|
|
171
186
|
yield c.assertQueue(queue);
|
|
@@ -173,7 +188,7 @@ class RabbitMq {
|
|
|
173
188
|
return Promise.all([
|
|
174
189
|
c.consume(queue, (msg) => {
|
|
175
190
|
outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
|
|
176
|
-
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, { messageTtl: deadMessageTtl }));
|
|
191
|
+
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
177
192
|
}),
|
|
178
193
|
]);
|
|
179
194
|
}));
|
|
@@ -181,9 +196,10 @@ class RabbitMq {
|
|
|
181
196
|
}
|
|
182
197
|
consumeFromExchange(queue, exchange, callback, options) {
|
|
183
198
|
return __awaiter(this, void 0, void 0, function* () {
|
|
184
|
-
|
|
199
|
+
const optionsWithDefaults = Object.assign(Object.assign({}, defaultOptions), options);
|
|
185
200
|
RabbitMq.validateName('exchange', exchange);
|
|
186
|
-
|
|
201
|
+
RabbitMq.validateName('queue', queue);
|
|
202
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
187
203
|
const channel = yield this.assertChannel();
|
|
188
204
|
return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
|
|
189
205
|
const assertExchange = yield assertExchangeFanout(c, exchange);
|
|
@@ -194,7 +210,7 @@ class RabbitMq {
|
|
|
194
210
|
c.bindQueue(queue, exchange, ''),
|
|
195
211
|
c.consume(queue, (msg) => {
|
|
196
212
|
outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
|
|
197
|
-
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, { messageTtl: deadMessageTtl }));
|
|
213
|
+
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
198
214
|
}),
|
|
199
215
|
]);
|
|
200
216
|
}));
|
|
@@ -211,11 +227,11 @@ class RabbitMq {
|
|
|
211
227
|
})).timeout(this.PUBLISH_TIMEOUT, `${this.PUBLISH_ERROR_MSG}${exchange}`);
|
|
212
228
|
});
|
|
213
229
|
}
|
|
214
|
-
sendToQueue(queue, content) {
|
|
230
|
+
sendToQueue(queue, content, options) {
|
|
215
231
|
return __awaiter(this, void 0, void 0, function* () {
|
|
216
232
|
RabbitMq.validateName('queue', queue);
|
|
217
233
|
const channel = yield this.assertChannel();
|
|
218
|
-
yield this.assertQueue(queue);
|
|
234
|
+
yield this.assertQueue(queue, options);
|
|
219
235
|
return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)));
|
|
220
236
|
});
|
|
221
237
|
}
|
package/dist/index.test.js
CHANGED
|
@@ -16,30 +16,48 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
16
16
|
const index_1 = __importDefault(require("./index"));
|
|
17
17
|
jest.setTimeout(120000);
|
|
18
18
|
const rabbit = new index_1.default();
|
|
19
|
-
const delay = () => new Promise((resolve) => setTimeout(() => resolve(),
|
|
19
|
+
const delay = (ms = 500) => new Promise((resolve) => setTimeout(() => resolve(), ms));
|
|
20
|
+
const callback = (eq = 'hey') => (msg, ack) => {
|
|
21
|
+
expect(msg.content).toEqual(eq);
|
|
22
|
+
ack(msg);
|
|
23
|
+
};
|
|
24
|
+
const nackcallback = () => (msg, ack, nack) => {
|
|
25
|
+
console.log('msg', msg.content);
|
|
26
|
+
expect(msg.content.ttt).toEqual('hey-q');
|
|
27
|
+
nack(msg);
|
|
28
|
+
};
|
|
20
29
|
describe('RabbitMQ', () => {
|
|
21
30
|
it('check exchange', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
-
const
|
|
23
|
-
expect(msg.content).toEqual('hey');
|
|
24
|
-
ack(msg);
|
|
25
|
-
};
|
|
26
|
-
const mockFn = jest.fn(callback);
|
|
31
|
+
const mockFn = jest.fn(callback());
|
|
27
32
|
yield rabbit.consumeFromExchange('test-q2', 'test-e', mockFn);
|
|
28
33
|
yield rabbit.publish('test-e', 'hey');
|
|
29
34
|
yield delay();
|
|
30
35
|
expect(mockFn).toBeCalled();
|
|
31
36
|
}));
|
|
32
37
|
it('check queue', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
-
const
|
|
34
|
-
expect(msg.content).toEqual('hey-q');
|
|
35
|
-
ack(msg);
|
|
36
|
-
};
|
|
37
|
-
const mockFn = jest.fn(callback);
|
|
38
|
+
const mockFn = jest.fn(callback('hey-q'));
|
|
38
39
|
yield rabbit.consume('test-q-2', mockFn);
|
|
39
40
|
yield rabbit.sendToQueue('test-q-2', 'hey-q');
|
|
40
41
|
yield delay();
|
|
41
42
|
expect(mockFn).toBeCalled();
|
|
42
43
|
}));
|
|
44
|
+
it('check retry', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
45
|
+
const mockFn = jest.fn(nackcallback());
|
|
46
|
+
yield rabbit.consume('test-q-retry', mockFn, { retries: 3 });
|
|
47
|
+
yield rabbit.sendToQueue('test-q-retry', { ttt: 'hey-q' });
|
|
48
|
+
yield delay(1500);
|
|
49
|
+
expect(mockFn).toHaveBeenCalledTimes(4); // one run then 3 times retry
|
|
50
|
+
}));
|
|
51
|
+
it('check nack and dead queue', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
|
+
const mockFn = jest.fn(nackcallback());
|
|
53
|
+
yield rabbit.consume('test-q-nack', mockFn);
|
|
54
|
+
yield rabbit.sendToQueue('test-q-nack', { ttt: 'hey-q' });
|
|
55
|
+
yield delay(1000);
|
|
56
|
+
expect(mockFn).toHaveBeenCalledTimes(2); // one run then 1 time retry
|
|
57
|
+
yield delay();
|
|
58
|
+
const length = yield rabbit.getQueueLength('test-q-nack-dead');
|
|
59
|
+
expect(length.messageCount).toEqual(1);
|
|
60
|
+
}));
|
|
43
61
|
it('cant publish to unknown exchange', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
62
|
let err;
|
|
45
63
|
try {
|
|
@@ -76,10 +94,7 @@ describe('RabbitMQ', () => {
|
|
|
76
94
|
yield rabbit.publish(exchangeName, 'hey');
|
|
77
95
|
({ messageCount } = yield rabbit.getQueueLength(queueName));
|
|
78
96
|
expect(messageCount).toEqual(2);
|
|
79
|
-
yield rabbit.consumeFromExchange(queueName, exchangeName, (
|
|
80
|
-
expect(msg.content).toEqual('hey');
|
|
81
|
-
ack(msg);
|
|
82
|
-
}));
|
|
97
|
+
yield rabbit.consumeFromExchange(queueName, exchangeName, callback());
|
|
83
98
|
yield delay();
|
|
84
99
|
({ messageCount } = yield rabbit.getQueueLength(queueName));
|
|
85
100
|
expect(messageCount).toEqual(0);
|
package/package.json
CHANGED
package/src/index.test.ts
CHANGED
|
@@ -5,15 +5,22 @@ jest.setTimeout(120000);
|
|
|
5
5
|
|
|
6
6
|
const rabbit = new RabbitMq();
|
|
7
7
|
|
|
8
|
-
const delay = () => new Promise((resolve) => setTimeout(() => resolve(),
|
|
8
|
+
const delay = (ms = 500) => new Promise((resolve) => setTimeout(() => resolve(), ms));
|
|
9
|
+
|
|
10
|
+
const callback = (eq = 'hey') => (msg: any, ack: any) => {
|
|
11
|
+
expect(msg.content).toEqual(eq);
|
|
12
|
+
ack(msg);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const nackcallback = () => (msg: any, ack: any, nack: any) => {
|
|
16
|
+
console.log('msg', msg.content);
|
|
17
|
+
expect(msg.content.ttt).toEqual('hey-q');
|
|
18
|
+
nack(msg);
|
|
19
|
+
};
|
|
9
20
|
|
|
10
21
|
describe('RabbitMQ', () => {
|
|
11
22
|
it('check exchange', async () => {
|
|
12
|
-
const
|
|
13
|
-
expect(msg.content).toEqual('hey');
|
|
14
|
-
ack(msg);
|
|
15
|
-
};
|
|
16
|
-
const mockFn = jest.fn(callback);
|
|
23
|
+
const mockFn = jest.fn(callback());
|
|
17
24
|
await rabbit.consumeFromExchange('test-q2', 'test-e', mockFn);
|
|
18
25
|
await rabbit.publish('test-e', 'hey');
|
|
19
26
|
await delay();
|
|
@@ -21,17 +28,32 @@ describe('RabbitMQ', () => {
|
|
|
21
28
|
});
|
|
22
29
|
|
|
23
30
|
it('check queue', async () => {
|
|
24
|
-
const
|
|
25
|
-
expect(msg.content).toEqual('hey-q');
|
|
26
|
-
ack(msg);
|
|
27
|
-
};
|
|
28
|
-
const mockFn = jest.fn(callback);
|
|
31
|
+
const mockFn = jest.fn(callback('hey-q'));
|
|
29
32
|
await rabbit.consume('test-q-2', mockFn);
|
|
30
33
|
await rabbit.sendToQueue('test-q-2', 'hey-q');
|
|
31
34
|
await delay();
|
|
32
35
|
expect(mockFn).toBeCalled();
|
|
33
36
|
});
|
|
34
37
|
|
|
38
|
+
it('check retry', async () => {
|
|
39
|
+
const mockFn = jest.fn(nackcallback());
|
|
40
|
+
await rabbit.consume('test-q-retry', mockFn, { retries: 3 });
|
|
41
|
+
await rabbit.sendToQueue('test-q-retry', { ttt: 'hey-q' });
|
|
42
|
+
await delay(1500);
|
|
43
|
+
expect(mockFn).toHaveBeenCalledTimes(4); // one run then 3 times retry
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('check nack and dead queue', async () => {
|
|
47
|
+
const mockFn = jest.fn(nackcallback());
|
|
48
|
+
await rabbit.consume('test-q-nack', mockFn);
|
|
49
|
+
await rabbit.sendToQueue('test-q-nack', { ttt: 'hey-q' });
|
|
50
|
+
await delay(1000);
|
|
51
|
+
expect(mockFn).toHaveBeenCalledTimes(2); // one run then 1 time retry
|
|
52
|
+
await delay();
|
|
53
|
+
const length = await rabbit.getQueueLength('test-q-nack-dead');
|
|
54
|
+
expect(length.messageCount).toEqual(1);
|
|
55
|
+
});
|
|
56
|
+
|
|
35
57
|
it('cant publish to unknown exchange', async () => {
|
|
36
58
|
let err;
|
|
37
59
|
try {
|
|
@@ -71,10 +93,7 @@ describe('RabbitMQ', () => {
|
|
|
71
93
|
await rabbit.publish(exchangeName, 'hey');
|
|
72
94
|
({ messageCount } = await rabbit.getQueueLength(queueName));
|
|
73
95
|
expect(messageCount).toEqual(2);
|
|
74
|
-
await rabbit.consumeFromExchange(queueName, exchangeName,
|
|
75
|
-
expect(msg.content).toEqual('hey');
|
|
76
|
-
ack(msg);
|
|
77
|
-
});
|
|
96
|
+
await rabbit.consumeFromExchange(queueName, exchangeName, callback());
|
|
78
97
|
await delay();
|
|
79
98
|
({ messageCount } = await rabbit.getQueueLength(queueName));
|
|
80
99
|
expect(messageCount).toEqual(0);
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,18 @@ interface ExchangesCache {
|
|
|
11
11
|
[key: string]: any
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export interface AfRabbitOptions {
|
|
15
|
+
reconnect: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 48;
|
|
19
|
+
|
|
20
|
+
const defaultOptions = {
|
|
21
|
+
limit: 1,
|
|
22
|
+
retries: 1,
|
|
23
|
+
deadMessageTtl: DEFAULT_DEAD_TTL_TWO_DAYS,
|
|
24
|
+
};
|
|
25
|
+
|
|
14
26
|
const assertExchangeFanout = (c: any, exchangeName: string) => c.assertExchange(exchangeName, 'fanout');
|
|
15
27
|
|
|
16
28
|
const connectionCreatedConst = 'connectionCreated';
|
|
@@ -35,20 +47,14 @@ class RabbitMq {
|
|
|
35
47
|
}
|
|
36
48
|
}
|
|
37
49
|
|
|
38
|
-
static consumeOptions(options?: any): {limit: number, deadMessageTtl: number} {
|
|
39
|
-
return {
|
|
40
|
-
limit: 1,
|
|
41
|
-
deadMessageTtl: null,
|
|
42
|
-
...options,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
50
|
PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
|
|
47
51
|
|
|
48
52
|
PUBLISH_ERROR_MSG = `rabbit: publish timeout(${this.PUBLISH_TIMEOUT}ms) has pass, exchange: `;
|
|
49
53
|
|
|
50
54
|
DISCONNECT_MSG = 'rabbit: connection disconnect';
|
|
51
55
|
|
|
56
|
+
RESCONNECT_MSG = 'rabbit: reconnecting';
|
|
57
|
+
|
|
52
58
|
channel: ChannelWrapper | null;
|
|
53
59
|
|
|
54
60
|
connection: AmqpConnectionManager | null;
|
|
@@ -59,12 +65,15 @@ class RabbitMq {
|
|
|
59
65
|
|
|
60
66
|
exchanges: ExchangesCache;
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
options: AfRabbitOptions | undefined;
|
|
69
|
+
|
|
70
|
+
constructor(options?: AfRabbitOptions) {
|
|
63
71
|
this.em = new EventEmitter();
|
|
64
72
|
this.channel = null;
|
|
65
73
|
this.connection = null;
|
|
66
74
|
this.creatingConnection = false;
|
|
67
75
|
this.exchanges = {};
|
|
76
|
+
this.options = options;
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
public ack = async (msg: any) => {
|
|
@@ -73,15 +82,15 @@ class RabbitMq {
|
|
|
73
82
|
}
|
|
74
83
|
}
|
|
75
84
|
|
|
76
|
-
public nack = (queue: string, options
|
|
85
|
+
public nack = (queue: string, options: any, deadQueueOptions: Options.AssertQueue) => async (msg: any) => {
|
|
77
86
|
if (this.channel) {
|
|
78
|
-
if (!msg.content['x-retry-count'] || msg.content['x-retry-count']
|
|
87
|
+
if (!msg.content['x-retry-count'] || msg.content['x-retry-count'] < options.retries) {
|
|
79
88
|
msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
|
|
80
89
|
await this.sendToQueue(queue, msg.content);
|
|
81
90
|
} else {
|
|
82
91
|
const deadQueue = `${queue}-dead`;
|
|
83
|
-
await this.assertQueue(deadQueue,
|
|
84
|
-
await this.sendToQueue(deadQueue, msg.content);
|
|
92
|
+
await this.assertQueue(deadQueue, deadQueueOptions);
|
|
93
|
+
await this.sendToQueue(deadQueue, msg.content, deadQueueOptions);
|
|
85
94
|
}
|
|
86
95
|
await this.channel.ack(msg);
|
|
87
96
|
}
|
|
@@ -101,7 +110,14 @@ class RabbitMq {
|
|
|
101
110
|
const connection: AmqpConnectionManager = await connect([`amqp://${host}`]);
|
|
102
111
|
this.connection = connection;
|
|
103
112
|
this.connection.on('disconnect',
|
|
104
|
-
({ err }) =>
|
|
113
|
+
({ err }) => {
|
|
114
|
+
if (this.options?.reconnect) {
|
|
115
|
+
console.error(`${this.RESCONNECT_MSG}${err && ` - ${err}`}`);
|
|
116
|
+
this.connection = null;
|
|
117
|
+
} else {
|
|
118
|
+
console.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
105
121
|
this.creatingConnection = false;
|
|
106
122
|
this.em.emit(connectionCreatedConst, connection);
|
|
107
123
|
resolve(connection);
|
|
@@ -159,8 +175,9 @@ class RabbitMq {
|
|
|
159
175
|
}
|
|
160
176
|
|
|
161
177
|
async consume(queue: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any) {
|
|
178
|
+
const optionsWithDefaults = { ...defaultOptions, ...options };
|
|
162
179
|
RabbitMq.validateName('queue', queue);
|
|
163
|
-
const { limit, deadMessageTtl } =
|
|
180
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
164
181
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
165
182
|
return channel.addSetup(async (c: ConfirmChannel) => {
|
|
166
183
|
await c.assertQueue(queue);
|
|
@@ -170,7 +187,7 @@ class RabbitMq {
|
|
|
170
187
|
queue,
|
|
171
188
|
(msg: any) => {
|
|
172
189
|
newTrace(traceTypes.RABBIT);
|
|
173
|
-
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, { messageTtl: deadMessageTtl }));
|
|
190
|
+
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
174
191
|
},
|
|
175
192
|
),
|
|
176
193
|
]);
|
|
@@ -178,9 +195,10 @@ class RabbitMq {
|
|
|
178
195
|
}
|
|
179
196
|
|
|
180
197
|
async consumeFromExchange(queue: string, exchange: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any) {
|
|
181
|
-
|
|
198
|
+
const optionsWithDefaults = { ...defaultOptions, ...options };
|
|
182
199
|
RabbitMq.validateName('exchange', exchange);
|
|
183
|
-
|
|
200
|
+
RabbitMq.validateName('queue', queue);
|
|
201
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
184
202
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
185
203
|
|
|
186
204
|
return channel.addSetup(async (c: ConfirmChannel) => {
|
|
@@ -194,7 +212,7 @@ class RabbitMq {
|
|
|
194
212
|
queue,
|
|
195
213
|
(msg: any) => {
|
|
196
214
|
newTrace(traceTypes.RABBIT);
|
|
197
|
-
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, { messageTtl: deadMessageTtl }));
|
|
215
|
+
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
198
216
|
},
|
|
199
217
|
),
|
|
200
218
|
]);
|
|
@@ -211,10 +229,10 @@ class RabbitMq {
|
|
|
211
229
|
}).timeout(this.PUBLISH_TIMEOUT, `${this.PUBLISH_ERROR_MSG}${exchange}`);
|
|
212
230
|
}
|
|
213
231
|
|
|
214
|
-
async sendToQueue(queue: string, content: any) {
|
|
232
|
+
async sendToQueue(queue: string, content: any, options?: any) {
|
|
215
233
|
RabbitMq.validateName('queue', queue);
|
|
216
234
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
217
|
-
await this.assertQueue(queue);
|
|
235
|
+
await this.assertQueue(queue, options);
|
|
218
236
|
return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)));
|
|
219
237
|
}
|
|
220
238
|
}
|