@autofleet/rabbit 2.2.4-beta-1 → 2.2.5
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 +3 -2
- package/dist/index.js +40 -28
- package/package.json +1 -1
- package/src/index.ts +49 -33
- package/tsconfig.json +3 -1
- package/.env +0 -0
- package/dump.rdb +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ declare type CustomMessageHeaders = {
|
|
|
25
25
|
redisTimestampValidationKey?: string;
|
|
26
26
|
};
|
|
27
27
|
declare type RedisLockType = (args0?: string, arg1?: number) => Promise<any>;
|
|
28
|
+
declare type ConsumeMessageOrNull = ConsumeMessage | null;
|
|
28
29
|
interface ConsumeOptions {
|
|
29
30
|
retries?: number;
|
|
30
31
|
deadMessageTtl?: number;
|
|
@@ -59,7 +60,7 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
59
60
|
constructor(options?: AfRabbitOptions, redisConfig?: RedisConfig);
|
|
60
61
|
private shouldConsumeMessageByTimestamp;
|
|
61
62
|
ack: (channel: ChannelWrapper, shouldUpdateRedisTimestamp?: boolean) => (msg: ConsumeMessage) => Promise<any>;
|
|
62
|
-
nack: (channel: ChannelWrapper, queue: string, options: any, deadQueueOptions: Options.AssertQueue) => (
|
|
63
|
+
nack: (channel: ChannelWrapper, queue: string, options: any, deadQueueOptions: Options.AssertQueue, msg: ConsumeMessageOrNull) => (userMsg: ConsumeMessageOrNull, { skipRetry, }?: any) => Promise<any>;
|
|
63
64
|
getConnection(): Promise<AmqpConnectionManager>;
|
|
64
65
|
getNewChannel(): Promise<ChannelWrapper>;
|
|
65
66
|
assertChannel(): Promise<ChannelWrapper>;
|
|
@@ -71,7 +72,7 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
71
72
|
private consumeWithLock;
|
|
72
73
|
private consumeFromRabbit;
|
|
73
74
|
consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
|
|
74
|
-
publish(exchange: string, content: any, customHeaders?: any): Promise<
|
|
75
|
+
publish(exchange: string, content: any, customHeaders?: any): Promise<boolean>;
|
|
75
76
|
sendToQueue(queue: string, content: any, options?: any, customHeaders?: any): Promise<boolean>;
|
|
76
77
|
isConnected(): Promise<boolean>;
|
|
77
78
|
}
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ const rabbitError_1 = __importDefault(require("./rabbitError"));
|
|
|
25
25
|
const redis_1 = __importDefault(require("./redis"));
|
|
26
26
|
const DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 48;
|
|
27
27
|
const DEFAULT_LOCK_TIMEOUT = 1000 * 5;
|
|
28
|
+
const RETRY_HEADER = 'x-retry-count';
|
|
28
29
|
const defaultOptions = {
|
|
29
30
|
limit: 1,
|
|
30
31
|
retries: 1,
|
|
@@ -32,6 +33,17 @@ const defaultOptions = {
|
|
|
32
33
|
};
|
|
33
34
|
const assertExchangeFanout = (c, exchangeName) => c.assertExchange(exchangeName, 'fanout');
|
|
34
35
|
const connectionCreatedConst = 'connectionCreated';
|
|
36
|
+
const wrapSetImmediate = (callback) => new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
+
setImmediate(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
try {
|
|
39
|
+
const value = yield callback();
|
|
40
|
+
resolve(value);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
reject(error);
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
}));
|
|
35
47
|
class RabbitMq {
|
|
36
48
|
constructor(options, redisConfig) {
|
|
37
49
|
this.PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
|
|
@@ -60,18 +72,24 @@ class RabbitMq {
|
|
|
60
72
|
yield this.redisClient.setAsync(headers.redisTimestampValidationKey, parsedTimestamp, 'EX', 3600);
|
|
61
73
|
}
|
|
62
74
|
});
|
|
63
|
-
this.nack = (channel, queue, options, deadQueueOptions) => (
|
|
64
|
-
if (channel) {
|
|
75
|
+
this.nack = (channel, queue, options, deadQueueOptions, msg) => (userMsg, { skipRetry = false, } = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
if (channel && msg) {
|
|
65
77
|
if (!skipRetry
|
|
66
|
-
&& (!msg.
|
|
67
|
-
|| msg.
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
&& (!msg.properties.headers[RETRY_HEADER]
|
|
79
|
+
|| parseInt(msg.properties.headers[RETRY_HEADER], 10) < options.retries)) {
|
|
80
|
+
yield this.sendToQueue(queue, RabbitMq.parseMsg(msg).content, options, {
|
|
81
|
+
[RETRY_HEADER]: msg.properties.headers[RETRY_HEADER]
|
|
82
|
+
? msg.properties.headers[RETRY_HEADER] + 1
|
|
83
|
+
: 1,
|
|
84
|
+
});
|
|
70
85
|
}
|
|
71
86
|
else {
|
|
72
87
|
const deadQueue = `${queue}-dead`;
|
|
73
|
-
yield this.
|
|
74
|
-
|
|
88
|
+
yield this.sendToQueue(deadQueue, RabbitMq.parseMsg(msg).content, deadQueueOptions, {
|
|
89
|
+
[RETRY_HEADER]: msg.properties.headers[RETRY_HEADER]
|
|
90
|
+
? msg.properties.headers[RETRY_HEADER] + 1
|
|
91
|
+
: 1,
|
|
92
|
+
});
|
|
75
93
|
}
|
|
76
94
|
yield channel.ack(msg);
|
|
77
95
|
}
|
|
@@ -267,10 +285,10 @@ class RabbitMq {
|
|
|
267
285
|
return this.ack(channel)(msg);
|
|
268
286
|
}
|
|
269
287
|
try {
|
|
270
|
-
yield callback(parsedMessage, this.ack(channel, true), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
288
|
+
yield callback(parsedMessage, this.ack(channel, true), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg));
|
|
271
289
|
}
|
|
272
290
|
catch (e) {
|
|
273
|
-
yield this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl })(msg);
|
|
291
|
+
yield this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg)(msg);
|
|
274
292
|
}
|
|
275
293
|
})),
|
|
276
294
|
]);
|
|
@@ -298,29 +316,23 @@ class RabbitMq {
|
|
|
298
316
|
}
|
|
299
317
|
publish(exchange, content, customHeaders) {
|
|
300
318
|
return __awaiter(this, void 0, void 0, function* () {
|
|
301
|
-
return
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
yield this.assertExchange(exchange);
|
|
307
|
-
yield channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
308
|
-
resolve(true);
|
|
309
|
-
}));
|
|
310
|
-
}
|
|
311
|
-
catch (error) {
|
|
312
|
-
reject(error);
|
|
313
|
-
}
|
|
319
|
+
return wrapSetImmediate(() => __awaiter(this, void 0, void 0, function* () {
|
|
320
|
+
RabbitMq.validateName('exchange', exchange);
|
|
321
|
+
const channel = yield this.assertChannel();
|
|
322
|
+
yield this.assertExchange(exchange);
|
|
323
|
+
yield channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
314
324
|
}));
|
|
315
325
|
});
|
|
316
326
|
}
|
|
317
327
|
sendToQueue(queue, content, options, customHeaders) {
|
|
318
328
|
return __awaiter(this, void 0, void 0, function* () {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
329
|
+
return wrapSetImmediate(() => __awaiter(this, void 0, void 0, function* () {
|
|
330
|
+
RabbitMq.validateName('queue', queue);
|
|
331
|
+
const channel = yield this.assertChannel();
|
|
332
|
+
yield this.assertQueue(queue, options);
|
|
333
|
+
logger_1.default.info('rabbit: sending to queue', { queue, content, customHeaders });
|
|
334
|
+
return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
335
|
+
}));
|
|
324
336
|
});
|
|
325
337
|
}
|
|
326
338
|
isConnected() {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -54,6 +54,7 @@ export interface AfRabbitOptions {
|
|
|
54
54
|
|
|
55
55
|
const DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 48;
|
|
56
56
|
const DEFAULT_LOCK_TIMEOUT = 1000 * 5;
|
|
57
|
+
const RETRY_HEADER = 'x-retry-count';
|
|
57
58
|
|
|
58
59
|
const defaultOptions = {
|
|
59
60
|
limit: 1,
|
|
@@ -65,6 +66,17 @@ const assertExchangeFanout = (c: any, exchangeName: string) => c.assertExchange(
|
|
|
65
66
|
|
|
66
67
|
const connectionCreatedConst = 'connectionCreated';
|
|
67
68
|
|
|
69
|
+
const wrapSetImmediate = (callback: () => any) => new Promise<any>(async (resolve, reject) => {
|
|
70
|
+
setImmediate(async () => {
|
|
71
|
+
try {
|
|
72
|
+
const value = await callback();
|
|
73
|
+
resolve(value);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
reject(error);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
68
80
|
class RabbitMq implements IAfRabbitMq {
|
|
69
81
|
static parseMsg(msg: any) : any {
|
|
70
82
|
let { content } = msg;
|
|
@@ -162,24 +174,33 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
162
174
|
queue: string,
|
|
163
175
|
options: any,
|
|
164
176
|
deadQueueOptions: Options.AssertQueue,
|
|
177
|
+
msg: ConsumeMessageOrNull,
|
|
165
178
|
) => async (
|
|
166
|
-
|
|
179
|
+
userMsg: ConsumeMessageOrNull,
|
|
167
180
|
{
|
|
168
181
|
skipRetry = false,
|
|
169
182
|
}: any = { },
|
|
170
|
-
) => {
|
|
171
|
-
if (channel) {
|
|
183
|
+
) : Promise<any> => {
|
|
184
|
+
if (channel && msg) {
|
|
172
185
|
if (
|
|
173
186
|
!skipRetry
|
|
174
|
-
&& (
|
|
175
|
-
|
|
187
|
+
&& (
|
|
188
|
+
!msg.properties.headers[RETRY_HEADER]
|
|
189
|
+
|| parseInt(msg.properties.headers[RETRY_HEADER], 10) < options.retries
|
|
190
|
+
)
|
|
176
191
|
) {
|
|
177
|
-
|
|
178
|
-
|
|
192
|
+
await this.sendToQueue(queue, RabbitMq.parseMsg(msg).content, options, {
|
|
193
|
+
[RETRY_HEADER]: msg.properties.headers[RETRY_HEADER]
|
|
194
|
+
? msg.properties.headers[RETRY_HEADER] + 1
|
|
195
|
+
: 1,
|
|
196
|
+
});
|
|
179
197
|
} else {
|
|
180
198
|
const deadQueue = `${queue}-dead`;
|
|
181
|
-
await this.
|
|
182
|
-
|
|
199
|
+
await this.sendToQueue(deadQueue, RabbitMq.parseMsg(msg).content, deadQueueOptions, {
|
|
200
|
+
[RETRY_HEADER]: msg.properties.headers[RETRY_HEADER]
|
|
201
|
+
? msg.properties.headers[RETRY_HEADER] + 1
|
|
202
|
+
: 1,
|
|
203
|
+
});
|
|
183
204
|
}
|
|
184
205
|
await channel.ack(msg);
|
|
185
206
|
}
|
|
@@ -340,10 +361,10 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
340
361
|
await callback(
|
|
341
362
|
parsedMessage,
|
|
342
363
|
this.ack(channel, true),
|
|
343
|
-
this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }),
|
|
364
|
+
this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg),
|
|
344
365
|
);
|
|
345
366
|
} catch (e) {
|
|
346
|
-
await this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl })(msg);
|
|
367
|
+
await this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg)(msg);
|
|
347
368
|
}
|
|
348
369
|
},
|
|
349
370
|
),
|
|
@@ -374,32 +395,27 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
374
395
|
});
|
|
375
396
|
}
|
|
376
397
|
|
|
377
|
-
async publish(exchange: string, content: any, customHeaders?: any) : Promise<
|
|
378
|
-
return
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
Buffer.from(JSON.stringify(content)),
|
|
386
|
-
RabbitMq.getPublishOptions(customHeaders));
|
|
387
|
-
resolve(true);
|
|
388
|
-
});
|
|
389
|
-
} catch (error) {
|
|
390
|
-
reject(error);
|
|
391
|
-
}
|
|
398
|
+
async publish(exchange: string, content: any, customHeaders?: any) : Promise<boolean> {
|
|
399
|
+
return wrapSetImmediate(async () => {
|
|
400
|
+
RabbitMq.validateName('exchange', exchange);
|
|
401
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
402
|
+
await this.assertExchange(exchange);
|
|
403
|
+
await channel.publish(exchange, '',
|
|
404
|
+
Buffer.from(JSON.stringify(content)),
|
|
405
|
+
RabbitMq.getPublishOptions(customHeaders));
|
|
392
406
|
});
|
|
393
407
|
}
|
|
394
408
|
|
|
395
409
|
async sendToQueue(queue: string, content: any, options?: any, customHeaders?: any) : Promise<boolean> {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
410
|
+
return wrapSetImmediate(async () => {
|
|
411
|
+
RabbitMq.validateName('queue', queue);
|
|
412
|
+
const channel: ChannelWrapper = await this.assertChannel();
|
|
413
|
+
await this.assertQueue(queue, options);
|
|
414
|
+
logger.info('rabbit: sending to queue', { queue, content, customHeaders });
|
|
415
|
+
return channel.sendToQueue(queue,
|
|
416
|
+
Buffer.from(JSON.stringify(content)),
|
|
417
|
+
RabbitMq.getPublishOptions(customHeaders));
|
|
418
|
+
});
|
|
403
419
|
}
|
|
404
420
|
|
|
405
421
|
async isConnected() : Promise<boolean> {
|
package/tsconfig.json
CHANGED
package/.env
DELETED
|
File without changes
|
package/dump.rdb
DELETED
|
Binary file
|