@autofleet/rabbit 2.3.6 → 2.3.7

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-new.js DELETED
@@ -1,327 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- /* 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 */
16
- // eslint-disable-next-line max-classes-per-file
17
- const moment_1 = __importDefault(require("moment"));
18
- const redis_lock_1 = __importDefault(require("redis-lock"));
19
- const amqp_connection_manager_1 = require("amqp-connection-manager");
20
- const events_1 = require("events");
21
- // import { newTrace, traceTypes } from '@autofleet/outbreak';
22
- const util_1 = require("util");
23
- const logger_1 = __importDefault(require("./logger"));
24
- const rabbitError_1 = __importDefault(require("./rabbitError"));
25
- const redis_1 = __importDefault(require("./redis"));
26
- const DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 48;
27
- const DEFAULT_LOCK_TIMEOUT = 1000 * 5;
28
- const RETRY_HEADER = 'x-retry-count';
29
- const DEFAULT_USE_CONSUME_WITH_LOCK = false;
30
- const defaultOptions = {
31
- limit: 1,
32
- retries: 1,
33
- deadMessageTtl: DEFAULT_DEAD_TTL_TWO_DAYS,
34
- lockTimeout: DEFAULT_LOCK_TIMEOUT,
35
- useConsumeWithLock: DEFAULT_USE_CONSUME_WITH_LOCK,
36
- };
37
- const assertExchangeFanout = (c, exchangeName) => __awaiter(void 0, void 0, void 0, function* () { return c.assertExchange(exchangeName, 'fanout'); });
38
- const connectionCreatedConst = 'connectionCreated';
39
- const wrapSetImmediate = (callback) => new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
40
- setImmediate(() => __awaiter(void 0, void 0, void 0, function* () {
41
- try {
42
- const value = yield callback();
43
- resolve(value);
44
- }
45
- catch (error) {
46
- reject(error);
47
- }
48
- }));
49
- }));
50
- class RabbitMq {
51
- constructor(options, redisConfig) {
52
- var _a;
53
- this.PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
54
- this.PUBLISH_ERROR_MSG = `rabbit: publish timeout(${this.PUBLISH_TIMEOUT}ms) has pass, exchange: `;
55
- this.DISCONNECT_MSG = 'rabbit: connection disconnect';
56
- this.RESCONNECT_MSG = 'rabbit: reconnecting';
57
- this.shouldConsumeMessageByTimestamp = (msg) => __awaiter(this, void 0, void 0, function* () {
58
- if (msg) {
59
- const { properties: { headers } } = msg;
60
- const timestamp = headers === null || headers === void 0 ? void 0 : headers.creationTimestamp;
61
- if (timestamp && (headers === null || headers === void 0 ? void 0 : headers.redisTimestampValidationKey) && this.redisClient) {
62
- const lastMessageTimestamp = yield this.redisClient.getAsync(headers.redisTimestampValidationKey);
63
- return !lastMessageTimestamp || (parseInt(lastMessageTimestamp, 10) <= parseInt(timestamp, 10));
64
- }
65
- return true;
66
- }
67
- return false;
68
- });
69
- this.ack = (channel, msg, shouldUpdateRedisTimestamp = false, releaseLock = null) => (userMsg) => __awaiter(this, void 0, void 0, function* () {
70
- if (msg) {
71
- yield channel.ack(msg);
72
- const { properties: { headers } } = msg;
73
- const timestamp = headers === null || headers === void 0 ? void 0 : headers.creationTimestamp;
74
- if (shouldUpdateRedisTimestamp && timestamp && (headers === null || headers === void 0 ? void 0 : headers.redisTimestampValidationKey) && this.redisClient) {
75
- const parsedTimestamp = parseInt(timestamp, 10);
76
- yield this.redisClient.setAsync(headers.redisTimestampValidationKey, parsedTimestamp, 'EX', 3600);
77
- yield this.unlockRedisIfNeeded(releaseLock);
78
- }
79
- }
80
- });
81
- this.nack = (channel, queue, options, deadQueueOptions, msg, releaseLock) => (userMsg, { skipRetry = false, } = {}) => __awaiter(this, void 0, void 0, function* () {
82
- yield this.unlockRedisIfNeeded(releaseLock);
83
- if (channel && msg) {
84
- if (!skipRetry
85
- && (!msg.properties.headers[RETRY_HEADER]
86
- || parseInt(msg.properties.headers[RETRY_HEADER], 10) < options.retries)) {
87
- yield this.sendToQueue(queue, RabbitMq.parseMsg(msg).content, options, Object.assign(Object.assign({}, msg.properties.headers), { [RETRY_HEADER]: msg.properties.headers[RETRY_HEADER]
88
- ? msg.properties.headers[RETRY_HEADER] + 1
89
- : 1 }));
90
- }
91
- else {
92
- const deadQueue = `${queue}-dead`;
93
- yield this.sendToQueue(deadQueue, RabbitMq.parseMsg(msg).content, deadQueueOptions, Object.assign(Object.assign({}, msg.properties.headers), { [RETRY_HEADER]: msg.properties.headers[RETRY_HEADER]
94
- ? msg.properties.headers[RETRY_HEADER] + 1
95
- : 1 }));
96
- }
97
- yield channel.ack(msg);
98
- }
99
- });
100
- this.em = new events_1.EventEmitter();
101
- this.channel = null;
102
- this.connection = null;
103
- this.creatingConnection = false;
104
- this.exchanges = {};
105
- this.queues = {};
106
- this.options = options;
107
- this.host = (_a = options === null || options === void 0 ? void 0 : options.host) !== null && _a !== void 0 ? _a : null;
108
- this.redisClient = redisConfig && redis_1.default(redisConfig);
109
- if (this.redisClient) {
110
- this.redisLock = util_1.promisify(redis_lock_1.default(this.redisClient));
111
- }
112
- }
113
- static parseMsg(msg) {
114
- let { content } = msg;
115
- content = content.toString();
116
- try {
117
- content = JSON.parse(content);
118
- }
119
- catch (e) { }
120
- return Object.assign(Object.assign({}, msg), { content });
121
- }
122
- static validateName(type, name) {
123
- if (!name || name === '') {
124
- throw new rabbitError_1.default(`error while using ${type} with no name`);
125
- }
126
- }
127
- static getPublishOptions(customHeaders = {}) {
128
- return {
129
- timestamp: moment_1.default().unix(),
130
- headers: Object.assign({ creationTimestamp: moment_1.default().valueOf() }, customHeaders),
131
- };
132
- }
133
- getConnection() {
134
- return __awaiter(this, void 0, void 0, function* () {
135
- return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
136
- if (this.connection !== null) {
137
- return resolve(this.connection);
138
- }
139
- if (this.creatingConnection) {
140
- this.em.once(connectionCreatedConst, resolve);
141
- return;
142
- }
143
- this.creatingConnection = true;
144
- logger_1.default.info('rabbit: env username', { userName: (process.env.RABBITMQ_USERNAME || 'doesnt exist') });
145
- const username = process.env.RABBITMQ_USERNAME || 'guest';
146
- const password = process.env.RABBITMQ_PASSWORD || 'guest';
147
- const host = this.host || process.env.RABBITMQ_SERVICE_HOST || '';
148
- const connection = yield amqp_connection_manager_1.connect([`amqp://${username}:${password}@${host}`], { reconnectTimeInSeconds: 0.5 });
149
- this.connection = connection;
150
- this.creatingConnection = false;
151
- this.em.emit(connectionCreatedConst, connection);
152
- resolve(connection);
153
- }));
154
- });
155
- }
156
- getNewChannel() {
157
- return __awaiter(this, void 0, void 0, function* () {
158
- const connection = yield this.getConnection();
159
- return connection.createChannel({});
160
- });
161
- }
162
- assertChannel() {
163
- return __awaiter(this, void 0, void 0, function* () {
164
- return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
165
- if (this.channel) {
166
- return resolve(this.channel);
167
- }
168
- try {
169
- const connection = yield this.getConnection();
170
- if (this.channel === null) {
171
- this.channel = yield connection.createChannel({});
172
- }
173
- resolve(this.channel);
174
- }
175
- catch (e) {
176
- reject(e);
177
- }
178
- }));
179
- });
180
- }
181
- assertExchange(exchangeName, options) {
182
- return __awaiter(this, void 0, void 0, function* () {
183
- const channel = yield this.assertChannel();
184
- if (this.exchanges[exchangeName]) {
185
- return this.exchanges[exchangeName];
186
- }
187
- const exchange = yield assertExchangeFanout(channel, exchangeName);
188
- this.exchanges[exchangeName] = exchange;
189
- return exchange;
190
- });
191
- }
192
- getQueueLength(queue) {
193
- return __awaiter(this, void 0, void 0, function* () {
194
- RabbitMq.validateName('queue', queue);
195
- const channel = yield this.assertChannel();
196
- // @ts-ignore
197
- return channel.checkQueue(queue);
198
- });
199
- }
200
- bindQueue(queue, exchange) {
201
- return __awaiter(this, void 0, void 0, function* () {
202
- const channel = yield this.assertChannel();
203
- yield channel.addSetup((setupChannel) => setupChannel.bindQueue(queue, exchange, ''));
204
- // @ts-ignore
205
- return channel.bindQueue(queue, exchange, '');
206
- });
207
- }
208
- assertQueue(queueName, options) {
209
- return __awaiter(this, void 0, void 0, function* () {
210
- RabbitMq.validateName('queue', queueName);
211
- const channel = yield this.assertChannel();
212
- if (this.queues[queueName]) {
213
- return this.queues[queueName];
214
- }
215
- yield channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, options));
216
- const queue = yield channel.assertQueue(queueName, options);
217
- this.queues[queueName] = queueName;
218
- return queue;
219
- });
220
- }
221
- consume(queue, callback, options) {
222
- return __awaiter(this, void 0, void 0, function* () {
223
- return this.consumeFromRabbit(queue, callback, options);
224
- });
225
- }
226
- lockRedisIfNeeded(msg, options) {
227
- return __awaiter(this, void 0, void 0, function* () {
228
- const { properties: { headers } } = msg;
229
- const timestamp = headers === null || headers === void 0 ? void 0 : headers.creationTimestamp;
230
- let releaseLock = null;
231
- if (options.useConsumeWithLock && timestamp && (headers === null || headers === void 0 ? void 0 : headers.redisTimestampValidationKey) && this.redisLock) {
232
- releaseLock = yield this.redisLock(headers.redisTimestampValidationKey, (options === null || options === void 0 ? void 0 : options.lockTimeout) || DEFAULT_LOCK_TIMEOUT);
233
- }
234
- return releaseLock;
235
- });
236
- }
237
- unlockRedisIfNeeded(releaseLock) {
238
- return __awaiter(this, void 0, void 0, function* () {
239
- if (this.redisLock && releaseLock) {
240
- yield releaseLock();
241
- }
242
- });
243
- }
244
- consumeFromRabbit(queue, callback, options) {
245
- return __awaiter(this, void 0, void 0, function* () {
246
- const optionsWithDefaults = Object.assign(Object.assign({}, defaultOptions), options);
247
- RabbitMq.validateName('queue', queue);
248
- const { limit, deadMessageTtl, useConsumeWithLock, lockTimeout, } = optionsWithDefaults;
249
- if (useConsumeWithLock) {
250
- if (!this.redisLock) {
251
- throw new Error('Usage of consumeWithLock requires RedisInstance');
252
- }
253
- logger_1.default.info(`Consuming with lock from queue ${queue} with lockTimeout: ${lockTimeout}ms`);
254
- }
255
- const channel = yield this.getNewChannel();
256
- return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
257
- yield c.assertQueue(queue);
258
- yield c.prefetch(limit, true);
259
- return Promise.all([
260
- c.consume(queue, (msg) => __awaiter(this, void 0, void 0, function* () {
261
- if (!msg) {
262
- return null;
263
- }
264
- const parsedMessage = RabbitMq.parseMsg(msg);
265
- const releaseLock = yield this.lockRedisIfNeeded(parsedMessage, optionsWithDefaults);
266
- const shouldConsume = yield this.shouldConsumeMessageByTimestamp(parsedMessage);
267
- if (!shouldConsume) {
268
- yield this.unlockRedisIfNeeded(releaseLock);
269
- return this.ack(channel, msg)(msg);
270
- }
271
- try {
272
- yield callback(parsedMessage, this.ack(channel, msg, true, releaseLock), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock));
273
- }
274
- catch (e) {
275
- yield this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }, msg, releaseLock)(msg);
276
- }
277
- })),
278
- ]);
279
- }));
280
- });
281
- }
282
- consumeFromExchange(queue, exchange, callback, options) {
283
- return __awaiter(this, void 0, void 0, function* () {
284
- const optionsWithDefaults = Object.assign(Object.assign({}, defaultOptions), options);
285
- RabbitMq.validateName('exchange', exchange);
286
- RabbitMq.validateName('queue', queue);
287
- const { limit, deadMessageTtl } = optionsWithDefaults;
288
- const channel = yield this.getNewChannel();
289
- return channel.addSetup((c) => __awaiter(this, void 0, void 0, function* () {
290
- yield assertExchangeFanout(c, exchange);
291
- yield c.assertQueue(queue);
292
- yield c.prefetch(limit, true);
293
- return Promise.all([
294
- c.bindQueue(queue, exchange, ''),
295
- this.consume(queue, callback, options),
296
- ]);
297
- }));
298
- });
299
- }
300
- publish(exchange, content, customHeaders) {
301
- return __awaiter(this, void 0, void 0, function* () {
302
- return wrapSetImmediate(() => __awaiter(this, void 0, void 0, function* () {
303
- RabbitMq.validateName('exchange', exchange);
304
- const channel = yield this.assertChannel();
305
- yield this.assertExchange(exchange);
306
- yield channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
307
- }));
308
- });
309
- }
310
- sendToQueue(queue, content, options, customHeaders) {
311
- return __awaiter(this, void 0, void 0, function* () {
312
- return wrapSetImmediate(() => __awaiter(this, void 0, void 0, function* () {
313
- RabbitMq.validateName('queue', queue);
314
- const channel = yield this.assertChannel();
315
- yield this.assertQueue(queue, options);
316
- return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
317
- }));
318
- });
319
- }
320
- isConnected() {
321
- return __awaiter(this, void 0, void 0, function* () {
322
- const connection = yield this.getConnection();
323
- return connection.isConnected();
324
- });
325
- }
326
- }
327
- exports.default = RabbitMq;
@@ -1 +0,0 @@
1
- export {};
@@ -1,54 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- /* eslint-disable no-await-in-loop */
16
- // eslint-disable-next-line import/no-extraneous-dependencies
17
- const node_tcp_proxy_1 = __importDefault(require("node-tcp-proxy"));
18
- const index_new_1 = __importDefault(require("./index-new"));
19
- const delay = (ms = 1000) => new Promise((resolve) => setTimeout(() => resolve(), ms));
20
- const callback = (eq, timeout = 0) => (msg, ack, nack) => __awaiter(void 0, void 0, void 0, function* () {
21
- setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
22
- // console.log(msg)
23
- yield ack(msg);
24
- }), timeout);
25
- return null;
26
- });
27
- const payload = { ttt: 123 };
28
- const testId = 'www';
29
- const main = () => __awaiter(void 0, void 0, void 0, function* () {
30
- const port = 6672;
31
- const createProxy = () => node_tcp_proxy_1.default.createProxy(port, '0.0.0.0', 5672);
32
- const restartProxy = (currentProxy, sleep) => __awaiter(void 0, void 0, void 0, function* () {
33
- currentProxy.end();
34
- yield delay(sleep);
35
- return node_tcp_proxy_1.default.createProxy(port, '0.0.0.0', 5672);
36
- });
37
- let currentProxy = createProxy();
38
- const rabbit = new index_new_1.default({ host: `127.0.0.1:${port}` });
39
- const queue = `test-timestamp-validation-${testId}`;
40
- const mockFn = callback(payload);
41
- yield rabbit.consume(queue, mockFn);
42
- console.error('start');
43
- const usedB = process.memoryUsage().heapUsed / 1024 / 1024;
44
- console.log('Used before', usedB);
45
- for (let i = 0; i < 10000; i += 1) {
46
- // currentProxy = await restartProxy(currentProxy, 100);
47
- yield rabbit.sendToQueue(queue, payload);
48
- yield delay(10);
49
- // expect(mockFn).toBeCalledTimes(i);
50
- const used = process.memoryUsage().heapUsed / 1024 / 1024;
51
- console.error('Used', i, used);
52
- }
53
- });
54
- main();
package/dump.rdb DELETED
Binary file