@autofleet/rabbit 3.2.21-beta.0.5 → 3.2.21-beta.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 +5 -17
- package/dist/index.js +12 -18
- package/dist/lib/types.d.ts +7 -3
- package/dist/lib/utils.d.ts +2 -2
- package/package.json +3 -1
- package/src/index.ts +18 -42
- package/src/lib/types.ts +9 -4
- package/src/lib/utils.ts +2 -6
- package/dist/lib/celery.d.ts +0 -9
- package/dist/lib/celery.js +0 -50
- package/src/lib/celery.ts +0 -85
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
|
-
import { AmqpConnectionManager, ChannelWrapper
|
|
3
|
+
import { AmqpConnectionManager, ChannelWrapper } from 'amqp-connection-manager';
|
|
4
4
|
import { ConfirmChannel, ConsumeMessage, Options, Replies } from 'amqplib';
|
|
5
5
|
import { RedisConfig } from './lib/redis';
|
|
6
|
-
import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary,
|
|
7
|
-
import { sendCeleryTaskViaHttp } from './lib/celery';
|
|
6
|
+
import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary, assertChannelOpts, newChannelOpts, PublishOptions } from './lib/types';
|
|
8
7
|
export interface IAfRabbitMq {
|
|
9
8
|
ack: any;
|
|
10
9
|
nack: any;
|
|
@@ -34,15 +33,6 @@ export interface AfRabbitOptions {
|
|
|
34
33
|
dontRetryAssert?: boolean;
|
|
35
34
|
rabbitHost?: string;
|
|
36
35
|
}
|
|
37
|
-
type newChannelOpts = {
|
|
38
|
-
name?: string;
|
|
39
|
-
onClose?: null | ((args: any | null) => void);
|
|
40
|
-
options?: CreateChannelOpts | undefined;
|
|
41
|
-
};
|
|
42
|
-
type assertChannelOpts = {
|
|
43
|
-
channelName?: string;
|
|
44
|
-
force?: boolean;
|
|
45
|
-
};
|
|
46
36
|
declare class RabbitMq implements IAfRabbitMq {
|
|
47
37
|
static parseMsg(msg: any): any;
|
|
48
38
|
static validateName(type: string, name: string): void;
|
|
@@ -67,7 +57,6 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
67
57
|
exchanges: ExchangesCache;
|
|
68
58
|
queues: QueuesCache;
|
|
69
59
|
queueSetupPromises: QueueSetupPromisesDictionary;
|
|
70
|
-
assertExchangePromises: AssertExchangePromisesDictionary;
|
|
71
60
|
options: AfRabbitOptions | undefined;
|
|
72
61
|
redisClient: any;
|
|
73
62
|
redisLock?: RedisLockType;
|
|
@@ -80,8 +69,8 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
80
69
|
nack: (channel: ConfirmChannel, queue: string, options: any, deadQueueOptions: Options.AssertQueue, msg: ConsumeMessageOrNull, releaseLock: any) => (userMsg: ConsumeMessageOrNull, { skipRetry, }?: NackOptions) => Promise<any>;
|
|
81
70
|
getConnection(): Promise<AmqpConnectionManager>;
|
|
82
71
|
getNewChannel({ name, onClose, options }?: newChannelOpts): Promise<ChannelWrapper>;
|
|
83
|
-
assertChannel({ force }?: assertChannelOpts): Promise<ChannelWrapper>;
|
|
84
|
-
assertExchange(exchangeName: string
|
|
72
|
+
assertChannel({ force, newChannelOptions }?: assertChannelOpts): Promise<ChannelWrapper>;
|
|
73
|
+
assertExchange(exchangeName: string): Promise<any>;
|
|
85
74
|
getQueueLength(queue: string): Promise<Replies.AssertQueue>;
|
|
86
75
|
private deleteQueue;
|
|
87
76
|
bindQueue(queue: string, exchange: string): Promise<void>;
|
|
@@ -93,10 +82,9 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
93
82
|
private unlockRedisIfNeeded;
|
|
94
83
|
private consumeFromRabbit;
|
|
95
84
|
consumeFromExchange(queue: string, exchange: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
|
|
96
|
-
publish(exchange: string, content: any, customHeaders?: any): Promise<boolean>;
|
|
85
|
+
publish(exchange: string, content: any, customHeaders?: any, options?: PublishOptions): Promise<boolean>;
|
|
97
86
|
sendToQueue(queue: string, content: any, options?: any, customHeaders?: any): Promise<boolean | undefined>;
|
|
98
87
|
isConnected(): Promise<boolean>;
|
|
99
88
|
gracefulShutdown(signal: string): Promise<void>;
|
|
100
89
|
}
|
|
101
90
|
export default RabbitMq;
|
|
102
|
-
export { sendCeleryTaskViaHttp, };
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.sendCeleryTaskViaHttp = void 0;
|
|
8
7
|
const events_1 = require("events");
|
|
9
8
|
const util_1 = require("util");
|
|
9
|
+
const lodash_1 = require("lodash");
|
|
10
10
|
const moment_1 = __importDefault(require("moment"));
|
|
11
11
|
const redis_lock_1 = __importDefault(require("redis-lock"));
|
|
12
12
|
const amqp_connection_manager_1 = require("amqp-connection-manager");
|
|
@@ -18,8 +18,6 @@ const redis_1 = __importDefault(require("./lib/redis"));
|
|
|
18
18
|
const utils_1 = require("./lib/utils");
|
|
19
19
|
const consts_1 = require("./lib/consts");
|
|
20
20
|
const types_1 = require("./lib/types");
|
|
21
|
-
const celery_1 = require("./lib/celery");
|
|
22
|
-
Object.defineProperty(exports, "sendCeleryTaskViaHttp", { enumerable: true, get: function () { return celery_1.sendCeleryTaskViaHttp; } });
|
|
23
21
|
// const debug = nodeDebug('af-rabbitmq')
|
|
24
22
|
const debug = logger_1.default.debug.bind(logger_1.default);
|
|
25
23
|
const PUBLISH_TIMEOUT = 1000 * 10;
|
|
@@ -126,7 +124,6 @@ class RabbitMq {
|
|
|
126
124
|
this.exchanges = {};
|
|
127
125
|
this.queues = {};
|
|
128
126
|
this.queueSetupPromises = {};
|
|
129
|
-
this.assertExchangePromises = {};
|
|
130
127
|
this.consumers = [];
|
|
131
128
|
this.options = options;
|
|
132
129
|
this.redisClient = redisConfig && (0, redis_1.default)(redisConfig);
|
|
@@ -246,14 +243,14 @@ class RabbitMq {
|
|
|
246
243
|
throw err;
|
|
247
244
|
}
|
|
248
245
|
}
|
|
249
|
-
async assertChannel({ force = false } = {}) {
|
|
246
|
+
async assertChannel({ force = false, newChannelOptions = {} } = {}) {
|
|
250
247
|
if (!this.publishChannelSetupPromise) {
|
|
251
248
|
this.publishChannelSetupPromise = new Promise(async (resolve, reject) => {
|
|
252
249
|
if (this.channel && !force) {
|
|
253
250
|
return resolve(this.channel);
|
|
254
251
|
}
|
|
255
252
|
try {
|
|
256
|
-
const channel = await this.getNewChannel({});
|
|
253
|
+
const channel = await this.getNewChannel({ options: newChannelOptions });
|
|
257
254
|
channel.on('error', (err) => {
|
|
258
255
|
logger_1.default.error('rabbit: channel error', { err });
|
|
259
256
|
});
|
|
@@ -267,18 +264,14 @@ class RabbitMq {
|
|
|
267
264
|
}
|
|
268
265
|
return this.publishChannelSetupPromise;
|
|
269
266
|
}
|
|
270
|
-
async assertExchange(exchangeName
|
|
267
|
+
async assertExchange(exchangeName) {
|
|
271
268
|
const channel = await this.assertChannel();
|
|
272
269
|
if (this.exchanges[exchangeName]) {
|
|
273
|
-
delete this.assertExchangePromises[exchangeName];
|
|
274
270
|
return this.exchanges[exchangeName];
|
|
275
271
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
this.assertExchangePromises[exchangeName] = (0, utils_1.assertExchangeFanout)(channel, exchangeName);
|
|
280
|
-
this.exchanges[exchangeName] = await this.assertExchangePromises[exchangeName];
|
|
281
|
-
return this.exchanges[exchangeName];
|
|
272
|
+
const exchange = await (0, utils_1.assertExchangeFanout)(channel, exchangeName);
|
|
273
|
+
this.exchanges[exchangeName] = exchange;
|
|
274
|
+
return exchange;
|
|
282
275
|
}
|
|
283
276
|
async getQueueLength(queue) {
|
|
284
277
|
RabbitMq.validateName('queue', queue);
|
|
@@ -385,6 +378,7 @@ class RabbitMq {
|
|
|
385
378
|
return channel.addSetup(async (confirmChannel) => {
|
|
386
379
|
await confirmChannel.assertQueue(queue, options ? { messageTtl: options.messageTtl } : undefined);
|
|
387
380
|
await confirmChannel.prefetch(limit, true);
|
|
381
|
+
const channelConsumerOptions = optionsWithDefaults.channelConsumeOptions ? (0, lodash_1.merge)(types_1.CONSUMER_DEFAULT_OPTIONS, optionsWithDefaults.channelConsumeOptions) : types_1.CONSUMER_DEFAULT_OPTIONS;
|
|
388
382
|
const { consumerTag } = await confirmChannel.consume(queue, async (msg) => {
|
|
389
383
|
if (!msg) {
|
|
390
384
|
return null;
|
|
@@ -445,7 +439,7 @@ class RabbitMq {
|
|
|
445
439
|
catch (e) {
|
|
446
440
|
await localNack(msg);
|
|
447
441
|
}
|
|
448
|
-
},
|
|
442
|
+
}, channelConsumerOptions);
|
|
449
443
|
if (!consumerTag) {
|
|
450
444
|
logger_1.default.error(`rabbit: failed to consume from queue ${queue}`);
|
|
451
445
|
}
|
|
@@ -473,17 +467,17 @@ class RabbitMq {
|
|
|
473
467
|
]);
|
|
474
468
|
});
|
|
475
469
|
}
|
|
476
|
-
async publish(exchange, content, customHeaders) {
|
|
470
|
+
async publish(exchange, content, customHeaders, options) {
|
|
477
471
|
return (0, utils_1.wrapSetImmediate)(async () => {
|
|
478
472
|
RabbitMq.validateName('exchange', exchange);
|
|
479
|
-
const channel = await this.assertChannel();
|
|
473
|
+
const channel = await this.assertChannel({ newChannelOptions: options?.newChannelOptions });
|
|
480
474
|
await this.assertExchange(exchange);
|
|
481
475
|
await channel.publish(exchange, '', Buffer.from(JSON.stringify(content)), RabbitMq.getPublishOptions(customHeaders));
|
|
482
476
|
});
|
|
483
477
|
}
|
|
484
478
|
async sendToQueue(queue, content, options, customHeaders) {
|
|
485
479
|
try {
|
|
486
|
-
await this.assertChannel();
|
|
480
|
+
await this.assertChannel({ newChannelOptions: options?.newChannelOptions });
|
|
487
481
|
}
|
|
488
482
|
catch (e) {
|
|
489
483
|
logger_1.default.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CreateChannelOpts } from 'amqp-connection-manager';
|
|
1
2
|
import { ConsumeMessage, Options, Replies } from 'amqplib';
|
|
2
3
|
export interface ExchangesCache {
|
|
3
4
|
[key: string]: any;
|
|
@@ -8,9 +9,6 @@ export interface QueuesCache {
|
|
|
8
9
|
export interface QueueSetupPromisesDictionary {
|
|
9
10
|
[key: string]: Promise<Replies.AssertQueue> | undefined;
|
|
10
11
|
}
|
|
11
|
-
export interface AssertExchangePromisesDictionary {
|
|
12
|
-
[key: string]: Promise<Replies.AssertExchange> | undefined;
|
|
13
|
-
}
|
|
14
12
|
export type CustomMessageHeaders = {
|
|
15
13
|
redisTimestampValidationKey?: string;
|
|
16
14
|
};
|
|
@@ -25,16 +23,22 @@ export interface ConsumeOptions {
|
|
|
25
23
|
useConsumeWithLock?: boolean;
|
|
26
24
|
auditContext?: any;
|
|
27
25
|
enableRabbitTrace?: boolean;
|
|
26
|
+
channelConsumeOptions?: Options.Consume;
|
|
28
27
|
}
|
|
29
28
|
export type CallbackFunction = (msg: ConsumeMessage, ack: any, nack: any) => Promise<any>;
|
|
30
29
|
export type newChannelOpts = {
|
|
31
30
|
name?: string;
|
|
32
31
|
onClose?: null | ((args: any | null) => void);
|
|
32
|
+
options?: CreateChannelOpts | undefined;
|
|
33
33
|
};
|
|
34
34
|
export type assertChannelOpts = {
|
|
35
35
|
channelName?: string;
|
|
36
36
|
force?: boolean;
|
|
37
|
+
newChannelOptions?: newChannelOpts;
|
|
37
38
|
};
|
|
39
|
+
export interface PublishOptions {
|
|
40
|
+
newChannelOptions?: newChannelOpts;
|
|
41
|
+
}
|
|
38
42
|
export type AfConsumer = {
|
|
39
43
|
queue: string;
|
|
40
44
|
callback: CallbackFunction;
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChannelWrapper } from 'amqp-connection-manager';
|
|
2
|
-
import { ConfirmChannel
|
|
3
|
-
export declare const assertExchangeFanout: (c: ChannelWrapper | ConfirmChannel, exchangeName: string) => Promise<Replies.AssertExchange>;
|
|
2
|
+
import { ConfirmChannel } from 'amqplib';
|
|
3
|
+
export declare const assertExchangeFanout: (c: ChannelWrapper | ConfirmChannel, exchangeName: string) => Promise<import("amqplib").Replies.AssertExchange>;
|
|
4
4
|
export declare const wrapSetImmediate: (callback: () => any) => Promise<any>;
|
|
5
5
|
export declare const rand: () => number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/rabbit",
|
|
3
|
-
"version": "3.2.21-beta.
|
|
3
|
+
"version": "3.2.21-beta.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"amqp-connection-manager": "4.1.9",
|
|
20
20
|
"amqplib": "0.10.3",
|
|
21
21
|
"bluebird": "^3.7.2",
|
|
22
|
+
"lodash": "^4.17.21",
|
|
22
23
|
"moment": "^2.29.1",
|
|
23
24
|
"redis": "^3.1.2",
|
|
24
25
|
"redis-lock": "^0.1.4"
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"@autofleet/logger": "4.0.6",
|
|
31
32
|
"@types/amqplib": "0.8.2",
|
|
32
33
|
"@types/jest": "^29.5.12",
|
|
34
|
+
"@types/lodash": "^4.17.12",
|
|
33
35
|
"@types/node": "^20.14.11",
|
|
34
36
|
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
|
35
37
|
"eslint": "^7.13.0",
|
package/src/index.ts
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import { EventEmitter, once } from 'events';
|
|
4
4
|
import { promisify } from 'util';
|
|
5
|
+
import { merge } from 'lodash';
|
|
5
6
|
import moment from 'moment';
|
|
6
7
|
import RedisLock from 'redis-lock';
|
|
7
8
|
import {
|
|
8
|
-
AmqpConnectionManager, ChannelWrapper, connect,
|
|
9
|
+
AmqpConnectionManager, ChannelWrapper, connect,
|
|
9
10
|
} from 'amqp-connection-manager';
|
|
10
11
|
import {
|
|
11
12
|
ConfirmChannel, ConsumeMessage, Options, Replies,
|
|
@@ -35,14 +36,12 @@ import {
|
|
|
35
36
|
CustomMessageHeaders,
|
|
36
37
|
QueuesCache,
|
|
37
38
|
RedisLockType,
|
|
38
|
-
ExchangesCache,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
ExchangesCache, CONSUMER_DEFAULT_OPTIONS, QueueSetupPromisesDictionary,
|
|
40
|
+
assertChannelOpts,
|
|
41
|
+
newChannelOpts,
|
|
42
|
+
PublishOptions,
|
|
42
43
|
} from './lib/types';
|
|
43
44
|
|
|
44
|
-
import { sendCeleryTaskViaHttp } from './lib/celery';
|
|
45
|
-
|
|
46
45
|
// const debug = nodeDebug('af-rabbitmq')
|
|
47
46
|
const debug = logger.debug.bind(logger);
|
|
48
47
|
|
|
@@ -83,17 +82,6 @@ export interface AfRabbitOptions {
|
|
|
83
82
|
rabbitHost?: string;
|
|
84
83
|
}
|
|
85
84
|
|
|
86
|
-
type newChannelOpts = {
|
|
87
|
-
name?: string;
|
|
88
|
-
onClose?: null | ((args: any | null) => void);
|
|
89
|
-
options?: CreateChannelOpts | undefined;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
type assertChannelOpts = {
|
|
93
|
-
channelName?: string;
|
|
94
|
-
force?: boolean;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
85
|
type AfConsumer = {
|
|
98
86
|
queue: string;
|
|
99
87
|
callback: CallbackFunction;
|
|
@@ -162,8 +150,6 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
162
150
|
|
|
163
151
|
queueSetupPromises: QueueSetupPromisesDictionary;
|
|
164
152
|
|
|
165
|
-
assertExchangePromises: AssertExchangePromisesDictionary;
|
|
166
|
-
|
|
167
153
|
options: AfRabbitOptions | undefined;
|
|
168
154
|
|
|
169
155
|
redisClient: any;
|
|
@@ -184,7 +170,6 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
184
170
|
this.exchanges = {};
|
|
185
171
|
this.queues = {};
|
|
186
172
|
this.queueSetupPromises = {};
|
|
187
|
-
this.assertExchangePromises = {};
|
|
188
173
|
this.consumers = [];
|
|
189
174
|
this.options = options;
|
|
190
175
|
this.redisClient = redisConfig && getRedisInstance(redisConfig);
|
|
@@ -387,7 +372,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
387
372
|
}
|
|
388
373
|
}
|
|
389
374
|
|
|
390
|
-
async assertChannel({ force = false } : assertChannelOpts = {}): Promise<ChannelWrapper> {
|
|
375
|
+
async assertChannel({ force = false, newChannelOptions = {} }: assertChannelOpts = {}): Promise<ChannelWrapper> {
|
|
391
376
|
if (!this.publishChannelSetupPromise) {
|
|
392
377
|
this.publishChannelSetupPromise = new Promise<ChannelWrapper>(async (resolve, reject) => {
|
|
393
378
|
if (this.channel && !force) {
|
|
@@ -395,7 +380,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
395
380
|
}
|
|
396
381
|
|
|
397
382
|
try {
|
|
398
|
-
const channel = await this.getNewChannel({});
|
|
383
|
+
const channel = await this.getNewChannel({ options: newChannelOptions });
|
|
399
384
|
channel.on('error', (err) => {
|
|
400
385
|
logger.error('rabbit: channel error', { err });
|
|
401
386
|
});
|
|
@@ -409,21 +394,14 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
409
394
|
return this.publishChannelSetupPromise;
|
|
410
395
|
}
|
|
411
396
|
|
|
412
|
-
async assertExchange(exchangeName: string
|
|
397
|
+
async assertExchange(exchangeName: string) {
|
|
413
398
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
414
|
-
|
|
415
399
|
if (this.exchanges[exchangeName]) {
|
|
416
|
-
delete this.assertExchangePromises[exchangeName];
|
|
417
400
|
return this.exchanges[exchangeName];
|
|
418
401
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
this.assertExchangePromises[exchangeName] = assertExchangeFanout(channel, exchangeName);
|
|
425
|
-
this.exchanges[exchangeName] = await this.assertExchangePromises[exchangeName];
|
|
426
|
-
return this.exchanges[exchangeName];
|
|
402
|
+
const exchange = await assertExchangeFanout(channel, exchangeName);
|
|
403
|
+
this.exchanges[exchangeName] = exchange;
|
|
404
|
+
return exchange;
|
|
427
405
|
}
|
|
428
406
|
|
|
429
407
|
async getQueueLength(queue: string) {
|
|
@@ -548,6 +526,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
548
526
|
return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
|
|
549
527
|
await confirmChannel.assertQueue(queue, options ? { messageTtl: options.messageTtl } : undefined);
|
|
550
528
|
await confirmChannel.prefetch(limit, true);
|
|
529
|
+
const channelConsumerOptions = optionsWithDefaults.channelConsumeOptions ? merge(CONSUMER_DEFAULT_OPTIONS, optionsWithDefaults.channelConsumeOptions) : CONSUMER_DEFAULT_OPTIONS;
|
|
551
530
|
const { consumerTag } = await confirmChannel.consume(
|
|
552
531
|
queue,
|
|
553
532
|
async (msg: ConsumeMessageOrNull) => {
|
|
@@ -619,7 +598,8 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
619
598
|
} catch (e) {
|
|
620
599
|
await localNack(msg);
|
|
621
600
|
}
|
|
622
|
-
},
|
|
601
|
+
},
|
|
602
|
+
channelConsumerOptions,
|
|
623
603
|
);
|
|
624
604
|
if (!consumerTag) {
|
|
625
605
|
logger.error(`rabbit: failed to consume from queue ${queue}`);
|
|
@@ -654,10 +634,10 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
654
634
|
});
|
|
655
635
|
}
|
|
656
636
|
|
|
657
|
-
async publish(exchange: string, content: any, customHeaders?: any)
|
|
637
|
+
async publish(exchange: string, content: any, customHeaders?: any, options?: PublishOptions): Promise<boolean> {
|
|
658
638
|
return wrapSetImmediate(async () => {
|
|
659
639
|
RabbitMq.validateName('exchange', exchange);
|
|
660
|
-
const channel: ChannelWrapper = await this.assertChannel();
|
|
640
|
+
const channel: ChannelWrapper = await this.assertChannel({ newChannelOptions: options?.newChannelOptions });
|
|
661
641
|
await this.assertExchange(exchange);
|
|
662
642
|
await channel.publish(exchange, '',
|
|
663
643
|
Buffer.from(JSON.stringify(content)),
|
|
@@ -672,7 +652,7 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
672
652
|
customHeaders?: any,
|
|
673
653
|
): Promise<boolean | undefined> {
|
|
674
654
|
try {
|
|
675
|
-
await this.assertChannel();
|
|
655
|
+
await this.assertChannel({ newChannelOptions: options?.newChannelOptions });
|
|
676
656
|
} catch (e) {
|
|
677
657
|
logger.error(`rabbit sendToQueue: failed to send assert channel when sending to queue ${queue}`, { e });
|
|
678
658
|
throw e;
|
|
@@ -737,7 +717,3 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
737
717
|
}
|
|
738
718
|
|
|
739
719
|
export default RabbitMq;
|
|
740
|
-
|
|
741
|
-
export {
|
|
742
|
-
sendCeleryTaskViaHttp,
|
|
743
|
-
};
|
package/src/lib/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CreateChannelOpts } from 'amqp-connection-manager';
|
|
1
2
|
import { ConsumeMessage, Options, Replies } from 'amqplib';
|
|
2
3
|
|
|
3
4
|
export interface ExchangesCache {
|
|
@@ -12,10 +13,6 @@ export interface QueueSetupPromisesDictionary {
|
|
|
12
13
|
[key: string]: Promise<Replies.AssertQueue> | undefined
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
export interface AssertExchangePromisesDictionary {
|
|
16
|
-
[key: string]: Promise<Replies.AssertExchange> | undefined
|
|
17
|
-
}
|
|
18
|
-
|
|
19
16
|
export type CustomMessageHeaders = {
|
|
20
17
|
redisTimestampValidationKey?: string;
|
|
21
18
|
}
|
|
@@ -31,6 +28,7 @@ export interface ConsumeOptions {
|
|
|
31
28
|
useConsumeWithLock?: boolean;
|
|
32
29
|
auditContext?: any;
|
|
33
30
|
enableRabbitTrace?: boolean;
|
|
31
|
+
channelConsumeOptions?: Options.Consume;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
34
|
export type CallbackFunction = (msg: ConsumeMessage, ack: any, nack: any) => Promise<any>
|
|
@@ -38,11 +36,18 @@ export type CallbackFunction = (msg: ConsumeMessage, ack: any, nack: any) => Pro
|
|
|
38
36
|
export type newChannelOpts = {
|
|
39
37
|
name?: string;
|
|
40
38
|
onClose?: null | ((args: any | null) => void);
|
|
39
|
+
options?: CreateChannelOpts | undefined;
|
|
41
40
|
};
|
|
42
41
|
export type assertChannelOpts = {
|
|
43
42
|
channelName?: string;
|
|
44
43
|
force?: boolean;
|
|
44
|
+
newChannelOptions?: newChannelOpts;
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
export interface PublishOptions {
|
|
48
|
+
newChannelOptions?: newChannelOpts;
|
|
49
|
+
}
|
|
50
|
+
|
|
46
51
|
export type AfConsumer = {
|
|
47
52
|
queue: string;
|
|
48
53
|
callback: CallbackFunction;
|
package/src/lib/utils.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { ChannelWrapper } from 'amqp-connection-manager';
|
|
2
|
-
import { ConfirmChannel
|
|
3
|
-
|
|
4
|
-
export const assertExchangeFanout = async (
|
|
5
|
-
c: ChannelWrapper | ConfirmChannel,
|
|
6
|
-
exchangeName: string,
|
|
7
|
-
): Promise<Replies.AssertExchange> => c.assertExchange(exchangeName, 'fanout');
|
|
2
|
+
import { ConfirmChannel } from 'amqplib';
|
|
8
3
|
|
|
4
|
+
export const assertExchangeFanout = async (c: ChannelWrapper | ConfirmChannel, exchangeName: string) => c.assertExchange(exchangeName, 'fanout');
|
|
9
5
|
export const wrapSetImmediate = (callback: () => any) => new Promise<any>((resolve, reject) => {
|
|
10
6
|
setImmediate(async () => {
|
|
11
7
|
try {
|
package/dist/lib/celery.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
interface TaskData {
|
|
2
|
-
[key: string]: any;
|
|
3
|
-
}
|
|
4
|
-
interface SendTaskOptions {
|
|
5
|
-
taskName: string;
|
|
6
|
-
queueName: string;
|
|
7
|
-
}
|
|
8
|
-
declare function sendCeleryTaskViaHttp(data: TaskData, { taskName, queueName }: SendTaskOptions): Promise<void>;
|
|
9
|
-
export { sendCeleryTaskViaHttp, TaskData, SendTaskOptions };
|
package/dist/lib/celery.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sendCeleryTaskViaHttp = void 0;
|
|
4
|
-
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
// Environment configuration
|
|
6
|
-
const config = {
|
|
7
|
-
host: process.env.RABBITMQ_SERVICE_HOST || '10.132.15.204',
|
|
8
|
-
username: process.env.RABBITMQ_USERNAME || 'default_user_Zjlb8cnBF-jwc61bbC8',
|
|
9
|
-
password: process.env.RABBITMQ_PASSWORD || 'SDjnZWKAgz9TROLDV85OUZb6FOLlfw1b',
|
|
10
|
-
};
|
|
11
|
-
async function sendCeleryTaskViaHttp(data, { taskName, queueName }) {
|
|
12
|
-
const apiUrl = `http://${config.host}:15672/api/exchanges/%2f/amq.default/publish`;
|
|
13
|
-
const message = {
|
|
14
|
-
task: taskName,
|
|
15
|
-
id: (0, node_crypto_1.randomUUID)(),
|
|
16
|
-
args: [data],
|
|
17
|
-
};
|
|
18
|
-
const payload = {
|
|
19
|
-
properties: {
|
|
20
|
-
delivery_mode: 2,
|
|
21
|
-
content_type: 'application/json',
|
|
22
|
-
},
|
|
23
|
-
routing_key: queueName,
|
|
24
|
-
payload: JSON.stringify(message),
|
|
25
|
-
payload_encoding: 'string',
|
|
26
|
-
};
|
|
27
|
-
try {
|
|
28
|
-
const response = await fetch(apiUrl, {
|
|
29
|
-
method: 'POST',
|
|
30
|
-
headers: {
|
|
31
|
-
'Content-Type': 'application/json',
|
|
32
|
-
Authorization: `Basic ${Buffer.from(`${config.username}:${config.password}`).toString('base64')}`,
|
|
33
|
-
},
|
|
34
|
-
body: JSON.stringify(payload),
|
|
35
|
-
});
|
|
36
|
-
if (response.ok) {
|
|
37
|
-
const result = await response.json();
|
|
38
|
-
console.log('Successfully published message:', result);
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
console.error(`Failed to publish message. Status code: ${response.status}`);
|
|
42
|
-
console.error(`Response: ${await response.text()}`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
console.error('Error sending request:', error instanceof Error ? error.message : String(error));
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
exports.sendCeleryTaskViaHttp = sendCeleryTaskViaHttp;
|
package/src/lib/celery.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
|
|
3
|
-
// Environment configuration
|
|
4
|
-
const config = {
|
|
5
|
-
host: process.env.RABBITMQ_SERVICE_HOST || '10.132.15.204',
|
|
6
|
-
username: process.env.RABBITMQ_USERNAME || 'default_user_Zjlb8cnBF-jwc61bbC8',
|
|
7
|
-
password: process.env.RABBITMQ_PASSWORD || 'SDjnZWKAgz9TROLDV85OUZb6FOLlfw1b',
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
// Type definitions
|
|
11
|
-
interface TaskData {
|
|
12
|
-
[key: string]: any;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface TaskMessage {
|
|
16
|
-
task: string;
|
|
17
|
-
id: string;
|
|
18
|
-
args: TaskData[];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface PublishPayload {
|
|
22
|
-
properties: {
|
|
23
|
-
delivery_mode: number;
|
|
24
|
-
content_type: string;
|
|
25
|
-
};
|
|
26
|
-
routing_key: string;
|
|
27
|
-
payload: string;
|
|
28
|
-
payload_encoding: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
interface PublishResponse {
|
|
32
|
-
routed: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
interface SendTaskOptions {
|
|
36
|
-
taskName: string;
|
|
37
|
-
queueName: string;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function sendCeleryTaskViaHttp(
|
|
41
|
-
data: TaskData,
|
|
42
|
-
{ taskName, queueName }: SendTaskOptions,
|
|
43
|
-
): Promise<void> {
|
|
44
|
-
const apiUrl = `http://${config.host}:15672/api/exchanges/%2f/amq.default/publish`;
|
|
45
|
-
|
|
46
|
-
const message: TaskMessage = {
|
|
47
|
-
task: taskName,
|
|
48
|
-
id: randomUUID(),
|
|
49
|
-
args: [data],
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const payload: PublishPayload = {
|
|
53
|
-
properties: {
|
|
54
|
-
delivery_mode: 2,
|
|
55
|
-
content_type: 'application/json',
|
|
56
|
-
},
|
|
57
|
-
routing_key: queueName,
|
|
58
|
-
payload: JSON.stringify(message),
|
|
59
|
-
payload_encoding: 'string',
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
const response = await fetch(apiUrl, {
|
|
64
|
-
method: 'POST',
|
|
65
|
-
headers: {
|
|
66
|
-
'Content-Type': 'application/json',
|
|
67
|
-
Authorization: `Basic ${Buffer.from(`${config.username}:${config.password}`).toString('base64')}`,
|
|
68
|
-
},
|
|
69
|
-
body: JSON.stringify(payload),
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
if (response.ok) {
|
|
73
|
-
const result: PublishResponse = await response.json();
|
|
74
|
-
console.log('Successfully published message:', result);
|
|
75
|
-
} else {
|
|
76
|
-
console.error(`Failed to publish message. Status code: ${response.status}`);
|
|
77
|
-
console.error(`Response: ${await response.text()}`);
|
|
78
|
-
}
|
|
79
|
-
} catch (error) {
|
|
80
|
-
console.error('Error sending request:', error instanceof Error ? error.message : String(error));
|
|
81
|
-
throw error;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export { sendCeleryTaskViaHttp, TaskData, SendTaskOptions };
|