@autofleet/rabbit 2.0.4 → 2.1.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 +13 -5
- package/dist/index.js +44 -14
- package/dist/redis.d.ts +7 -0
- package/dist/redis.js +11 -0
- package/package.json +6 -2
- package/src/index.ts +56 -13
- package/src/redis.ts +15 -0
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Options } from 'amqplib';
|
|
3
3
|
import { AmqpConnectionManager, ChannelWrapper } from 'amqp-connection-manager';
|
|
4
4
|
import { EventEmitter } from 'events';
|
|
5
|
+
import { RedisConfig } from './redis';
|
|
5
6
|
export interface IAfRabbitMq {
|
|
6
7
|
ack: any;
|
|
7
8
|
nack: any;
|
|
@@ -12,18 +13,23 @@ export interface IAfRabbitMq {
|
|
|
12
13
|
consumeFromExchange: any;
|
|
13
14
|
publish: any;
|
|
14
15
|
sendToQueue: any;
|
|
16
|
+
redisClient?: any;
|
|
15
17
|
}
|
|
16
18
|
interface ExchangesCache {
|
|
17
19
|
[key: string]: any;
|
|
18
20
|
}
|
|
21
|
+
declare type CustomMessageHeaders = {
|
|
22
|
+
redisTimestampValidationKey?: string;
|
|
23
|
+
};
|
|
19
24
|
export interface AfRabbitOptions {
|
|
20
25
|
reconnect: boolean;
|
|
21
26
|
}
|
|
22
27
|
declare class RabbitMq implements IAfRabbitMq {
|
|
23
28
|
static parseMsg(msg: any): any;
|
|
24
29
|
static validateName(type: string, name: string): void;
|
|
25
|
-
static getPublishOptions(): {
|
|
30
|
+
static getPublishOptions(customHeaders?: CustomMessageHeaders): {
|
|
26
31
|
timestamp: number;
|
|
32
|
+
headers: CustomMessageHeaders;
|
|
27
33
|
};
|
|
28
34
|
PUBLISH_TIMEOUT: number;
|
|
29
35
|
PUBLISH_ERROR_MSG: string;
|
|
@@ -35,8 +41,10 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
35
41
|
creatingConnection: boolean;
|
|
36
42
|
exchanges: ExchangesCache;
|
|
37
43
|
options: AfRabbitOptions | undefined;
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
redisClient: any;
|
|
45
|
+
constructor(options?: AfRabbitOptions, redisConfig?: RedisConfig);
|
|
46
|
+
private shouldConsumeMessageByTimestamp;
|
|
47
|
+
ack: (channel: ChannelWrapper, shouldUpdateRedisTimestamp?: boolean) => (msg: any) => Promise<void>;
|
|
40
48
|
nack: (channel: ChannelWrapper, queue: string, options: any, deadQueueOptions: Options.AssertQueue) => (msg: any, { skipRetry, }?: any) => Promise<void>;
|
|
41
49
|
getConnection(): Promise<AmqpConnectionManager>;
|
|
42
50
|
getNewChannel(): Promise<ChannelWrapper>;
|
|
@@ -47,7 +55,7 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
47
55
|
assertQueue(queue: string, options?: Options.AssertQueue): Promise<void>;
|
|
48
56
|
consume(queue: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
|
|
49
57
|
consumeFromExchange(queue: string, exchange: string, callback: (msg: any, ack: Function, nack: Function) => any, options?: any): Promise<void>;
|
|
50
|
-
publish(exchange: string, content: any): Promise<unknown>;
|
|
51
|
-
sendToQueue(queue: string, content: any, options?: any): Promise<void>;
|
|
58
|
+
publish(exchange: string, content: any, customHeaders?: any): Promise<unknown>;
|
|
59
|
+
sendToQueue(queue: string, content: any, options?: any, customHeaders?: any): Promise<void>;
|
|
52
60
|
}
|
|
53
61
|
export default RabbitMq;
|
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ const amqp_connection_manager_1 = require("amqp-connection-manager");
|
|
|
39
39
|
const events_1 = require("events");
|
|
40
40
|
const outbreak_1 = require("@autofleet/outbreak");
|
|
41
41
|
const rabbitError_1 = __importDefault(require("./rabbitError"));
|
|
42
|
+
const redis_1 = __importDefault(require("./redis"));
|
|
42
43
|
const DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 48;
|
|
43
44
|
const defaultOptions = {
|
|
44
45
|
limit: 1,
|
|
@@ -48,13 +49,26 @@ const defaultOptions = {
|
|
|
48
49
|
const assertExchangeFanout = (c, exchangeName) => c.assertExchange(exchangeName, 'fanout');
|
|
49
50
|
const connectionCreatedConst = 'connectionCreated';
|
|
50
51
|
class RabbitMq {
|
|
51
|
-
constructor(options) {
|
|
52
|
+
constructor(options, redisConfig) {
|
|
52
53
|
this.PUBLISH_TIMEOUT = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT) || 60000;
|
|
53
54
|
this.PUBLISH_ERROR_MSG = `rabbit: publish timeout(${this.PUBLISH_TIMEOUT}ms) has pass, exchange: `;
|
|
54
55
|
this.DISCONNECT_MSG = 'rabbit: connection disconnect';
|
|
55
56
|
this.RESCONNECT_MSG = 'rabbit: reconnecting';
|
|
56
|
-
this.
|
|
57
|
+
this.shouldConsumeMessageByTimestamp = (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
const { properties: { timestamp, headers } } = msg;
|
|
59
|
+
if (timestamp && (headers === null || headers === void 0 ? void 0 : headers.redisTimestampValidationKey) && this.redisClient) {
|
|
60
|
+
const lastMessageTimestamp = yield this.redisClient.getAsync(headers.redisTimestampValidationKey);
|
|
61
|
+
return !lastMessageTimestamp || !moment_1.default(parseInt(lastMessageTimestamp, 10)).isAfter(moment_1.default(timestamp));
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
});
|
|
65
|
+
this.ack = (channel, shouldUpdateRedisTimestamp = false) => (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
57
66
|
yield channel.ack(msg);
|
|
67
|
+
const { properties: { timestamp, headers } } = msg;
|
|
68
|
+
if (shouldUpdateRedisTimestamp && timestamp && (headers === null || headers === void 0 ? void 0 : headers.redisTimestampValidationKey) && this.redisClient) {
|
|
69
|
+
const parsedTimestamp = parseInt(timestamp, 10);
|
|
70
|
+
yield this.redisClient.setAsync(headers.redisTimestampValidationKey, parsedTimestamp);
|
|
71
|
+
}
|
|
58
72
|
});
|
|
59
73
|
this.nack = (channel, queue, options, deadQueueOptions) => (msg, { skipRetry = false, } = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
60
74
|
if (channel) {
|
|
@@ -78,6 +92,7 @@ class RabbitMq {
|
|
|
78
92
|
this.creatingConnection = false;
|
|
79
93
|
this.exchanges = {};
|
|
80
94
|
this.options = options;
|
|
95
|
+
this.redisClient = redisConfig && redis_1.default(redisConfig);
|
|
81
96
|
}
|
|
82
97
|
static parseMsg(msg) {
|
|
83
98
|
let { content } = msg;
|
|
@@ -93,9 +108,10 @@ class RabbitMq {
|
|
|
93
108
|
throw new rabbitError_1.default(`error while using ${type} with no name`);
|
|
94
109
|
}
|
|
95
110
|
}
|
|
96
|
-
static getPublishOptions() {
|
|
111
|
+
static getPublishOptions(customHeaders = {}) {
|
|
97
112
|
return {
|
|
98
113
|
timestamp: moment_1.default().unix() * 1000,
|
|
114
|
+
headers: customHeaders,
|
|
99
115
|
};
|
|
100
116
|
}
|
|
101
117
|
getConnection() {
|
|
@@ -109,8 +125,10 @@ class RabbitMq {
|
|
|
109
125
|
return resolve(this.connection);
|
|
110
126
|
}
|
|
111
127
|
this.creatingConnection = true;
|
|
128
|
+
const username = process.env.RABBITMQ_USERNAME || 'guest';
|
|
129
|
+
const password = process.env.RABBITMQ_PASSWORD || 'guest';
|
|
112
130
|
const host = process.env.RABBITMQ_SERVICE_HOST || '';
|
|
113
|
-
const connection = yield amqp_connection_manager_1.connect([`amqp://${host}`]);
|
|
131
|
+
const connection = yield amqp_connection_manager_1.connect([`amqp://${username}:${password}@${host}`]);
|
|
114
132
|
this.connection = connection;
|
|
115
133
|
this.connection.on('disconnect', ({ err }) => {
|
|
116
134
|
var _a;
|
|
@@ -198,10 +216,16 @@ class RabbitMq {
|
|
|
198
216
|
yield c.assertQueue(queue);
|
|
199
217
|
yield c.prefetch(limit, true);
|
|
200
218
|
return Promise.all([
|
|
201
|
-
c.consume(queue, (msg) => {
|
|
219
|
+
c.consume(queue, (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
220
|
+
const parsedMessage = RabbitMq.parseMsg(msg);
|
|
202
221
|
outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
|
|
203
|
-
|
|
204
|
-
|
|
222
|
+
const shouldConsume = yield this.shouldConsumeMessageByTimestamp(parsedMessage);
|
|
223
|
+
if (!shouldConsume) {
|
|
224
|
+
this.ack(channel);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
callback(parsedMessage, this.ack(channel, true), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
228
|
+
})),
|
|
205
229
|
]);
|
|
206
230
|
}));
|
|
207
231
|
});
|
|
@@ -220,22 +244,28 @@ class RabbitMq {
|
|
|
220
244
|
yield c.prefetch(limit, true);
|
|
221
245
|
return Promise.all([
|
|
222
246
|
c.bindQueue(queue, exchange, ''),
|
|
223
|
-
c.consume(queue, (msg) => {
|
|
247
|
+
c.consume(queue, (msg) => __awaiter(this, void 0, void 0, function* () {
|
|
248
|
+
const parsedMessage = RabbitMq.parseMsg(msg);
|
|
224
249
|
outbreak_1.newTrace(outbreak_1.traceTypes.RABBIT);
|
|
225
|
-
|
|
226
|
-
|
|
250
|
+
const shouldConsume = yield this.shouldConsumeMessageByTimestamp(parsedMessage);
|
|
251
|
+
if (!shouldConsume) {
|
|
252
|
+
this.ack(channel);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
callback(parsedMessage, this.ack(channel, true), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
256
|
+
})),
|
|
227
257
|
]);
|
|
228
258
|
}));
|
|
229
259
|
});
|
|
230
260
|
}
|
|
231
|
-
publish(exchange, content) {
|
|
261
|
+
publish(exchange, content, customHeaders) {
|
|
232
262
|
return __awaiter(this, void 0, void 0, function* () {
|
|
233
263
|
RabbitMq.validateName('exchange', exchange);
|
|
234
264
|
const channel = yield this.assertChannel();
|
|
235
265
|
yield this.assertExchange(exchange);
|
|
236
266
|
return new bluebird.Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
237
267
|
try {
|
|
238
|
-
yield channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions());
|
|
268
|
+
yield channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
239
269
|
return resolve();
|
|
240
270
|
}
|
|
241
271
|
catch (e) {
|
|
@@ -244,12 +274,12 @@ class RabbitMq {
|
|
|
244
274
|
})).timeout(this.PUBLISH_TIMEOUT, `${this.PUBLISH_ERROR_MSG}${exchange}`);
|
|
245
275
|
});
|
|
246
276
|
}
|
|
247
|
-
sendToQueue(queue, content, options) {
|
|
277
|
+
sendToQueue(queue, content, options, customHeaders) {
|
|
248
278
|
return __awaiter(this, void 0, void 0, function* () {
|
|
249
279
|
RabbitMq.validateName('queue', queue);
|
|
250
280
|
const channel = yield this.assertChannel();
|
|
251
281
|
yield this.assertQueue(queue, options);
|
|
252
|
-
return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions());
|
|
282
|
+
return channel.sendToQueue(queue, Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
253
283
|
});
|
|
254
284
|
}
|
|
255
285
|
}
|
package/dist/redis.d.ts
ADDED
package/dist/redis.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const redis_1 = __importDefault(require("redis"));
|
|
7
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
8
|
+
bluebird_1.default.promisifyAll(redis_1.default.RedisClient.prototype);
|
|
9
|
+
bluebird_1.default.promisifyAll(redis_1.default.Multi.prototype);
|
|
10
|
+
const getRedisInstance = (config) => redis_1.default.createClient(config);
|
|
11
|
+
exports.default = getRedisInstance;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/rabbit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,10 +17,14 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@types/amqp-connection-manager": "^2.0.10",
|
|
19
19
|
"@types/amqplib": "^0.5.16",
|
|
20
|
+
"@types/redis": "^2.8.32",
|
|
21
|
+
"@types/uuid": "^8.3.3",
|
|
20
22
|
"amqp-connection-manager": "^3.2.1",
|
|
21
23
|
"amqplib": "^0.6.0",
|
|
22
24
|
"bluebird": "^3.7.2",
|
|
23
|
-
"moment": "^2.29.1"
|
|
25
|
+
"moment": "^2.29.1",
|
|
26
|
+
"redis": "^3.1.2",
|
|
27
|
+
"uuid": "^8.3.2"
|
|
24
28
|
},
|
|
25
29
|
"devDependencies": {
|
|
26
30
|
"@autofleet/outbreak": "*",
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,9 @@ import { ConfirmChannel, Options } from 'amqplib';
|
|
|
6
6
|
import { AmqpConnectionManager, ChannelWrapper, connect } from 'amqp-connection-manager';
|
|
7
7
|
import { EventEmitter } from 'events';
|
|
8
8
|
import { newTrace, traceTypes } from '@autofleet/outbreak';
|
|
9
|
+
import { RedisClient } from 'redis';
|
|
9
10
|
import RabbitError from './rabbitError';
|
|
11
|
+
import getRedisInstance, { RedisConfig } from './redis';
|
|
10
12
|
|
|
11
13
|
export interface IAfRabbitMq {
|
|
12
14
|
ack: any;
|
|
@@ -18,14 +20,19 @@ export interface IAfRabbitMq {
|
|
|
18
20
|
consumeFromExchange: any;
|
|
19
21
|
publish: any;
|
|
20
22
|
sendToQueue: any;
|
|
23
|
+
redisClient?: any;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
interface ExchangesCache {
|
|
24
27
|
[key: string]: any
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
type CustomMessageHeaders = {
|
|
31
|
+
redisTimestampValidationKey?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
export interface AfRabbitOptions {
|
|
28
|
-
reconnect: boolean
|
|
35
|
+
reconnect: boolean;
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
const DEFAULT_DEAD_TTL_TWO_DAYS = 60000 * 60 * 48;
|
|
@@ -60,9 +67,10 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
static getPublishOptions() {
|
|
70
|
+
static getPublishOptions(customHeaders: CustomMessageHeaders = {}) {
|
|
64
71
|
return {
|
|
65
72
|
timestamp: moment().unix() * 1000,
|
|
73
|
+
headers: customHeaders,
|
|
66
74
|
};
|
|
67
75
|
}
|
|
68
76
|
|
|
@@ -86,17 +94,34 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
86
94
|
|
|
87
95
|
options: AfRabbitOptions | undefined;
|
|
88
96
|
|
|
89
|
-
|
|
97
|
+
redisClient: any;
|
|
98
|
+
|
|
99
|
+
constructor(options?: AfRabbitOptions, redisConfig?: RedisConfig) {
|
|
90
100
|
this.em = new EventEmitter();
|
|
91
101
|
this.channel = null;
|
|
92
102
|
this.connection = null;
|
|
93
103
|
this.creatingConnection = false;
|
|
94
104
|
this.exchanges = {};
|
|
95
105
|
this.options = options;
|
|
106
|
+
this.redisClient = redisConfig && getRedisInstance(redisConfig);
|
|
96
107
|
}
|
|
97
108
|
|
|
98
|
-
|
|
109
|
+
private shouldConsumeMessageByTimestamp = async (msg: any) => {
|
|
110
|
+
const { properties: { timestamp, headers } } = msg;
|
|
111
|
+
if (timestamp && headers?.redisTimestampValidationKey && this.redisClient) {
|
|
112
|
+
const lastMessageTimestamp = await this.redisClient.getAsync(headers.redisTimestampValidationKey);
|
|
113
|
+
return !lastMessageTimestamp || !moment(parseInt(lastMessageTimestamp, 10)).isAfter(moment(timestamp));
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
public ack = (channel: ChannelWrapper, shouldUpdateRedisTimestamp = false) => async (msg: any) => {
|
|
99
119
|
await channel.ack(msg);
|
|
120
|
+
const { properties: { timestamp, headers } } = msg;
|
|
121
|
+
if (shouldUpdateRedisTimestamp && timestamp && headers?.redisTimestampValidationKey && this.redisClient) {
|
|
122
|
+
const parsedTimestamp = parseInt(timestamp, 10);
|
|
123
|
+
await this.redisClient.setAsync(headers.redisTimestampValidationKey, parsedTimestamp);
|
|
124
|
+
}
|
|
100
125
|
}
|
|
101
126
|
|
|
102
127
|
public nack = (
|
|
@@ -137,8 +162,10 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
137
162
|
return resolve(this.connection);
|
|
138
163
|
}
|
|
139
164
|
this.creatingConnection = true;
|
|
165
|
+
const username: string = process.env.RABBITMQ_USERNAME || 'guest';
|
|
166
|
+
const password: string = process.env.RABBITMQ_PASSWORD || 'guest';
|
|
140
167
|
const host: string = process.env.RABBITMQ_SERVICE_HOST || '';
|
|
141
|
-
const connection: AmqpConnectionManager = await connect([`amqp://${host}`]);
|
|
168
|
+
const connection: AmqpConnectionManager = await connect([`amqp://${username}:${password}@${host}`]);
|
|
142
169
|
this.connection = connection;
|
|
143
170
|
this.connection.on('disconnect',
|
|
144
171
|
({ err }) => {
|
|
@@ -221,9 +248,15 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
221
248
|
return Promise.all([
|
|
222
249
|
c.consume(
|
|
223
250
|
queue,
|
|
224
|
-
(msg: any) => {
|
|
251
|
+
async (msg: any) => {
|
|
252
|
+
const parsedMessage = RabbitMq.parseMsg(msg);
|
|
225
253
|
newTrace(traceTypes.RABBIT);
|
|
226
|
-
|
|
254
|
+
const shouldConsume = await this.shouldConsumeMessageByTimestamp(parsedMessage);
|
|
255
|
+
if (!shouldConsume) {
|
|
256
|
+
this.ack(channel);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
callback(parsedMessage, this.ack(channel, true), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
227
260
|
},
|
|
228
261
|
),
|
|
229
262
|
]);
|
|
@@ -246,22 +279,30 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
246
279
|
c.bindQueue(queue, exchange, ''),
|
|
247
280
|
c.consume(
|
|
248
281
|
queue,
|
|
249
|
-
(msg: any) => {
|
|
282
|
+
async (msg: any) => {
|
|
283
|
+
const parsedMessage = RabbitMq.parseMsg(msg);
|
|
250
284
|
newTrace(traceTypes.RABBIT);
|
|
251
|
-
|
|
285
|
+
const shouldConsume = await this.shouldConsumeMessageByTimestamp(parsedMessage);
|
|
286
|
+
if (!shouldConsume) {
|
|
287
|
+
this.ack(channel);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
callback(parsedMessage, this.ack(channel, true), this.nack(channel, queue, optionsWithDefaults, { messageTtl: deadMessageTtl }));
|
|
252
291
|
},
|
|
253
292
|
),
|
|
254
293
|
]);
|
|
255
294
|
});
|
|
256
295
|
}
|
|
257
296
|
|
|
258
|
-
async publish(exchange: string, content: any) {
|
|
297
|
+
async publish(exchange: string, content: any, customHeaders?: any) {
|
|
259
298
|
RabbitMq.validateName('exchange', exchange);
|
|
260
299
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
261
300
|
await this.assertExchange(exchange);
|
|
262
301
|
return new bluebird.Promise(async (resolve, reject) => {
|
|
263
302
|
try {
|
|
264
|
-
await channel.publish(exchange, '',
|
|
303
|
+
await channel.publish(exchange, '',
|
|
304
|
+
Buffer.from(JSON.stringify(content)),
|
|
305
|
+
RabbitMq.getPublishOptions(customHeaders));
|
|
265
306
|
return resolve();
|
|
266
307
|
} catch (e) {
|
|
267
308
|
reject(e);
|
|
@@ -269,11 +310,13 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
269
310
|
}).timeout(this.PUBLISH_TIMEOUT, `${this.PUBLISH_ERROR_MSG}${exchange}`);
|
|
270
311
|
}
|
|
271
312
|
|
|
272
|
-
async sendToQueue(queue: string, content: any, options?: any) {
|
|
313
|
+
async sendToQueue(queue: string, content: any, options?: any, customHeaders?: any) {
|
|
273
314
|
RabbitMq.validateName('queue', queue);
|
|
274
315
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
275
316
|
await this.assertQueue(queue, options);
|
|
276
|
-
return channel.sendToQueue(queue,
|
|
317
|
+
return channel.sendToQueue(queue,
|
|
318
|
+
Buffer.from(JSON.stringify(content)),
|
|
319
|
+
RabbitMq.getPublishOptions(customHeaders));
|
|
277
320
|
}
|
|
278
321
|
}
|
|
279
322
|
|
package/src/redis.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import redis from 'redis';
|
|
2
|
+
import bluebird from 'bluebird';
|
|
3
|
+
|
|
4
|
+
bluebird.promisifyAll(redis.RedisClient.prototype);
|
|
5
|
+
bluebird.promisifyAll(redis.Multi.prototype);
|
|
6
|
+
|
|
7
|
+
export type RedisConfig = {
|
|
8
|
+
host: string;
|
|
9
|
+
port: number | undefined;
|
|
10
|
+
prefix?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const getRedisInstance = (config: RedisConfig): any => redis.createClient(config);
|
|
14
|
+
|
|
15
|
+
export default getRedisInstance;
|