@autofleet/rabbit 3.2.21-beta.0.6 → 3.2.21
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 +1 -2
- package/dist/index.js +28 -10
- package/package.json +2 -2
- package/src/index.ts +33 -14
- package/dist/lib/celery.d.ts +0 -9
- package/dist/lib/celery.js +0 -54
- package/src/lib/celery.ts +0 -85
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { AmqpConnectionManager, ChannelWrapper, CreateChannelOpts } from 'amqp-c
|
|
|
4
4
|
import { ConfirmChannel, ConsumeMessage, Options, Replies } from 'amqplib';
|
|
5
5
|
import { RedisConfig } from './lib/redis';
|
|
6
6
|
import { CallbackFunction, ConsumeMessageOrNull, ConsumeOptions, CustomMessageHeaders, QueuesCache, RedisLockType, ExchangesCache, QueueSetupPromisesDictionary, AssertExchangePromisesDictionary } from './lib/types';
|
|
7
|
-
import { sendCeleryTaskViaHttp } from './lib/celery';
|
|
8
7
|
export interface IAfRabbitMq {
|
|
9
8
|
ack: any;
|
|
10
9
|
nack: any;
|
|
@@ -86,6 +85,7 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
86
85
|
private deleteQueue;
|
|
87
86
|
bindQueue(queue: string, exchange: string): Promise<void>;
|
|
88
87
|
setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue>;
|
|
88
|
+
static shouldUseQuorum(queueName: string): boolean;
|
|
89
89
|
assertQueue(queueName: string, options?: Options.AssertQueue): Promise<any>;
|
|
90
90
|
private saveConsumer;
|
|
91
91
|
consume(queue: string, callback: CallbackFunction, options?: ConsumeOptions): Promise<any>;
|
|
@@ -99,4 +99,3 @@ declare class RabbitMq implements IAfRabbitMq {
|
|
|
99
99
|
gracefulShutdown(signal: string): Promise<void>;
|
|
100
100
|
}
|
|
101
101
|
export default RabbitMq;
|
|
102
|
-
export { sendCeleryTaskViaHttp, };
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ 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");
|
|
10
9
|
const moment_1 = __importDefault(require("moment"));
|
|
@@ -18,8 +17,6 @@ const redis_1 = __importDefault(require("./lib/redis"));
|
|
|
18
17
|
const utils_1 = require("./lib/utils");
|
|
19
18
|
const consts_1 = require("./lib/consts");
|
|
20
19
|
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
20
|
// const debug = nodeDebug('af-rabbitmq')
|
|
24
21
|
const debug = logger_1.default.debug.bind(logger_1.default);
|
|
25
22
|
const PUBLISH_TIMEOUT = 1000 * 10;
|
|
@@ -304,12 +301,22 @@ class RabbitMq {
|
|
|
304
301
|
}
|
|
305
302
|
async setupQueue(queueName, options) {
|
|
306
303
|
let queue;
|
|
304
|
+
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
305
|
+
const localeOptions = {
|
|
306
|
+
...options,
|
|
307
|
+
durable: true,
|
|
308
|
+
arguments: {
|
|
309
|
+
...options?.arguments,
|
|
310
|
+
'x-consumer-timeout': 1000 * 60 * 60 * 24,
|
|
311
|
+
'x-queue-type': shouldUseQuorum ? 'quorum' : 'classic',
|
|
312
|
+
},
|
|
313
|
+
};
|
|
307
314
|
try {
|
|
308
315
|
const channel = await this.assertChannel();
|
|
309
316
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
310
|
-
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName,
|
|
317
|
+
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
311
318
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
312
|
-
queue = await channel.assertQueue(queueName,
|
|
319
|
+
queue = await channel.assertQueue(queueName, localeOptions);
|
|
313
320
|
}
|
|
314
321
|
catch (e) {
|
|
315
322
|
logger_1.default.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
@@ -318,17 +325,28 @@ class RabbitMq {
|
|
|
318
325
|
const channel = await this.assertChannel({ force: true });
|
|
319
326
|
await this.deleteQueue(queueName);
|
|
320
327
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
321
|
-
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName,
|
|
328
|
+
await channel.addSetup((setupChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
322
329
|
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
323
|
-
queue = await channel.assertQueue(queueName,
|
|
330
|
+
queue = await channel.assertQueue(queueName, localeOptions);
|
|
324
331
|
}
|
|
325
332
|
else {
|
|
326
333
|
throw e;
|
|
327
334
|
}
|
|
328
335
|
}
|
|
329
|
-
this.queues[queueName] =
|
|
336
|
+
this.queues[queueName] = queue;
|
|
330
337
|
return queue;
|
|
331
338
|
}
|
|
339
|
+
static shouldUseQuorum(queueName) {
|
|
340
|
+
const envQuorumQueuesWhitelist = process.env.QUORUM_QUEUES_WHITELIST;
|
|
341
|
+
if (envQuorumQueuesWhitelist === '*') {
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
if (envQuorumQueuesWhitelist) {
|
|
345
|
+
const whitelist = envQuorumQueuesWhitelist.split(',');
|
|
346
|
+
return whitelist.includes(queueName);
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
332
350
|
async assertQueue(queueName, options) {
|
|
333
351
|
RabbitMq.validateName('queue', queueName);
|
|
334
352
|
if (this.queues[queueName]) {
|
|
@@ -383,8 +401,8 @@ class RabbitMq {
|
|
|
383
401
|
}
|
|
384
402
|
const channel = await this.getNewChannel({});
|
|
385
403
|
return channel.addSetup(async (confirmChannel) => {
|
|
386
|
-
await
|
|
387
|
-
await confirmChannel.prefetch(limit,
|
|
404
|
+
const q = await this.assertQueue(queue, optionsWithDefaults);
|
|
405
|
+
await confirmChannel.prefetch(limit, false);
|
|
388
406
|
const { consumerTag } = await confirmChannel.consume(queue, async (msg) => {
|
|
389
407
|
if (!msg) {
|
|
390
408
|
return null;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -41,8 +41,6 @@ import {
|
|
|
41
41
|
AssertExchangePromisesDictionary,
|
|
42
42
|
} from './lib/types';
|
|
43
43
|
|
|
44
|
-
import { sendCeleryTaskViaHttp } from './lib/celery';
|
|
45
|
-
|
|
46
44
|
// const debug = nodeDebug('af-rabbitmq')
|
|
47
45
|
const debug = logger.debug.bind(logger);
|
|
48
46
|
|
|
@@ -453,12 +451,22 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
453
451
|
|
|
454
452
|
async setupQueue(queueName: string, options?: Options.AssertQueue): Promise<Replies.AssertQueue> {
|
|
455
453
|
let queue: Replies.AssertQueue;
|
|
454
|
+
const shouldUseQuorum = RabbitMq.shouldUseQuorum(queueName);
|
|
455
|
+
const localeOptions = {
|
|
456
|
+
...options,
|
|
457
|
+
durable: true,
|
|
458
|
+
arguments: {
|
|
459
|
+
...options?.arguments,
|
|
460
|
+
'x-consumer-timeout': 1000 * 60 * 60 * 24,
|
|
461
|
+
'x-queue-type': shouldUseQuorum ? 'quorum' : 'classic',
|
|
462
|
+
},
|
|
463
|
+
};
|
|
456
464
|
try {
|
|
457
465
|
const channel: ChannelWrapper = await this.assertChannel();
|
|
458
466
|
debug('assertQueue->channel.addSetup', { queueName });
|
|
459
|
-
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName,
|
|
467
|
+
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
460
468
|
debug('assertQueue->channel.assertQueue', { queueName });
|
|
461
|
-
queue = await channel.assertQueue(queueName,
|
|
469
|
+
queue = await channel.assertQueue(queueName, localeOptions);
|
|
462
470
|
} catch (e) {
|
|
463
471
|
logger.error('rabbit: assertQueue error', { queueName, options, error: e });
|
|
464
472
|
if (!this.options?.dontRetryAssert) {
|
|
@@ -467,19 +475,34 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
467
475
|
await this.deleteQueue(queueName);
|
|
468
476
|
|
|
469
477
|
debug('retrying assertQueue->channel.addSetup', { queueName });
|
|
470
|
-
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName,
|
|
478
|
+
await channel.addSetup((setupChannel: ConfirmChannel) => setupChannel.assertQueue(queueName, localeOptions));
|
|
471
479
|
debug('retrying assertQueue->channel.assertQueue', { queueName });
|
|
472
|
-
queue = await channel.assertQueue(queueName,
|
|
480
|
+
queue = await channel.assertQueue(queueName, localeOptions);
|
|
473
481
|
} else {
|
|
474
482
|
throw e;
|
|
475
483
|
}
|
|
476
484
|
}
|
|
477
485
|
|
|
478
|
-
this.queues[queueName] =
|
|
486
|
+
this.queues[queueName] = queue;
|
|
479
487
|
return queue;
|
|
480
488
|
}
|
|
481
489
|
|
|
482
|
-
|
|
490
|
+
static shouldUseQuorum(queueName: string): boolean {
|
|
491
|
+
const envQuorumQueuesWhitelist = process.env.QUORUM_QUEUES_WHITELIST;
|
|
492
|
+
|
|
493
|
+
if (envQuorumQueuesWhitelist === '*') {
|
|
494
|
+
return true;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (envQuorumQueuesWhitelist) {
|
|
498
|
+
const whitelist = envQuorumQueuesWhitelist.split(',');
|
|
499
|
+
return whitelist.includes(queueName);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
async assertQueue(queueName: string, options?: Options.AssertQueue): Promise<any> {
|
|
483
506
|
RabbitMq.validateName('queue', queueName);
|
|
484
507
|
if (this.queues[queueName]) {
|
|
485
508
|
delete this.queueSetupPromises[queueName];
|
|
@@ -546,8 +569,8 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
546
569
|
}
|
|
547
570
|
const channel = await this.getNewChannel({});
|
|
548
571
|
return channel.addSetup(async (confirmChannel: ConfirmChannel) => {
|
|
549
|
-
await
|
|
550
|
-
await confirmChannel.prefetch(limit,
|
|
572
|
+
const q = await this.assertQueue(queue, optionsWithDefaults);
|
|
573
|
+
await confirmChannel.prefetch(limit, false);
|
|
551
574
|
const { consumerTag } = await confirmChannel.consume(
|
|
552
575
|
queue,
|
|
553
576
|
async (msg: ConsumeMessageOrNull) => {
|
|
@@ -737,7 +760,3 @@ class RabbitMq implements IAfRabbitMq {
|
|
|
737
760
|
}
|
|
738
761
|
|
|
739
762
|
export default RabbitMq;
|
|
740
|
-
|
|
741
|
-
export {
|
|
742
|
-
sendCeleryTaskViaHttp,
|
|
743
|
-
};
|
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,54 +0,0 @@
|
|
|
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
|
-
exports.sendCeleryTaskViaHttp = void 0;
|
|
7
|
-
const node_crypto_1 = require("node:crypto");
|
|
8
|
-
const logger_1 = __importDefault(require("../logger"));
|
|
9
|
-
// Environment configuration
|
|
10
|
-
const config = {
|
|
11
|
-
host: process.env.RABBITMQ_SERVICE_HOST || '10.132.15.204',
|
|
12
|
-
username: process.env.RABBITMQ_USERNAME || 'default_user_Zjlb8cnBF-jwc61bbC8',
|
|
13
|
-
password: process.env.RABBITMQ_PASSWORD || 'SDjnZWKAgz9TROLDV85OUZb6FOLlfw1b',
|
|
14
|
-
};
|
|
15
|
-
async function sendCeleryTaskViaHttp(data, { taskName, queueName }) {
|
|
16
|
-
const apiUrl = `http://${config.host}:15672/api/exchanges/%2f/amq.default/publish`;
|
|
17
|
-
const message = {
|
|
18
|
-
task: taskName,
|
|
19
|
-
id: (0, node_crypto_1.randomUUID)(),
|
|
20
|
-
args: [data],
|
|
21
|
-
};
|
|
22
|
-
const payload = {
|
|
23
|
-
properties: {
|
|
24
|
-
delivery_mode: 2,
|
|
25
|
-
content_type: 'application/json',
|
|
26
|
-
},
|
|
27
|
-
routing_key: queueName,
|
|
28
|
-
payload: JSON.stringify(message),
|
|
29
|
-
payload_encoding: 'string',
|
|
30
|
-
};
|
|
31
|
-
try {
|
|
32
|
-
const response = await fetch(apiUrl, {
|
|
33
|
-
method: 'POST',
|
|
34
|
-
headers: {
|
|
35
|
-
'Content-Type': 'application/json',
|
|
36
|
-
Authorization: `Basic ${Buffer.from(`${config.username}:${config.password}`).toString('base64')}`,
|
|
37
|
-
},
|
|
38
|
-
body: JSON.stringify(payload),
|
|
39
|
-
});
|
|
40
|
-
if (response.ok) {
|
|
41
|
-
const result = await response.json();
|
|
42
|
-
logger_1.default.info('Successfully published message:', result);
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
logger_1.default.error(`Failed to publish message. Status code: ${response.status}`);
|
|
46
|
-
logger_1.default.error(`Response: ${await response.text()}`);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
logger_1.default.error('Error sending request:', error instanceof Error ? error.message : String(error));
|
|
51
|
-
throw error;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
exports.sendCeleryTaskViaHttp = sendCeleryTaskViaHttp;
|
package/src/lib/celery.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import logger from '../logger';
|
|
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
|
-
logger.info('Successfully published message:', result);
|
|
75
|
-
} else {
|
|
76
|
-
logger.error(`Failed to publish message. Status code: ${response.status}`);
|
|
77
|
-
logger.error(`Response: ${await response.text()}`);
|
|
78
|
-
}
|
|
79
|
-
} catch (error) {
|
|
80
|
-
logger.error('Error sending request:', error instanceof Error ? error.message : String(error));
|
|
81
|
-
throw error;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export { sendCeleryTaskViaHttp, TaskData, SendTaskOptions };
|