@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 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) => (msg: any, { skipRetry, }?: any) => Promise<void>;
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<any>;
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) => (msg, { skipRetry = false, } = {}) => __awaiter(this, void 0, void 0, function* () {
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.content['x-retry-count']
67
- || msg.content['x-retry-count'] < options.retries)) {
68
- msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
69
- yield this.sendToQueue(queue, msg.content);
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.assertQueue(deadQueue, deadQueueOptions);
74
- yield this.sendToQueue(deadQueue, msg.content, deadQueueOptions);
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 new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
302
- try {
303
- setImmediate(() => __awaiter(this, void 0, void 0, function* () {
304
- RabbitMq.validateName('exchange', exchange);
305
- const channel = yield this.assertChannel();
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
- RabbitMq.validateName('queue', queue);
320
- const channel = yield this.assertChannel();
321
- yield this.assertQueue(queue, options);
322
- logger_1.default.info('rabbit: sending to queue', { queue, content, customHeaders });
323
- return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autofleet/rabbit",
3
- "version": "2.2.4-beta-1",
3
+ "version": "2.2.5",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
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
- msg: any,
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
- && (!msg.content['x-retry-count']
175
- || msg.content['x-retry-count'] < options.retries)
187
+ && (
188
+ !msg.properties.headers[RETRY_HEADER]
189
+ || parseInt(msg.properties.headers[RETRY_HEADER], 10) < options.retries
190
+ )
176
191
  ) {
177
- msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
178
- await this.sendToQueue(queue, msg.content);
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.assertQueue(deadQueue, deadQueueOptions);
182
- await this.sendToQueue(deadQueue, msg.content, deadQueueOptions);
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<any> {
378
- return new Promise<any>(async (resolve, reject) => {
379
- try {
380
- setImmediate(async () => {
381
- RabbitMq.validateName('exchange', exchange);
382
- const channel: ChannelWrapper = await this.assertChannel();
383
- await this.assertExchange(exchange);
384
- await channel.publish(exchange, '',
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
- RabbitMq.validateName('queue', queue);
397
- const channel: ChannelWrapper = await this.assertChannel();
398
- await this.assertQueue(queue, options);
399
- logger.info('rabbit: sending to queue', { queue, content, customHeaders });
400
- return channel.sendToQueue(queue,
401
- Buffer.from(JSON.stringify(content)),
402
- RabbitMq.getPublishOptions(customHeaders));
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
@@ -5,7 +5,9 @@
5
5
  "declaration": true,
6
6
  "outDir": "./dist",
7
7
  "strict": true,
8
- "esModuleInterop": true
8
+ "esModuleInterop": true,
9
+ "experimentalDecorators": true,
10
+ "emitDecoratorMetadata": true
9
11
  },
10
12
  "exclude": ["node_modules", "**/*.test.ts"]
11
13
  }
package/.env DELETED
File without changes
package/dump.rdb DELETED
Binary file