@autofleet/rabbit 2.0.4-beta3 → 2.0.4-beta5
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 +54 -0
- package/dist/index.js +282 -0
- package/dist/mock.d.ts +14 -0
- package/dist/mock.js +18 -0
- package/dist/rabbitError.d.ts +3 -0
- package/dist/rabbitError.js +9 -0
- package/package.json +3 -2
- package/src/index.ts +16 -13
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Options } from 'amqplib';
|
|
3
|
+
import { AmqpConnectionManager, ChannelWrapper } from 'amqp-connection-manager';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
|
+
export interface IAfRabbitMq {
|
|
6
|
+
ack: any;
|
|
7
|
+
nack: any;
|
|
8
|
+
assertChannel: any;
|
|
9
|
+
assertExchange: any;
|
|
10
|
+
assertQueue: any;
|
|
11
|
+
consume: any;
|
|
12
|
+
consumeFromExchange: any;
|
|
13
|
+
publish: any;
|
|
14
|
+
sendToQueue: any;
|
|
15
|
+
}
|
|
16
|
+
interface ExchangesCache {
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}
|
|
19
|
+
export interface AfRabbitOptions {
|
|
20
|
+
reconnect: boolean;
|
|
21
|
+
}
|
|
22
|
+
declare class RabbitMq implements IAfRabbitMq {
|
|
23
|
+
static parseMsg(msg: any): any;
|
|
24
|
+
static validateName(type: string, name: string): void;
|
|
25
|
+
PUBLISH_TIMEOUT: number;
|
|
26
|
+
PUBLISH_ERROR_MSG: string;
|
|
27
|
+
DISCONNECT_MSG: string;
|
|
28
|
+
RESCONNECT_MSG: string;
|
|
29
|
+
channel: ChannelWrapper | null;
|
|
30
|
+
connection: AmqpConnectionManager | null;
|
|
31
|
+
em: EventEmitter;
|
|
32
|
+
creatingConnection: boolean;
|
|
33
|
+
exchanges: ExchangesCache;
|
|
34
|
+
options: AfRabbitOptions | undefined;
|
|
35
|
+
logger: any;
|
|
36
|
+
constructor({ options, logger }?: {
|
|
37
|
+
options?: AfRabbitOptions;
|
|
38
|
+
logger?: any;
|
|
39
|
+
});
|
|
40
|
+
ack: (channel: ChannelWrapper) => (msg: any) => Promise<void>;
|
|
41
|
+
nack: (channel: ChannelWrapper, queue: string, options: any, deadQueueOptions: Options.AssertQueue) => (msg: any, { skipRetry, }?: any) => Promise<void>;
|
|
42
|
+
getConnection(): Promise<AmqpConnectionManager>;
|
|
43
|
+
getNewChannel(): Promise<ChannelWrapper>;
|
|
44
|
+
assertChannel(): Promise<ChannelWrapper>;
|
|
45
|
+
assertExchange(exchangeName: string, options?: any): Promise<any>;
|
|
46
|
+
getQueueLength(queue: string): Promise<any>;
|
|
47
|
+
bindQueue(queue: string, exchange: string): Promise<any>;
|
|
48
|
+
assertQueue(queue: string, options?: Options.AssertQueue): Promise<void>;
|
|
49
|
+
consume(queue: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
|
|
50
|
+
consumeFromExchange(queue: string, exchange: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
|
|
51
|
+
publish(exchange: string, content: any): Promise<unknown>;
|
|
52
|
+
sendToQueue(queue: string, content: any, options?: any): Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
export default RabbitMq;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
|
+
};
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment,@typescript-eslint/ban-types,@typescript-eslint/no-unused-vars,consistent-return,no-async-promise-executor,no-param-reassign,no-empty */
|
|
35
|
+
// eslint-disable-next-line max-classes-per-file
|
|
36
|
+
const bluebird = __importStar(require("bluebird"));
|
|
37
|
+
const amqp_connection_manager_1 = require("amqp-connection-manager");
|
|
38
|
+
const events_1 = require("events");
|
|
39
|
+
const outbreak_1 = require("@autofleet/outbreak");
|
|
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
|
+
};
|
|
47
|
+
const assertExchangeFanout = (c, exchangeName) => c.assertExchange(exchangeName, 'fanout');
|
|
48
|
+
const callbackWithTimeout = (callback, args, timeout, timeoutMessage = 'Timeout while ack message') => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
yield new bluebird.Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
+
try {
|
|
51
|
+
yield callback(...args);
|
|
52
|
+
return resolve();
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
return reject(e);
|
|
56
|
+
}
|
|
57
|
+
})).timeout(timeout, timeoutMessage);
|
|
58
|
+
});
|
|
59
|
+
const connectionCreatedConst = 'connectionCreated';
|
|
60
|
+
class RabbitMq {
|
|
61
|
+
constructor({ options, logger } = {}) {
|
|
62
|
+
this.PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
|
|
63
|
+
this.PUBLISH_ERROR_MSG = `rabbit: publish timeout(${this.PUBLISH_TIMEOUT}ms) has pass, exchange: `;
|
|
64
|
+
this.DISCONNECT_MSG = 'rabbit: connection disconnect';
|
|
65
|
+
this.RESCONNECT_MSG = 'rabbit: reconnecting';
|
|
66
|
+
this.ack = (channel) => (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
yield channel.ack(msg);
|
|
68
|
+
});
|
|
69
|
+
this.nack = (channel, queue, options, deadQueueOptions) => (msg, { skipRetry = false, } = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
if (channel) {
|
|
71
|
+
if (!skipRetry
|
|
72
|
+
&& (!msg.content['x-retry-count']
|
|
73
|
+
|| msg.content['x-retry-count'] < options.retries)) {
|
|
74
|
+
msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
|
|
75
|
+
yield this.sendToQueue(queue, msg.content);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const deadQueue = `${queue}-dead`;
|
|
79
|
+
yield this.assertQueue(deadQueue, deadQueueOptions);
|
|
80
|
+
yield this.sendToQueue(deadQueue, msg.content, deadQueueOptions);
|
|
81
|
+
}
|
|
82
|
+
yield channel.ack(msg);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
this.em = new events_1.EventEmitter();
|
|
86
|
+
this.channel = null;
|
|
87
|
+
this.connection = null;
|
|
88
|
+
this.creatingConnection = false;
|
|
89
|
+
this.exchanges = {};
|
|
90
|
+
this.options = options;
|
|
91
|
+
this.logger = logger;
|
|
92
|
+
}
|
|
93
|
+
static parseMsg(msg) {
|
|
94
|
+
let { content } = msg;
|
|
95
|
+
content = content.toString();
|
|
96
|
+
try {
|
|
97
|
+
content = JSON.parse(content);
|
|
98
|
+
}
|
|
99
|
+
catch (e) { }
|
|
100
|
+
return Object.assign(Object.assign({}, msg), { content });
|
|
101
|
+
}
|
|
102
|
+
static validateName(type, name) {
|
|
103
|
+
if (!name || name === '') {
|
|
104
|
+
throw new rabbitError_1.default(`error while using ${type} with no name`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
getConnection() {
|
|
108
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
if (this.creatingConnection) {
|
|
111
|
+
this.em.on(connectionCreatedConst, resolve);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (this.connection !== null) {
|
|
115
|
+
return resolve(this.connection);
|
|
116
|
+
}
|
|
117
|
+
this.creatingConnection = true;
|
|
118
|
+
const host = process.env.RABBITMQ_SERVICE_HOST || '';
|
|
119
|
+
const connection = yield amqp_connection_manager_1.connect([`amqp://${host}`]);
|
|
120
|
+
this.connection = connection;
|
|
121
|
+
this.connection.on('disconnect', ({ err }) => {
|
|
122
|
+
var _a;
|
|
123
|
+
if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.reconnect) {
|
|
124
|
+
console.error(`${this.RESCONNECT_MSG}${err && ` - ${err}`}`);
|
|
125
|
+
this.connection = null;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
console.error(`${this.DISCONNECT_MSG}${err && ` - ${err}`}`);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
this.creatingConnection = false;
|
|
132
|
+
this.em.emit(connectionCreatedConst, connection);
|
|
133
|
+
resolve(connection);
|
|
134
|
+
}));
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
getNewChannel() {
|
|
138
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
139
|
+
const connection = yield this.getConnection();
|
|
140
|
+
return connection.createChannel({});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
assertChannel() {
|
|
144
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
145
|
+
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
146
|
+
if (this.channel) {
|
|
147
|
+
return resolve(this.channel);
|
|
148
|
+
}
|
|
149
|
+
const connection = yield this.getConnection();
|
|
150
|
+
try {
|
|
151
|
+
if (this.channel === null) {
|
|
152
|
+
this.channel = connection.createChannel({});
|
|
153
|
+
}
|
|
154
|
+
resolve(this.channel);
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
reject(e);
|
|
158
|
+
}
|
|
159
|
+
}));
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
assertExchange(exchangeName, options) {
|
|
163
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
164
|
+
const channel = yield this.assertChannel();
|
|
165
|
+
if (this.exchanges[exchangeName]) {
|
|
166
|
+
return this.exchanges[exchangeName];
|
|
167
|
+
}
|
|
168
|
+
return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
|
|
169
|
+
const exchange = yield assertExchangeFanout(c, exchangeName);
|
|
170
|
+
this.exchanges[exchangeName] = exchange;
|
|
171
|
+
return exchange;
|
|
172
|
+
}));
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
getQueueLength(queue) {
|
|
176
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
177
|
+
RabbitMq.validateName('queue', queue);
|
|
178
|
+
const channel = yield this.assertChannel();
|
|
179
|
+
// @ts-ignore
|
|
180
|
+
return channel.checkQueue(queue);
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
bindQueue(queue, exchange) {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
const channel = yield this.assertChannel();
|
|
186
|
+
// @ts-ignore
|
|
187
|
+
return channel.bindQueue(queue, exchange, '');
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
assertQueue(queue, options) {
|
|
191
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
192
|
+
RabbitMq.validateName('queue', queue);
|
|
193
|
+
const channel = yield this.assertChannel();
|
|
194
|
+
return channel.addSetup((c) => c.assertQueue(queue, options));
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
consume(queue, callback, options) {
|
|
198
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
+
const optionsWithDefaults = Object.assign(Object.assign({}, defaultOptions), options);
|
|
200
|
+
RabbitMq.validateName('queue', queue);
|
|
201
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
202
|
+
const channel = yield this.getNewChannel();
|
|
203
|
+
return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
|
|
204
|
+
yield c.assertQueue(queue);
|
|
205
|
+
yield c.prefetch(limit, true);
|
|
206
|
+
return Promise.all([
|
|
207
|
+
c.consume(queue, (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
208
|
+
var _a;
|
|
209
|
+
outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
|
|
210
|
+
if (optionsWithDefaults.timeout) {
|
|
211
|
+
const args = [
|
|
212
|
+
RabbitMq.parseMsg(msg),
|
|
213
|
+
this.ack(channel),
|
|
214
|
+
this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }),
|
|
215
|
+
];
|
|
216
|
+
try {
|
|
217
|
+
yield callbackWithTimeout(callback, args, optionsWithDefaults.timeout, optionsWithDefaults.timeoutMessage);
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.error('message nacked because of error in callbackWithTimeout', {
|
|
221
|
+
error: e,
|
|
222
|
+
msg,
|
|
223
|
+
});
|
|
224
|
+
this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
callback(RabbitMq.parseMsg(msg), this.ack(channel), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
229
|
+
}
|
|
230
|
+
})),
|
|
231
|
+
]);
|
|
232
|
+
}));
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
consumeFromExchange(queue, exchange, callback, options) {
|
|
236
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
237
|
+
const optionsWithDefaults = Object.assign(Object.assign({}, defaultOptions), options);
|
|
238
|
+
RabbitMq.validateName('exchange', exchange);
|
|
239
|
+
RabbitMq.validateName('queue', queue);
|
|
240
|
+
const { limit, deadMessageTtl } = optionsWithDefaults;
|
|
241
|
+
const channel = yield this.getNewChannel();
|
|
242
|
+
return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
|
|
243
|
+
const assertExchange = yield assertExchangeFanout(c, exchange);
|
|
244
|
+
yield c.assertQueue(queue);
|
|
245
|
+
this.exchanges[exchange] = assertExchange;
|
|
246
|
+
yield c.prefetch(limit, true);
|
|
247
|
+
return Promise.all([
|
|
248
|
+
c.bindQueue(queue, exchange, ''),
|
|
249
|
+
c.consume(queue, (msg) => {
|
|
250
|
+
outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
|
|
251
|
+
callback(RabbitMq.parseMsg(msg), this.ack(channel), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
252
|
+
}),
|
|
253
|
+
]);
|
|
254
|
+
}));
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
publish(exchange, content) {
|
|
258
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
259
|
+
RabbitMq.validateName('exchange', exchange);
|
|
260
|
+
const channel = yield this.assertChannel();
|
|
261
|
+
yield this.assertExchange(exchange);
|
|
262
|
+
return new bluebird.Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
263
|
+
try {
|
|
264
|
+
yield channel.publish(exchange, '', Buffer.from(JSON.stringify(content)));
|
|
265
|
+
return resolve();
|
|
266
|
+
}
|
|
267
|
+
catch (e) {
|
|
268
|
+
reject(e);
|
|
269
|
+
}
|
|
270
|
+
})).timeout(this.PUBLISH_TIMEOUT, `${this.PUBLISH_ERROR_MSG}${exchange}`);
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
sendToQueue(queue, content, options) {
|
|
274
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
275
|
+
RabbitMq.validateName('queue', queue);
|
|
276
|
+
const channel = yield this.assertChannel();
|
|
277
|
+
yield this.assertQueue(queue, options);
|
|
278
|
+
return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)));
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
exports.default = RabbitMq;
|
package/dist/mock.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import 'jest';
|
|
2
|
+
import { IAfRabbitMq } from './index';
|
|
3
|
+
declare class RabbitMq implements IAfRabbitMq {
|
|
4
|
+
ack: any;
|
|
5
|
+
nack: any;
|
|
6
|
+
assertChannel: any;
|
|
7
|
+
assertExchange: any;
|
|
8
|
+
assertQueue: any;
|
|
9
|
+
consume: any;
|
|
10
|
+
consumeFromExchange: any;
|
|
11
|
+
publish: any;
|
|
12
|
+
sendToQueue: any;
|
|
13
|
+
}
|
|
14
|
+
export default RabbitMq;
|
package/dist/mock.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
4
|
+
require("jest");
|
|
5
|
+
class RabbitMq {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.ack = jest.fn();
|
|
8
|
+
this.nack = jest.fn();
|
|
9
|
+
this.assertChannel = jest.fn();
|
|
10
|
+
this.assertExchange = jest.fn();
|
|
11
|
+
this.assertQueue = jest.fn();
|
|
12
|
+
this.consume = jest.fn();
|
|
13
|
+
this.consumeFromExchange = jest.fn();
|
|
14
|
+
this.publish = jest.fn();
|
|
15
|
+
this.sendToQueue = jest.fn();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.default = RabbitMq;
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/rabbit",
|
|
3
|
-
"version": "2.0.4-
|
|
3
|
+
"version": "2.0.4-beta5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"postinstall": "echo '\\033[0;31m\nWARNING: in case of migrating to new version of @autofleet/rabbit \nyou might have to delete existing queues or the deployment will fail.\\033[0m\n'",
|
|
8
8
|
"start": "ts-node src/index.ts",
|
|
9
9
|
"example": "ts-node src/example.ts",
|
|
10
|
-
"build": "tsc",
|
|
10
|
+
"build": "rm -rf dist && tsc",
|
|
11
|
+
"prepublish": "npm run build",
|
|
11
12
|
"linter": "./node_modules/.bin/eslint .",
|
|
12
13
|
"test": "jest --forceExit",
|
|
13
14
|
"test-local": "RABBITMQ_SERVICE_HOST=10.132.0.98:5672 jest --forceExit",
|
package/src/index.ts
CHANGED
|
@@ -38,17 +38,14 @@ const defaultOptions = {
|
|
|
38
38
|
const assertExchangeFanout = (c: any, exchangeName: string) => c.assertExchange(exchangeName, 'fanout');
|
|
39
39
|
|
|
40
40
|
const callbackWithTimeout = async (callback: any, args: any[], timeout: number, timeoutMessage = 'Timeout while ack message') => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}, timeout);
|
|
50
|
-
}),
|
|
51
|
-
]);
|
|
41
|
+
await new bluebird.Promise(async (resolve, reject) => {
|
|
42
|
+
try {
|
|
43
|
+
await callback(...args);
|
|
44
|
+
return resolve();
|
|
45
|
+
} catch (e) {
|
|
46
|
+
return reject(e);
|
|
47
|
+
}
|
|
48
|
+
}).timeout(timeout, timeoutMessage);
|
|
52
49
|
};
|
|
53
50
|
|
|
54
51
|
const connectionCreatedConst = 'connectionCreated';
|
|
@@ -93,13 +90,16 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
93
90
|
|
|
94
91
|
options: AfRabbitOptions | undefined;
|
|
95
92
|
|
|
96
|
-
|
|
93
|
+
logger: any;
|
|
94
|
+
|
|
95
|
+
constructor({ options, logger }: { options?: AfRabbitOptions, logger?: any} = {}) {
|
|
97
96
|
this.em = new EventEmitter();
|
|
98
97
|
this.channel = null;
|
|
99
98
|
this.connection = null;
|
|
100
99
|
this.creatingConnection = false;
|
|
101
100
|
this.exchanges = {};
|
|
102
101
|
this.options = options;
|
|
102
|
+
this.logger = logger;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
public ack = (channel: ChannelWrapper) => async (msg: any) => {
|
|
@@ -124,7 +124,6 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
124
124
|
|| msg.content['x-retry-count'] < options.retries)
|
|
125
125
|
) {
|
|
126
126
|
msg.content['x-retry-count'] = msg.content['x-retry-count'] ? msg.content['x-retry-count'] + 1 : 1;
|
|
127
|
-
// msg.content.nackCount = msg.content.nackCount ? msg.content.nackCount + 1 : 1;
|
|
128
127
|
await this.sendToQueue(queue, msg.content);
|
|
129
128
|
} else {
|
|
130
129
|
const deadQueue = `${queue}-dead`;
|
|
@@ -240,6 +239,10 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
240
239
|
try {
|
|
241
240
|
await callbackWithTimeout(callback, args, optionsWithDefaults.timeout, optionsWithDefaults.timeoutMessage);
|
|
242
241
|
} catch (e) {
|
|
242
|
+
this.logger?.error('message nacked because of error in callbackWithTimeout', {
|
|
243
|
+
error: e,
|
|
244
|
+
msg,
|
|
245
|
+
});
|
|
243
246
|
this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl });
|
|
244
247
|
}
|
|
245
248
|
} else {
|