@autofleet/rabbit 1.6.0 → 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 +1 -5
- package/dist/index.js +17 -16
- package/dist/index.test.js +30 -15
- package/package.json +1 -1
- package/src/index.test.ts +34 -15
- package/src/index.ts +19 -21
package/dist/index.d.ts
CHANGED
|
@@ -11,10 +11,6 @@ export interface AfRabbitOptions {
|
|
|
11
11
|
declare class RabbitMq {
|
|
12
12
|
static parseMsg(msg: any): any;
|
|
13
13
|
static validateName(type: string, name: string): void;
|
|
14
|
-
static consumeOptions(options?: any): {
|
|
15
|
-
limit: number;
|
|
16
|
-
deadMessageTtl: number;
|
|
17
|
-
};
|
|
18
14
|
PUBLISH_TIMEOUT: number;
|
|
19
15
|
PUBLISH_ERROR_MSG: string;
|
|
20
16
|
DISCONNECT_MSG: string;
|
|
@@ -27,7 +23,7 @@ declare class RabbitMq {
|
|
|
27
23
|
options: AfRabbitOptions | undefined;
|
|
28
24
|
constructor(options?: AfRabbitOptions);
|
|
29
25
|
ack: (msg: any) => Promise<void>;
|
|
30
|
-
nack: (queue: string, deadQueueOptions
|
|
26
|
+
nack: (queue: string, options: any, deadQueueOptions: Options.AssertQueue) => (msg: any) => Promise<void>;
|
|
31
27
|
getConnection(): Promise<AmqpConnectionManager>;
|
|
32
28
|
assertChannel(): Promise<ChannelWrapper>;
|
|
33
29
|
assertExchange(exchangeName: string, options?: any): Promise<any>;
|
package/dist/index.js
CHANGED
|
@@ -38,6 +38,12 @@ 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 {
|
|
@@ -51,9 +57,9 @@ class RabbitMq {
|
|
|
51
57
|
yield this.channel.ack(msg);
|
|
52
58
|
}
|
|
53
59
|
});
|
|
54
|
-
this.nack = (queue, deadQueueOptions) => (msg
|
|
60
|
+
this.nack = (queue, options, deadQueueOptions) => (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
55
61
|
if (this.channel) {
|
|
56
|
-
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) {
|
|
57
63
|
msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
|
|
58
64
|
yield this.sendToQueue(queue, msg.content);
|
|
59
65
|
}
|
|
@@ -86,9 +92,6 @@ class RabbitMq {
|
|
|
86
92
|
throw new rabbitError_1.default(`error while using ${type} with no name`);
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
|
-
static consumeOptions(options) {
|
|
90
|
-
return Object.assign({ limit: 1, deadMessageTtl: null }, options);
|
|
91
|
-
}
|
|
92
95
|
getConnection() {
|
|
93
96
|
return __awaiter(this, void 0, void 0, function* () {
|
|
94
97
|
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -175,18 +178,17 @@ class RabbitMq {
|
|
|
175
178
|
}
|
|
176
179
|
consume(queue, callback, options) {
|
|
177
180
|
return __awaiter(this, void 0, void 0, function* () {
|
|
181
|
+
const optionsWithDefaults = Object.assign(Object.assign({}, defaultOptions), options);
|
|
178
182
|
RabbitMq.validateName('queue', queue);
|
|
179
|
-
const { limit, deadMessageTtl } =
|
|
183
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
180
184
|
const channel = yield this.assertChannel();
|
|
181
185
|
return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
|
|
182
186
|
yield c.assertQueue(queue);
|
|
183
187
|
yield c.prefetch(limit, true);
|
|
184
188
|
return Promise.all([
|
|
185
189
|
c.consume(queue, (msg) => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, { messageTtl: deadMessageTtl }));
|
|
189
|
-
});
|
|
190
|
+
outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
|
|
191
|
+
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
190
192
|
}),
|
|
191
193
|
]);
|
|
192
194
|
}));
|
|
@@ -194,9 +196,10 @@ class RabbitMq {
|
|
|
194
196
|
}
|
|
195
197
|
consumeFromExchange(queue, exchange, callback, options) {
|
|
196
198
|
return __awaiter(this, void 0, void 0, function* () {
|
|
197
|
-
|
|
199
|
+
const optionsWithDefaults = Object.assign(Object.assign({}, defaultOptions), options);
|
|
198
200
|
RabbitMq.validateName('exchange', exchange);
|
|
199
|
-
|
|
201
|
+
RabbitMq.validateName('queue', queue);
|
|
202
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
200
203
|
const channel = yield this.assertChannel();
|
|
201
204
|
return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
|
|
202
205
|
const assertExchange = yield assertExchangeFanout(c, exchange);
|
|
@@ -206,10 +209,8 @@ class RabbitMq {
|
|
|
206
209
|
return Promise.all([
|
|
207
210
|
c.bindQueue(queue, exchange, ''),
|
|
208
211
|
c.consume(queue, (msg) => {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, { messageTtl: deadMessageTtl }));
|
|
212
|
-
});
|
|
212
|
+
outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
|
|
213
|
+
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
213
214
|
}),
|
|
214
215
|
]);
|
|
215
216
|
}));
|
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
|
@@ -15,6 +15,14 @@ export interface AfRabbitOptions {
|
|
|
15
15
|
reconnect: boolean
|
|
16
16
|
}
|
|
17
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
|
+
|
|
18
26
|
const assertExchangeFanout = (c: any, exchangeName: string) => c.assertExchange(exchangeName, 'fanout');
|
|
19
27
|
|
|
20
28
|
const connectionCreatedConst = 'connectionCreated';
|
|
@@ -39,14 +47,6 @@ class RabbitMq {
|
|
|
39
47
|
}
|
|
40
48
|
}
|
|
41
49
|
|
|
42
|
-
static consumeOptions(options?: any): {limit: number, deadMessageTtl: number} {
|
|
43
|
-
return {
|
|
44
|
-
limit: 1,
|
|
45
|
-
deadMessageTtl: null,
|
|
46
|
-
...options,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
50
|
PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
|
|
51
51
|
|
|
52
52
|
PUBLISH_ERROR_MSG = `rabbit: publish timeout(${this.PUBLISH_TIMEOUT}ms) has pass, exchange: `;
|
|
@@ -82,9 +82,9 @@ class RabbitMq {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
public nack = (queue: string, deadQueueOptions
|
|
85
|
+
public nack = (queue: string, options: any, deadQueueOptions: Options.AssertQueue) => async (msg: any) => {
|
|
86
86
|
if (this.channel) {
|
|
87
|
-
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) {
|
|
88
88
|
msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
|
|
89
89
|
await this.sendToQueue(queue, msg.content);
|
|
90
90
|
} else {
|
|
@@ -175,8 +175,9 @@ class RabbitMq {
|
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
async consume(queue: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any) {
|
|
178
|
+
const optionsWithDefaults = { ...defaultOptions, ...options };
|
|
178
179
|
RabbitMq.validateName('queue', queue);
|
|
179
|
-
const { limit, deadMessageTtl } =
|
|
180
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
180
181
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
181
182
|
return channel.addSetup(async (c: ConfirmChannel) => {
|
|
182
183
|
await c.assertQueue(queue);
|
|
@@ -185,10 +186,8 @@ class RabbitMq {
|
|
|
185
186
|
c.consume(
|
|
186
187
|
queue,
|
|
187
188
|
(msg: any) => {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, { messageTtl: deadMessageTtl }));
|
|
191
|
-
})
|
|
189
|
+
newTrace(traceTypes.RABBIT);
|
|
190
|
+
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
192
191
|
},
|
|
193
192
|
),
|
|
194
193
|
]);
|
|
@@ -196,9 +195,10 @@ class RabbitMq {
|
|
|
196
195
|
}
|
|
197
196
|
|
|
198
197
|
async consumeFromExchange(queue: string, exchange: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any) {
|
|
199
|
-
|
|
198
|
+
const optionsWithDefaults = { ...defaultOptions, ...options };
|
|
200
199
|
RabbitMq.validateName('exchange', exchange);
|
|
201
|
-
|
|
200
|
+
RabbitMq.validateName('queue', queue);
|
|
201
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
202
202
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
203
203
|
|
|
204
204
|
return channel.addSetup(async (c: ConfirmChannel) => {
|
|
@@ -211,10 +211,8 @@ class RabbitMq {
|
|
|
211
211
|
c.consume(
|
|
212
212
|
queue,
|
|
213
213
|
(msg: any) => {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, { messageTtl: deadMessageTtl }));
|
|
217
|
-
})
|
|
214
|
+
newTrace(traceTypes.RABBIT);
|
|
215
|
+
callback(RabbitMq.parseMsg(msg), this.ack, this.nack(queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
218
216
|
},
|
|
219
217
|
),
|
|
220
218
|
]);
|