@diia-inhouse/diia-queue 14.0.20 → 14.0.22

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 CHANGED
@@ -1,11 +1,11 @@
1
1
  import { BaseQueueOptions, BindOptions, ConsumerOptions, ExchangeName, ExchangeOptions, ExchangeType, MessageBrokerExternalServiceType, MessageBrokerExternalServiceTypes, MessageBrokerGeneralServiceType, MessageBrokerGeneralServiceTypes, MessageBrokerInternalServiceType, MessageBrokerInternalServiceTypes, MessageBrokerServiceConfig, MessageBrokerServiceType, MessageBrokerServicesConfig, QueueOptions, QueueTypes, RecreateChannelOptions, RedeclareQueueOptions, UnbindOptions, emptyMessageBrokerServiceConfig } from "./interfaces/messageBrokerServiceConfig.js";
2
+ import { ListenerOptions, PublishDirectMessageOptions, PublishDirectOptions, PublishMessageOptions, PublishOptions, PublisherOptions, SubscribeOptions } from "./interfaces/options.js";
2
3
  import { AmqpConfig, AmqpConnectionEventNames, ConnectOptions, ConnectionStatus, ReconnectOptions, SocketOptions } from "./interfaces/providers/rabbitmq/amqpConnection.js";
3
4
  import { AmqpConnection } from "./providers/rabbitmq/amqpConnection.js";
4
- import { ListenerOptions, PublishDirectOptions, PublishExternalEventOptions, PublishOptions, PublisherOptions, SubscribeOptions } from "./interfaces/options.js";
5
5
  import { EventName, ExternalServiceConfig, InternalServiceConfig, QueueConfigByQueueName, QueueConfigType, QueueName, ServiceConfig, ServiceConfigByConfigType, ServiceRulesConfig, TopicConfig, TopicConfigByConfigType } from "./interfaces/queueConfig/configs.js";
6
6
  import { Arguments, ConnectionClientType, ConnectionList, DeclareOptions, ExportConfig, Headers, Message, MessageData, MessageProperties, NackOptions, QueueMessage, QueueMessageData, QueueMessageError, QueueMessageMetaData, RabbitMQConfig, RabbitMQConfigCustomParams, RabbitMQStatus } from "./interfaces/providers/rabbitmq/index.js";
7
+ import { AmqpPublisherPublishOptions, DirectResponse, DirectResponseHeaders, MessageHeaders, MessagePayload, PublishingResult } from "./providers/rabbitmq/amqpPublisher.types.js";
7
8
  import { MessageHandler } from "./interfaces/messageHandler.js";
8
- import { DirectResponse, DirectResponseHeaders, MessageHeaders, MessagePayload, PublishingResult } from "./interfaces/providers/rabbitmq/amqpPublisher.js";
9
9
  import { MessageBrokerServicesStatus, QueueConnectionType, QueueStatus, QueueStatusByType } from "./interfaces/queueStatus.js";
10
10
  import { QueueContext } from "./interfaces/queueContext.js";
11
11
  import { CommunicationDirection, CommunicationsTotalLabelsMap, LabelUnknown, Metrics, TotalListenerChannelErrorsLabelsMap, TotalMessageHandlerErrorsLabelsMap, communicationsTotalLabelsMap } from "./interfaces/metrics/index.js";
@@ -24,4 +24,4 @@ import { Queue } from "./services/queue.js";
24
24
  import { ScheduledTask } from "./services/scheduledTask.js";
25
25
  import { Task } from "./services/task.js";
26
26
  import { CommonQueueDeps, ExternalQueueDeps, InternalQueueDeps, QueueDeps } from "./interfaces/deps.js";
27
- export { AmqpAsserter, AmqpConfig, AmqpConnection, AmqpConnectionEventNames, AmqpListener, AmqpPublisher, Arguments, BaseQueueOptions, BindOptions, CommonQueueDeps, CommunicationDirection, CommunicationsTotalLabelsMap, ConnectOptions, ConnectionClientType, ConnectionList, ConnectionStatus, ConsumerOptions, DeclareOptions, DirectResponse, DirectResponseHeaders, EventBus, EventBusListener, EventBusQueue, EventListeners, EventMessageHandler, EventMessageValidator, EventName, ExchangeName, ExchangeOptions, ExchangeType, ExportConfig, ExternalCommunicator, ExternalCommunicatorFailureResponse, ExternalCommunicatorResponse, ExternalCommunicatorResponseError, ExternalCommunicatorSuccessResponse, ExternalEventBus, ExternalEventBusQueue, ExternalQueueDeps, ExternalServiceConfig, Headers, InternalQueueConfig, InternalQueueDeps, InternalServiceConfig, LabelUnknown, Listener, ListenerOptions, Message, MessageBrokerExternalServiceType, MessageBrokerExternalServiceTypes, MessageBrokerGeneralServiceType, MessageBrokerGeneralServiceTypes, MessageBrokerInternalServiceType, MessageBrokerInternalServiceTypes, MessageBrokerServiceConfig, MessageBrokerServiceEventsListener, MessageBrokerServiceListener, MessageBrokerServiceType, MessageBrokerServicesConfig, MessageBrokerServicesStatus, MessageData, MessageHandler, MessageHeaders, MessagePayload, MessageProperties, Metrics, NackOptions, PublishDirectOptions, PublishExternalEventOptions, PublishOptions, PublisherOptions, PublishingResult, Queue, QueueConfig, QueueConfigByQueueName, QueueConfigType, QueueConnectionConfig, QueueConnectionType, QueueContext, QueueDeps, QueueMessage, QueueMessageData, QueueMessageError, QueueMessageMetaData, QueueName, QueueOptions, QueueStatus, QueueStatusByType, QueueTypes, RabbitMQConfig, RabbitMQConfigCustomParams, RabbitMQProvider, RabbitMQStatus, ReceiveDirectOps, ReconnectOptions, RecreateChannelOptions, RedeclareQueueOptions, ScheduledTask, ScheduledTasksQueue, ServiceConfig, ServiceConfigByConfigType, ServiceRulesConfig, SocketOptions, SubscribeOptions, Task, TaskListener, TaskQueue, TopicConfig, TopicConfigByConfigType, TotalListenerChannelErrorsLabelsMap, TotalMessageHandlerErrorsLabelsMap, UnbindOptions, communicationsTotalLabelsMap, emptyMessageBrokerServiceConfig };
27
+ export { AmqpAsserter, AmqpConfig, AmqpConnection, AmqpConnectionEventNames, AmqpListener, AmqpPublisher, AmqpPublisherPublishOptions, Arguments, BaseQueueOptions, BindOptions, CommonQueueDeps, CommunicationDirection, CommunicationsTotalLabelsMap, ConnectOptions, ConnectionClientType, ConnectionList, ConnectionStatus, ConsumerOptions, DeclareOptions, DirectResponse, DirectResponseHeaders, EventBus, EventBusListener, EventBusQueue, EventListeners, EventMessageHandler, EventMessageValidator, EventName, ExchangeName, ExchangeOptions, ExchangeType, ExportConfig, ExternalCommunicator, ExternalCommunicatorFailureResponse, ExternalCommunicatorResponse, ExternalCommunicatorResponseError, ExternalCommunicatorSuccessResponse, ExternalEventBus, ExternalEventBusQueue, ExternalQueueDeps, ExternalServiceConfig, Headers, InternalQueueConfig, InternalQueueDeps, InternalServiceConfig, LabelUnknown, Listener, ListenerOptions, Message, MessageBrokerExternalServiceType, MessageBrokerExternalServiceTypes, MessageBrokerGeneralServiceType, MessageBrokerGeneralServiceTypes, MessageBrokerInternalServiceType, MessageBrokerInternalServiceTypes, MessageBrokerServiceConfig, MessageBrokerServiceEventsListener, MessageBrokerServiceListener, MessageBrokerServiceType, MessageBrokerServicesConfig, MessageBrokerServicesStatus, MessageData, MessageHandler, MessageHeaders, MessagePayload, MessageProperties, Metrics, NackOptions, PublishDirectMessageOptions, PublishDirectOptions, PublishMessageOptions, PublishOptions, PublisherOptions, PublishingResult, Queue, QueueConfig, QueueConfigByQueueName, QueueConfigType, QueueConnectionConfig, QueueConnectionType, QueueContext, QueueDeps, QueueMessage, QueueMessageData, QueueMessageError, QueueMessageMetaData, QueueName, QueueOptions, QueueStatus, QueueStatusByType, QueueTypes, RabbitMQConfig, RabbitMQConfigCustomParams, RabbitMQProvider, RabbitMQStatus, ReceiveDirectOps, ReconnectOptions, RecreateChannelOptions, RedeclareQueueOptions, ScheduledTask, ScheduledTasksQueue, ServiceConfig, ServiceConfigByConfigType, ServiceRulesConfig, SocketOptions, SubscribeOptions, Task, TaskListener, TaskQueue, TopicConfig, TopicConfigByConfigType, TotalListenerChannelErrorsLabelsMap, TotalMessageHandlerErrorsLabelsMap, UnbindOptions, communicationsTotalLabelsMap, emptyMessageBrokerServiceConfig };
@@ -37,6 +37,11 @@ interface ReceiveDirectOps {
37
37
  * Defaults to a freshly generated `randomUUID()` when omitted.
38
38
  */
39
39
  requestUuid?: string;
40
+ /**
41
+ * Timeout (ms) for publish drain / backpressure wait
42
+ * @default 10000
43
+ */
44
+ publishTimeout?: number;
40
45
  }
41
46
  interface ExternalCommunicatorResponseError {
42
47
  http_code: HttpStatusCode;
@@ -1,10 +1,10 @@
1
1
  import { BaseQueueOptions, BindOptions, ConsumerOptions, ExchangeName, ExchangeOptions, ExchangeType, MessageBrokerExternalServiceType, MessageBrokerExternalServiceTypes, MessageBrokerGeneralServiceType, MessageBrokerGeneralServiceTypes, MessageBrokerInternalServiceType, MessageBrokerInternalServiceTypes, MessageBrokerServiceConfig, MessageBrokerServiceType, MessageBrokerServicesConfig, QueueOptions, QueueTypes, RecreateChannelOptions, RedeclareQueueOptions, UnbindOptions, emptyMessageBrokerServiceConfig } from "./messageBrokerServiceConfig.js";
2
+ import { ListenerOptions, PublishDirectMessageOptions, PublishDirectOptions, PublishMessageOptions, PublishOptions, PublisherOptions, SubscribeOptions } from "./options.js";
2
3
  import { AmqpConfig, AmqpConnectionEventNames, ConnectOptions, ConnectionStatus, ReconnectOptions, SocketOptions } from "./providers/rabbitmq/amqpConnection.js";
3
- import { ListenerOptions, PublishDirectOptions, PublishExternalEventOptions, PublishOptions, PublisherOptions, SubscribeOptions } from "./options.js";
4
4
  import { EventName, ExternalServiceConfig, InternalServiceConfig, QueueConfigByQueueName, QueueConfigType, QueueName, ServiceConfig, ServiceConfigByConfigType, ServiceRulesConfig, TopicConfig, TopicConfigByConfigType } from "./queueConfig/configs.js";
5
5
  import { Arguments, ConnectionClientType, ConnectionList, DeclareOptions, ExportConfig, Headers, Message, MessageData, MessageProperties, NackOptions, QueueMessage, QueueMessageData, QueueMessageError, QueueMessageMetaData, RabbitMQConfig, RabbitMQConfigCustomParams, RabbitMQStatus } from "./providers/rabbitmq/index.js";
6
+ import { AmqpPublisherPublishOptions, DirectResponse, DirectResponseHeaders, MessageHeaders, MessagePayload, PublishingResult } from "../providers/rabbitmq/amqpPublisher.types.js";
6
7
  import { MessageHandler } from "./messageHandler.js";
7
- import { DirectResponse, DirectResponseHeaders, MessageHeaders, MessagePayload, PublishingResult } from "./providers/rabbitmq/amqpPublisher.js";
8
8
  import { MessageBrokerServicesStatus, QueueConnectionType, QueueStatus, QueueStatusByType } from "./queueStatus.js";
9
9
  import { QueueContext } from "./queueContext.js";
10
10
  import { CommunicationDirection, CommunicationsTotalLabelsMap, LabelUnknown, Metrics, TotalListenerChannelErrorsLabelsMap, TotalMessageHandlerErrorsLabelsMap, communicationsTotalLabelsMap } from "./metrics/index.js";
@@ -44,7 +44,7 @@ interface ExternalEventBusQueue {
44
44
  * - use the publishToExchange method for pushing a message by a routing key
45
45
  * - use the publishToQueue method for pushing a message to a queue
46
46
  * */
47
- publish(eventName: EventName, message: MessagePayload, options?: PublishExternalEventOptions): Promise<PublishingResult>;
47
+ publish(eventName: EventName, message: MessagePayload, options?: PublishOptions): Promise<PublishingResult>;
48
48
  publishDirect<T>(eventName: string, message: MessagePayload, options?: PublishDirectOptions): Promise<T>;
49
49
  publishToExchange(exchangeName: ExchangeName, routingKey: string, messageData: MessageData, options?: PublishOptions): Promise<PublishingResult>;
50
50
  publishToQueue(queueName: QueueName, messageData: MessageData): Promise<PublishingResult>;
@@ -3,24 +3,90 @@ import { Options } from "amqplib";
3
3
 
4
4
  //#region src/interfaces/options.d.ts
5
5
  interface PublisherOptions {
6
+ /**
7
+ * @deprecated use directResponseTimeout instead. Applies to RPC direct response wait only, not publish drain.
8
+ */
6
9
  timeout?: number;
10
+ /**
11
+ * Timeout (ms) for publish drain / backpressure wait
12
+ * @default 10000
13
+ */
14
+ publishTimeout?: number;
15
+ /**
16
+ * Reply-to queue name for RPC direct responses
17
+ * @default amq.rabbitmq.reply-to
18
+ */
7
19
  replyToQueueName?: string;
20
+ /**
21
+ * Timeout (ms) for direct response
22
+ * @default 10000
23
+ */
24
+ directResponseTimeout?: number;
8
25
  }
9
26
  interface ListenerOptions {
10
27
  queueOptions?: Options.AssertQueue;
11
28
  prefetchCount?: number;
12
29
  recreateChannelOptions?: RecreateChannelOptions;
13
30
  }
31
+ interface PublishMessageOptions {
32
+ /**
33
+ * How to handle publish drain / backpressure wait timeout:
34
+ * - `true` — reject with `InternalServerError` (`Message publish timeout exceeded`)
35
+ * - `false` — log the error, resolve, and record publish metrics with `ErrorType.Unoperated`
36
+ * @default true
37
+ */
38
+ throwOnPublishTimeout?: boolean;
39
+ /**
40
+ * Timeout (ms) for publish drain / backpressure wait
41
+ * @default 10000
42
+ */
43
+ publishTimeout?: number;
44
+ }
45
+ interface PublishDirectMessageOptions {
46
+ /**
47
+ * Timeout (ms) for direct response
48
+ * @default 10000
49
+ */
50
+ responseTimeout?: number;
51
+ /**
52
+ * Timeout (ms) for publish drain / backpressure wait
53
+ * @default 10000
54
+ */
55
+ publishTimeout?: number;
56
+ }
14
57
  interface PublishDirectOptions {
58
+ /**
59
+ * Override the target exchange. Defaults to the exchange resolved from the
60
+ * external queue configuration for the given event.
61
+ * @default undefined
62
+ */
15
63
  exchangeName?: string;
64
+ /**
65
+ * Timeout (ms) for direct response
66
+ * @default 10000
67
+ */
16
68
  timeout?: number;
69
+ /**
70
+ * Whether to ignore cache
71
+ * @default false
72
+ */
17
73
  ignoreCache?: boolean;
74
+ /**
75
+ * Registry API version
76
+ * @default undefined
77
+ */
18
78
  registryApiVersion?: string;
79
+ /**
80
+ * Timeout (ms) for publish drain / backpressure wait
81
+ * @default 10000
82
+ */
83
+ publishTimeout?: number;
19
84
  }
20
- interface PublishOptions {
85
+ interface PublishOptions extends PublishMessageOptions {
21
86
  /**
22
87
  * Delay (ms) before message delivery
23
88
  * @default undefined
89
+ * @deprecated rabbitmq version 4.x does not support delays
24
90
  */
25
91
  delay?: number;
26
92
  /**
@@ -28,16 +94,6 @@ interface PublishOptions {
28
94
  * @default undefined
29
95
  */
30
96
  routingKey?: string;
31
- /**
32
- * Timeout (ms) for publish operation
33
- * @default Infinity
34
- */
35
- publishTimeout?: number;
36
- /**
37
- * Whether to throw error on timeout (true) or return false (false)
38
- * @default true
39
- */
40
- throwOnPublishTimeout?: boolean;
41
97
  }
42
98
  interface SubscribeOptions {
43
99
  routingKey?: string;
@@ -47,6 +103,5 @@ interface SubscribeOptions {
47
103
  */
48
104
  delayed?: boolean;
49
105
  }
50
- interface PublishExternalEventOptions extends PublishOptions, PublishDirectOptions {}
51
106
  //#endregion
52
- export { ListenerOptions, PublishDirectOptions, PublishExternalEventOptions, PublishOptions, PublisherOptions, SubscribeOptions };
107
+ export { ListenerOptions, PublishDirectMessageOptions, PublishDirectOptions, PublishMessageOptions, PublishOptions, PublisherOptions, SubscribeOptions };
@@ -1,7 +1,7 @@
1
1
  import { BaseQueueOptions } from "../../messageBrokerServiceConfig.js";
2
+ import { ListenerOptions } from "../../options.js";
2
3
  import { ConnectOptions, ConnectionStatus, ReconnectOptions, SocketOptions } from "./amqpConnection.js";
3
4
  import { AmqpConnection } from "../../../providers/rabbitmq/amqpConnection.js";
4
- import { ListenerOptions } from "../../options.js";
5
5
  import { EventName, QueueConfigByQueueName, ServiceConfigByConfigType, TopicConfigByConfigType } from "../../queueConfig/configs.js";
6
6
  import { ErrorData } from "@diia-inhouse/errors";
7
7
  import * as amqp from "amqplib";
@@ -1,4 +1,5 @@
1
1
  import { AmqpConnection } from "./rabbitmq/amqpConnection.js";
2
+ import { AmqpPublisherPublishOptions, DirectResponse, DirectResponseHeaders, MessageHeaders, MessagePayload, PublishingResult } from "./rabbitmq/amqpPublisher.types.js";
2
3
  import { AmqpAsserter } from "./rabbitmq/amqpAsserter.js";
3
4
  import { AmqpListener } from "./rabbitmq/amqpListener.js";
4
5
  import { AmqpPublisher } from "./rabbitmq/amqpPublisher.js";
@@ -1,9 +1,9 @@
1
1
  import { ExchangeName } from "../../interfaces/messageBrokerServiceConfig.js";
2
+ import { PublishDirectMessageOptions, PublishMessageOptions, PublisherOptions } from "../../interfaces/options.js";
2
3
  import { ConnectionStatus } from "../../interfaces/providers/rabbitmq/amqpConnection.js";
3
4
  import { AmqpConnection } from "./amqpConnection.js";
4
- import { PublisherOptions } from "../../interfaces/options.js";
5
5
  import { QueueMessageData } from "../../interfaces/providers/rabbitmq/index.js";
6
- import { MessageHeaders, PublishingResult } from "../../interfaces/providers/rabbitmq/amqpPublisher.js";
6
+ import { MessageHeaders, PublishingResult } from "./amqpPublisher.types.js";
7
7
  import { RabbitMQMetricsService } from "../../services/metrics.js";
8
8
  import { Logger } from "@diia-inhouse/types";
9
9
 
@@ -19,10 +19,12 @@ declare class AmqpPublisher {
19
19
  private readonly replyToQueueName;
20
20
  private eventEmitter?;
21
21
  private readonly directResponseTimeout;
22
+ private readonly publishTimeout;
23
+ private readonly throwOnPublishTimeout;
22
24
  constructor(connection: AmqpConnection, logger: Logger, rabbitMQMetrics: RabbitMQMetricsService, systemServiceName: string, options?: PublisherOptions);
23
25
  init(): Promise<void>;
24
- publishToExchange(exchangeName: ExchangeName, message: QueueMessageData, headers: MessageHeaders, routingKey?: string): Promise<PublishingResult>;
25
- publishToExchangeDirect<T>(exchangeName: ExchangeName, message: QueueMessageData, headers: MessageHeaders, routingKey?: string, responseTimeoutMs?: number): Promise<T>;
26
+ publishToExchange(exchangeName: ExchangeName, message: QueueMessageData, headers: MessageHeaders, routingKey?: string, publishMessageOptions?: PublishMessageOptions): Promise<PublishingResult>;
27
+ publishToExchangeDirect<T>(exchangeName: ExchangeName, message: QueueMessageData, headers: MessageHeaders, routingKey?: string, publishDirectOptions?: PublishDirectMessageOptions): Promise<T>;
26
28
  getStatus(): ConnectionStatus;
27
29
  private createRegularChannel;
28
30
  private createRpcChannel;
@@ -30,7 +32,9 @@ declare class AmqpPublisher {
30
32
  private publishMessage;
31
33
  private publishRequest;
32
34
  private publish;
33
- private getPublishOptions;
35
+ private waitForDrain;
36
+ private getWaitingTimeMs;
37
+ private getAmqpPublisherPublishOptions;
34
38
  private receiveDirectResponse;
35
39
  private collectMetrics;
36
40
  }
@@ -24,13 +24,16 @@ var AmqpPublisher = class {
24
24
  replyToQueueName = REPLY_TO_QUEUE_NAME;
25
25
  eventEmitter;
26
26
  directResponseTimeout = 1e4;
27
+ publishTimeout = 1e4;
28
+ throwOnPublishTimeout = true;
27
29
  constructor(connection, logger, rabbitMQMetrics, systemServiceName, options = {}) {
28
30
  this.connection = connection;
29
31
  this.logger = logger;
30
32
  this.rabbitMQMetrics = rabbitMQMetrics;
31
33
  this.systemServiceName = systemServiceName;
32
- this.directResponseTimeout = options.timeout || this.directResponseTimeout;
33
- this.replyToQueueName = options.replyToQueueName || REPLY_TO_QUEUE_NAME;
34
+ this.publishTimeout = options.publishTimeout ?? this.publishTimeout;
35
+ this.directResponseTimeout = options.directResponseTimeout ?? options.timeout ?? this.directResponseTimeout;
36
+ this.replyToQueueName = options.replyToQueueName ?? REPLY_TO_QUEUE_NAME;
34
37
  }
35
38
  async init() {
36
39
  await this.createRpcChannel();
@@ -40,7 +43,7 @@ var AmqpPublisher = class {
40
43
  await this.createRegularChannel();
41
44
  });
42
45
  }
43
- async publishToExchange(exchangeName, message, headers, routingKey = DEFAULT_ROUTING_KEY) {
46
+ async publishToExchange(exchangeName, message, headers, routingKey = DEFAULT_ROUTING_KEY, publishMessageOptions = {}) {
44
47
  const { event, payload } = message;
45
48
  const startTime = process.hrtime.bigint();
46
49
  const route = event;
@@ -52,14 +55,14 @@ var AmqpPublisher = class {
52
55
  this.logger.error(errorMessage);
53
56
  throw new InternalServerError(errorMessage);
54
57
  }
55
- const publishOptions = this.getPublishOptions(headers);
58
+ const amqpPublisherPublishOptions = this.getAmqpPublisherPublishOptions(publishMessageOptions, headers);
56
59
  this.logger.info(`Publish event: ${event}`, {
57
60
  routingKey,
58
61
  delay: headers["x-delay"]
59
62
  });
60
63
  this.logger.io("Event message", message);
61
- this.publishMessage(message, exchangeName, routingKey, publishOptions);
62
- this.collectMetrics(startTime, route, source, destination);
64
+ const isPublished = await this.publishMessage(message, exchangeName, routingKey, amqpPublisherPublishOptions);
65
+ this.collectMetrics(startTime, route, source, destination, isPublished ? void 0 : ErrorType.Unoperated);
63
66
  } catch (err) {
64
67
  this.logger.error("Error while publishing event", {
65
68
  err,
@@ -70,15 +73,15 @@ var AmqpPublisher = class {
70
73
  throw err;
71
74
  }
72
75
  }
73
- async publishToExchangeDirect(exchangeName, message, headers, routingKey = DEFAULT_ROUTING_KEY, responseTimeoutMs = this.directResponseTimeout) {
76
+ async publishToExchangeDirect(exchangeName, message, headers, routingKey = DEFAULT_ROUTING_KEY, publishDirectOptions = {}) {
74
77
  const startTime = process.hrtime.bigint();
75
78
  const route = message.event;
76
79
  const source = this.systemServiceName;
77
80
  let errorType = void 0;
78
81
  let destination = LabelUnknown;
79
82
  try {
80
- const { body, headers: { [Headers.handledBy]: handledBy } } = await this.receiveDirectResponse(exchangeName, message, headers, routingKey, responseTimeoutMs);
81
- destination = handledBy || destination;
83
+ const { body, headers: { [Headers.handledBy]: handledBy } } = await this.receiveDirectResponse(exchangeName, message, headers, routingKey, publishDirectOptions);
84
+ destination = handledBy ?? destination;
82
85
  return body;
83
86
  } catch (err) {
84
87
  this.logger.error("Failed to receive a direct response", {
@@ -110,71 +113,140 @@ var AmqpPublisher = class {
110
113
  this.logger.error("Consumed direct message is null");
111
114
  return;
112
115
  }
113
- const body = JSON.parse(msg.content.toString("utf8"));
114
- const headers = msg.properties.headers || {};
115
- this.eventEmitter?.emit(msg.properties.correlationId, {
116
- body,
117
- headers
118
- });
116
+ const response = {
117
+ body: JSON.parse(msg.content.toString("utf8")),
118
+ headers: msg.properties.headers || {}
119
+ };
120
+ this.eventEmitter?.emit(msg.properties.correlationId, response);
119
121
  }
120
- publishMessage(eventMessage, exchangeName, routingKey, publishOptions) {
122
+ async publishMessage(eventMessage, exchangeName, routingKey, amqpPublisherPublishOptions) {
121
123
  if (!this.regularChannel) throw new Error("Publishing message is denied, channel is not initialized");
122
- return this.publish(eventMessage, exchangeName, routingKey, publishOptions, this.regularChannel);
124
+ return await this.publish(eventMessage, exchangeName, routingKey, amqpPublisherPublishOptions, this.regularChannel);
123
125
  }
124
- publishRequest(eventMessage, exchangeName, routingKey, publishOptions) {
126
+ async publishRequest(eventMessage, exchangeName, routingKey, amqpPublisherPublishOptions) {
125
127
  if (!this.rpcChannel) throw new Error("Publishing RPC request is denied, channel is not initialized");
126
- return this.publish(eventMessage, exchangeName, routingKey, publishOptions, this.rpcChannel);
128
+ await this.publish(eventMessage, exchangeName, routingKey, amqpPublisherPublishOptions, this.rpcChannel);
127
129
  }
128
- publish(eventMessage, exchangeName, routingKey, publishOptions, channel) {
129
- const data = JSON.stringify(eventMessage);
130
- const content = Buffer.from(data);
131
- if (!channel.publish(exchangeName, routingKey, content, publishOptions)) throw new InternalServerError("Message has not been published");
130
+ async publish(eventMessage, exchangeName, routingKey, publishOptions, channel) {
131
+ const { channel: channelPublishOptions, custom: customPublishOptions } = publishOptions;
132
+ const content = Buffer.from(JSON.stringify(eventMessage));
133
+ if (channel.publish(exchangeName, routingKey, content, channelPublishOptions)) return true;
134
+ const backpressureStartTime = process.hrtime.bigint();
135
+ const logParams = {
136
+ routingKey,
137
+ exchangeName,
138
+ event: eventMessage.event
139
+ };
140
+ try {
141
+ const hasMessagePublished = await this.waitForDrain(channel, customPublishOptions);
142
+ const waitTimeMs = this.getWaitingTimeMs(backpressureStartTime);
143
+ if (hasMessagePublished) this.logger.info("Message published after backpressure", {
144
+ ...logParams,
145
+ waitTimeMs
146
+ });
147
+ else this.logger.error("Message publish timeout exceeded", {
148
+ ...logParams,
149
+ waitTimeMs
150
+ });
151
+ return hasMessagePublished;
152
+ } catch (err) {
153
+ const waitTimeMs = this.getWaitingTimeMs(backpressureStartTime);
154
+ this.logger.error("Error while waiting for drain", {
155
+ err,
156
+ ...logParams,
157
+ waitTimeMs
158
+ });
159
+ throw err;
160
+ }
132
161
  }
133
- getPublishOptions(headers, extraOpts = {}) {
162
+ async waitForDrain(channel, publishMessageOptions) {
163
+ const { publishTimeout = this.publishTimeout, throwOnPublishTimeout = this.throwOnPublishTimeout } = publishMessageOptions;
164
+ const { promise, resolve, reject } = Promise.withResolvers();
165
+ let timeoutId;
166
+ const cleanup = () => {
167
+ channel.off("drain", onDrain);
168
+ channel.off("error", onError);
169
+ clearTimeout(timeoutId);
170
+ };
171
+ const onDrain = () => {
172
+ resolve(true);
173
+ };
174
+ const onError = (err) => {
175
+ reject(err);
176
+ };
177
+ channel.once("drain", onDrain);
178
+ channel.once("error", onError);
179
+ timeoutId = setTimeout(() => {
180
+ if (throwOnPublishTimeout) reject(new InternalServerError("Message publish timeout exceeded"));
181
+ else resolve(false);
182
+ }, publishTimeout);
183
+ try {
184
+ return await promise;
185
+ } finally {
186
+ cleanup();
187
+ }
188
+ }
189
+ getWaitingTimeMs(backpressureStartTime) {
190
+ return Number(process.hrtime.bigint() - backpressureStartTime) / 1e6;
191
+ }
192
+ getAmqpPublisherPublishOptions(customOptions, headers, amqpOptions = {}) {
134
193
  return {
135
- ...this.defaultPublishOptions,
136
- timestamp: Date.now(),
137
- ...extraOpts,
138
- headers: {
139
- ...headers,
140
- [Headers.sentFrom]: this.systemServiceName
141
- }
194
+ channel: {
195
+ ...this.defaultPublishOptions,
196
+ timestamp: Date.now(),
197
+ ...amqpOptions,
198
+ headers: {
199
+ ...headers,
200
+ [Headers.sentFrom]: this.systemServiceName
201
+ }
202
+ },
203
+ custom: { ...customOptions }
142
204
  };
143
205
  }
144
- async receiveDirectResponse(exchangeName, message, headers, routingKey = DEFAULT_ROUTING_KEY, responseTimeoutMs = this.directResponseTimeout) {
206
+ async receiveDirectResponse(exchangeName, message, headers, routingKey = DEFAULT_ROUTING_KEY, publishDirectOptions) {
145
207
  const { event, payload } = message;
146
208
  if (!event || !exchangeName || !payload) throw new Error(`Invalid event name [${event}] or exchange name [${exchangeName}] or payload [${JSON.stringify(payload)}]`);
147
209
  const correlationId = randomUUID();
148
- const publishOptions = this.getPublishOptions(headers, {
210
+ const publishMessageOptions = {
211
+ ...publishDirectOptions,
212
+ throwOnPublishTimeout: true
213
+ };
214
+ const amqpPublishOptions = {
149
215
  correlationId,
150
216
  replyTo: this.replyToQueueName
151
- });
217
+ };
218
+ const amqpPublisherPublishOptions = this.getAmqpPublisherPublishOptions(publishMessageOptions, headers, amqpPublishOptions);
152
219
  this.logger.info(`Publish direct event: ${event}`, {
153
220
  routingKey,
154
221
  correlationId,
155
222
  eventUuid: payload.uuid
156
223
  });
157
224
  this.logger.io("Direct event message", message);
158
- return await new Promise((resolve, reject) => {
159
- const timeout = setTimeout(() => {
160
- this.eventEmitter?.removeAllListeners(correlationId);
161
- reject(new ExternalCommunicatorError(`Time out for external event: ${event}`, HttpStatusCode.GATEWAY_TIMEOUT));
162
- }, responseTimeoutMs);
163
- this.eventEmitter?.once(correlationId, (args) => {
164
- clearTimeout(timeout);
165
- this.logger.info(`Received direct event response: ${event}`, { traceId: headers.traceId });
166
- this.logger.io(`Direct event response message`, {
167
- body: args.body,
168
- traceId: headers.traceId
169
- });
170
- return resolve(args);
225
+ const { promise, resolve, reject } = Promise.withResolvers();
226
+ let timeoutId;
227
+ const cleanup = () => {
228
+ clearTimeout(timeoutId);
229
+ this.eventEmitter?.removeAllListeners(correlationId);
230
+ };
231
+ const onResponse = (args) => {
232
+ this.logger.info(`Received direct event response: ${event}`, { traceId: headers.traceId });
233
+ this.logger.io(`Direct event response message`, {
234
+ body: args.body,
235
+ traceId: headers.traceId
171
236
  });
172
- try {
173
- this.publishRequest(message, exchangeName, routingKey, publishOptions);
174
- } catch (err) {
175
- reject(err);
176
- }
177
- });
237
+ resolve(args);
238
+ };
239
+ this.eventEmitter?.once(correlationId, onResponse);
240
+ try {
241
+ await this.publishRequest(message, exchangeName, routingKey, amqpPublisherPublishOptions);
242
+ const responseTimeout = publishDirectOptions.responseTimeout ?? this.directResponseTimeout;
243
+ timeoutId = setTimeout(() => {
244
+ reject(new ExternalCommunicatorError(`Time out for external event: ${event}`, HttpStatusCode.GATEWAY_TIMEOUT));
245
+ }, responseTimeout);
246
+ return await promise;
247
+ } finally {
248
+ cleanup();
249
+ }
178
250
  }
179
251
  collectMetrics(startTime, route, source, destination, errorType) {
180
252
  this.rabbitMQMetrics.collectCommunicationsTotalMetric(route, source, destination, "outbound");
@@ -0,0 +1,25 @@
1
+ import { PublishMessageOptions } from "../../interfaces/options.js";
2
+ import { Headers } from "../../interfaces/providers/rabbitmq/index.js";
3
+ import { MessagePropertyHeaders, Options } from "amqplib";
4
+
5
+ //#region src/providers/rabbitmq/amqpPublisher.types.d.ts
6
+ type MessagePayload = unknown;
7
+ interface MessageHeaders {
8
+ traceId: string;
9
+ serviceCode?: string;
10
+ "x-delay"?: number;
11
+ }
12
+ type DirectResponseHeaders = MessagePropertyHeaders & {
13
+ [Headers.handledBy]?: string;
14
+ };
15
+ interface DirectResponse<T = unknown> {
16
+ body: T;
17
+ headers: DirectResponseHeaders;
18
+ }
19
+ type PublishingResult = void;
20
+ interface AmqpPublisherPublishOptions {
21
+ channel: Options.Publish;
22
+ custom: PublishMessageOptions;
23
+ }
24
+ //#endregion
25
+ export { AmqpPublisherPublishOptions, DirectResponse, DirectResponseHeaders, MessageHeaders, MessagePayload, PublishingResult };
@@ -1,10 +1,10 @@
1
1
  import { MessageBrokerServiceConfig, QueueOptions } from "../../interfaces/messageBrokerServiceConfig.js";
2
+ import { PublishDirectMessageOptions, PublishOptions } from "../../interfaces/options.js";
2
3
  import { AmqpConnection } from "./amqpConnection.js";
3
- import { PublishDirectOptions, PublishOptions } from "../../interfaces/options.js";
4
4
  import { EventName, QueueConfigByQueueName, QueueName, ServiceConfigByConfigType, TopicConfigByConfigType } from "../../interfaces/queueConfig/configs.js";
5
5
  import { ConnectionClientType, ExportConfig, QueueMessageData, RabbitMQConfig, RabbitMQStatus } from "../../interfaces/providers/rabbitmq/index.js";
6
+ import { PublishingResult } from "./amqpPublisher.types.js";
6
7
  import { MessageHandler } from "../../interfaces/messageHandler.js";
7
- import { PublishingResult } from "../../interfaces/providers/rabbitmq/amqpPublisher.js";
8
8
  import { QueueContext } from "../../interfaces/queueContext.js";
9
9
  import { AmqpAsserter } from "./amqpAsserter.js";
10
10
  import { AmqpListener } from "./amqpListener.js";
@@ -31,6 +31,9 @@ declare class RabbitMQProvider extends EventEmitter {
31
31
  private publisher?;
32
32
  private asserter?;
33
33
  private connectionList;
34
+ private readonly publishTimeout;
35
+ private readonly directResponseTimeout;
36
+ private readonly throwOnPublishTimeout;
34
37
  private readonly publisherIsNotInitializedErrorMsg;
35
38
  private readonly rabbitMQMetricsService;
36
39
  constructor(systemServiceName: string, rabbitmqConfig: RabbitMQConfig, serviceConfig: ServiceConfigByConfigType, topicsConfig: TopicConfigByConfigType, portalEvents: EventName[], logger: Logger, metrics: MetricsService, asyncLocalStorage?: AsyncLocalStorage<QueueContext> | undefined, queuesConfig?: QueueConfigByQueueName | undefined, messageBrokerServiceConfig?: MessageBrokerServiceConfig | undefined);
@@ -40,7 +43,7 @@ declare class RabbitMQProvider extends EventEmitter {
40
43
  subscribe(queueName: QueueName, messageHandler: MessageHandler): Promise<boolean>;
41
44
  unsubscribe(queueName: QueueName): Promise<void>;
42
45
  publish(message: QueueMessageData, exchangeName: string, routingKey?: string, options?: PublishOptions): Promise<PublishingResult>;
43
- publishExternalDirect<T>(message: QueueMessageData, exchangeName: string, routingKey?: string, options?: PublishDirectOptions): Promise<T>;
46
+ publishExternalDirect<T>(message: QueueMessageData, exchangeName: string, routingKey?: string, options?: PublishDirectMessageOptions): Promise<T>;
44
47
  getStatus(): RabbitMQStatus;
45
48
  makeAMQPConnection(client: ConnectionClientType): Promise<AmqpConnection>;
46
49
  makeAMQPListener(queuesOptions: QueueOptions[]): Promise<AmqpListener>;
@@ -8,11 +8,9 @@ import { AmqpAsserter } from "./amqpAsserter.js";
8
8
  import { AmqpConnection } from "./amqpConnection.js";
9
9
  import { AmqpListener } from "./amqpListener.js";
10
10
  import { AmqpPublisher } from "./amqpPublisher.js";
11
- import { InternalServerError } from "@diia-inhouse/errors";
12
- import _ from "lodash";
11
+ import lodash from "lodash";
13
12
  import { randomUUID } from "node:crypto";
14
13
  import { EventEmitter } from "node:events";
15
- import pTimeout from "p-timeout";
16
14
  //#region src/providers/rabbitmq/index.ts
17
15
  var RabbitMQProvider = class extends EventEmitter {
18
16
  systemServiceName;
@@ -34,6 +32,9 @@ var RabbitMQProvider = class extends EventEmitter {
34
32
  ["asserter"]: {},
35
33
  ["publisher"]: {}
36
34
  };
35
+ publishTimeout = 1e4;
36
+ directResponseTimeout = 1e4;
37
+ throwOnPublishTimeout = true;
37
38
  publisherIsNotInitializedErrorMsg = "Publisher is not initialized";
38
39
  rabbitMQMetricsService;
39
40
  constructor(systemServiceName, rabbitmqConfig, serviceConfig, topicsConfig, portalEvents, logger, metrics, asyncLocalStorage = void 0, queuesConfig = void 0, messageBrokerServiceConfig = void 0) {
@@ -86,23 +87,23 @@ var RabbitMQProvider = class extends EventEmitter {
86
87
  await this.listener?.cancelQueue(queueName);
87
88
  }
88
89
  async publish(message, exchangeName, routingKey = constants_default.DEFAULT_ROUTING_KEY, options) {
89
- const { publishTimeout = Infinity, throwOnPublishTimeout = true, delay } = options || {};
90
- const publishTask = async () => {
91
- const headers = this.preparePublisherHeaders(delay);
92
- if (!this.publisher) throw new Error(this.publisherIsNotInitializedErrorMsg);
93
- return await this.publisher?.publishToExchange(exchangeName, message, headers, routingKey);
94
- };
95
- const timeoutMsg = `Publishing message to ${exchangeName} exchange with ${routingKey} routing key timeout exceed`;
96
- if (throwOnPublishTimeout) return await pTimeout(publishTask(), publishTimeout, timeoutMsg);
97
- return await pTimeout(publishTask(), publishTimeout, () => {
98
- this.logger.error(timeoutMsg, { publishTimeout });
99
- throw new InternalServerError(timeoutMsg);
90
+ const { delay, publishTimeout = this.publishTimeout, throwOnPublishTimeout = this.throwOnPublishTimeout } = options || {};
91
+ const headers = this.preparePublisherHeaders(delay);
92
+ if (!this.publisher) throw new Error(this.publisherIsNotInitializedErrorMsg);
93
+ return await this.publisher.publishToExchange(exchangeName, message, headers, routingKey, {
94
+ ...options,
95
+ publishTimeout,
96
+ throwOnPublishTimeout
100
97
  });
101
98
  }
102
99
  async publishExternalDirect(message, exchangeName, routingKey = constants_default.DEFAULT_ROUTING_KEY, options) {
103
100
  const headers = this.preparePublisherHeaders();
104
101
  if (!this.publisher) throw new Error(this.publisherIsNotInitializedErrorMsg);
105
- return await this.publisher?.publishToExchangeDirect(exchangeName, message, headers, routingKey, options?.timeout);
102
+ const { publishTimeout = this.publishTimeout } = options || {};
103
+ return await this.publisher.publishToExchangeDirect(exchangeName, message, headers, routingKey, {
104
+ ...options,
105
+ publishTimeout
106
+ });
106
107
  }
107
108
  getStatus() {
108
109
  return {
@@ -111,7 +112,7 @@ var RabbitMQProvider = class extends EventEmitter {
111
112
  };
112
113
  }
113
114
  async makeAMQPConnection(client) {
114
- return new AmqpConnection(this.rabbitmqConfig.connection, this.logger, this.rabbitmqConfig.reconnectOptions, _.merge({ clientProperties: { connectionClientType: client } }, this.rabbitmqConfig.socketOptions));
115
+ return new AmqpConnection(this.rabbitmqConfig.connection, this.logger, this.rabbitmqConfig.reconnectOptions, lodash.merge({ clientProperties: { connectionClientType: client } }, this.rabbitmqConfig.socketOptions));
115
116
  }
116
117
  async makeAMQPListener(queuesOptions) {
117
118
  return new AmqpListener(await this.getConnection("listener"), this.logger, this.rabbitMQMetricsService, queuesOptions, this.systemServiceName);
@@ -120,7 +121,10 @@ var RabbitMQProvider = class extends EventEmitter {
120
121
  return new AmqpAsserter(await this.getConnection("asserter"), this.logger, this.rabbitmqConfig.declareOptions);
121
122
  }
122
123
  async makeAMQPPublisher() {
123
- return new AmqpPublisher(await this.getConnection("publisher"), this.logger, this.rabbitMQMetricsService, this.systemServiceName);
124
+ return new AmqpPublisher(await this.getConnection("publisher"), this.logger, this.rabbitMQMetricsService, this.systemServiceName, {
125
+ publishTimeout: this.publishTimeout,
126
+ directResponseTimeout: this.directResponseTimeout
127
+ });
124
128
  }
125
129
  async setListener(queuesOptions) {
126
130
  if (!this.listener) {
@@ -2,8 +2,8 @@ import { ExchangeName, ExchangeOptions, MessageBrokerServiceConfig } from "../in
2
2
  import { PublishOptions } from "../interfaces/options.js";
3
3
  import { EventName, QueueName } from "../interfaces/queueConfig/configs.js";
4
4
  import { Message, MessageData, QueueMessageData, QueueMessageMetaData } from "../interfaces/providers/rabbitmq/index.js";
5
+ import { MessagePayload, PublishingResult } from "../providers/rabbitmq/amqpPublisher.types.js";
5
6
  import { MessageHandler } from "../interfaces/messageHandler.js";
6
- import { MessagePayload, PublishingResult } from "../interfaces/providers/rabbitmq/amqpPublisher.js";
7
7
  import { MessageBrokerServiceEventsListener } from "../interfaces/index.js";
8
8
  import { RabbitMQProvider } from "../providers/rabbitmq/index.js";
9
9
  import { OptionsBuilder } from "./optionsBuilder.js";
@@ -1,7 +1,7 @@
1
1
  import { ExchangeName, ExchangeOptions } from "../interfaces/messageBrokerServiceConfig.js";
2
2
  import { PublishOptions } from "../interfaces/options.js";
3
3
  import { EventName, QueueName } from "../interfaces/queueConfig/configs.js";
4
- import { MessagePayload, PublishingResult } from "../interfaces/providers/rabbitmq/amqpPublisher.js";
4
+ import { MessagePayload, PublishingResult } from "../providers/rabbitmq/amqpPublisher.types.js";
5
5
  import { EventBusListener, EventBusQueue, MessageBrokerServiceEventsListener } from "../interfaces/index.js";
6
6
  import { RabbitMQProvider } from "../providers/rabbitmq/index.js";
7
7
  import { Communicator } from "./communicator.js";
@@ -1,5 +1,5 @@
1
1
  import { collectEventBusListeners } from "../utils.js";
2
- import _ from "lodash";
2
+ import lodash from "lodash";
3
3
  //#region src/services/eventCommunicator.ts
4
4
  var EventCommunicator = class {
5
5
  logger;
@@ -31,8 +31,8 @@ var EventCommunicator = class {
31
31
  getUnicastListeners() {
32
32
  const listeners = [];
33
33
  const { queuesOptions, exchangesOptions } = this.queueProvider.getMessageBrokerServiceConfig();
34
- const queuesOptionsMap = _.keyBy(queuesOptions, "name");
35
- const exchangesOptionsMap = _.keyBy(exchangesOptions, "name");
34
+ const queuesOptionsMap = lodash.keyBy(queuesOptions, "name");
35
+ const exchangesOptionsMap = lodash.keyBy(exchangesOptions, "name");
36
36
  for (const eventListener of this.listenerList) {
37
37
  const { queueNames = [] } = eventListener;
38
38
  for (const queueName of queueNames) {
@@ -110,7 +110,7 @@ var ExternalCommunicator = class {
110
110
  * ```
111
111
  */
112
112
  async receiveDirect(event, request = {}, ops) {
113
- const { exchangeName, validationRules, ignoreCache, timeout, registryApiVersion, requestUuid = randomUUID() } = ops;
113
+ const { exchangeName, publishTimeout, validationRules, ignoreCache, timeout, registryApiVersion, requestUuid = randomUUID() } = ops;
114
114
  const payload = {
115
115
  uuid: requestUuid,
116
116
  request
@@ -119,7 +119,8 @@ var ExternalCommunicator = class {
119
119
  ignoreCache,
120
120
  timeout,
121
121
  exchangeName,
122
- registryApiVersion
122
+ registryApiVersion,
123
+ publishTimeout
123
124
  };
124
125
  const externalResponse = await this.externalEventBus.publishDirect(event, payload, options);
125
126
  this.logger.debug("External direct response", externalResponse);
@@ -1,7 +1,7 @@
1
1
  import { ExchangeName, ExchangeOptions } from "../interfaces/messageBrokerServiceConfig.js";
2
2
  import { PublishDirectOptions, PublishOptions } from "../interfaces/options.js";
3
3
  import { EventName } from "../interfaces/queueConfig/configs.js";
4
- import { MessagePayload, PublishingResult } from "../interfaces/providers/rabbitmq/amqpPublisher.js";
4
+ import { MessagePayload, PublishingResult } from "../providers/rabbitmq/amqpPublisher.types.js";
5
5
  import { EventBusListener, ExternalEventBusQueue, MessageBrokerServiceEventsListener } from "../interfaces/index.js";
6
6
  import { RabbitMQProvider } from "../providers/rabbitmq/index.js";
7
7
  import { Communicator } from "./communicator.js";
@@ -29,6 +29,7 @@ declare class ExternalEventBus extends Communicator implements ExternalEventBusQ
29
29
  protected getProducerExchangesOptions(): ExchangeOptions[];
30
30
  protected override getMulticastListeners(): MessageBrokerServiceEventsListener[];
31
31
  private getPublishMessage;
32
+ private getPublishDirectMessage;
32
33
  private getPublishRoutingKey;
33
34
  private defineQueuesAndExchangesOptionsBasedOnGlobalConfig;
34
35
  private buildEventQueueMap;
@@ -35,7 +35,7 @@ var ExternalEventBus = class ExternalEventBus extends Communicator {
35
35
  return `queue.${constants_default.PROJECT_NAME}`;
36
36
  }
37
37
  async publish(eventName, payload, options) {
38
- const message = this.getPublishMessage(eventName, payload, options);
38
+ const message = this.getPublishMessage(eventName, payload);
39
39
  const routingKey = this.getPublishRoutingKey(eventName);
40
40
  return await this.publishEventToExchange(eventName, message, {
41
41
  ...options,
@@ -50,8 +50,12 @@ var ExternalEventBus = class ExternalEventBus extends Communicator {
50
50
  customExchangeName
51
51
  }, ErrorType.Unoperated);
52
52
  const routingKey = ExternalEventBus.BuildRequestRoutingKey(eventName);
53
- const { data } = this.getPublishMessage(eventName, payload, options);
54
- return await this.queueProvider.publishExternalDirect(data, exchangeName, routingKey, options);
53
+ const { data } = this.getPublishDirectMessage(eventName, payload, options);
54
+ const publishDirectMessageOptions = {
55
+ responseTimeout: options.timeout,
56
+ publishTimeout: options.publishTimeout
57
+ };
58
+ return await this.queueProvider.publishExternalDirect(data, exchangeName, routingKey, publishDirectMessageOptions);
55
59
  }
56
60
  getUnicastListeners() {
57
61
  return this.eventCommunicator.getUnicastListeners();
@@ -67,7 +71,13 @@ var ExternalEventBus = class ExternalEventBus extends Communicator {
67
71
  const [exchangesOptions, queuesOptions] = this.defineQueuesAndExchangesOptionsBasedOnGlobalConfig();
68
72
  return this.eventCommunicator.getMulticastListeners(queuesOptions, exchangesOptions, this.eventQueueMap);
69
73
  }
70
- getPublishMessage(eventName, message, options) {
74
+ getPublishMessage(eventName, message) {
75
+ const { rabbit: { custom: { responseRoutingKeyPrefix } = {} } } = this.queueProvider.getConfig();
76
+ const responseRoutingKey = this.buildResponseQueueName(eventName, responseRoutingKeyPrefix);
77
+ const partialMeta = this.publishEventsSet.has(eventName) ? { responseRoutingKey } : {};
78
+ return new Message(this.getPublishQueueMessageData(eventName, message, partialMeta));
79
+ }
80
+ getPublishDirectMessage(eventName, message, options) {
71
81
  const { rabbit: { custom: { responseRoutingKeyPrefix } = {} } } = this.queueProvider.getConfig();
72
82
  const responseRoutingKey = this.buildResponseQueueName(eventName, responseRoutingKeyPrefix);
73
83
  const partialMeta = {
@@ -1,6 +1,6 @@
1
1
  import { ExchangeName, ExchangeOptions } from "../interfaces/messageBrokerServiceConfig.js";
2
2
  import { QueueName } from "../interfaces/queueConfig/configs.js";
3
- import { PublishingResult } from "../interfaces/providers/rabbitmq/amqpPublisher.js";
3
+ import { PublishingResult } from "../providers/rabbitmq/amqpPublisher.types.js";
4
4
  import { EventBusListener, MessageBrokerServiceEventsListener, ScheduledTasksQueue } from "../interfaces/index.js";
5
5
  import { RabbitMQProvider } from "../providers/rabbitmq/index.js";
6
6
  import { Communicator } from "./communicator.js";
@@ -1,5 +1,5 @@
1
1
  import { ExchangeOptions } from "../interfaces/messageBrokerServiceConfig.js";
2
- import { MessagePayload, PublishingResult } from "../interfaces/providers/rabbitmq/amqpPublisher.js";
2
+ import { MessagePayload, PublishingResult } from "../providers/rabbitmq/amqpPublisher.types.js";
3
3
  import { MessageBrokerServiceListener, TaskListener, TaskQueue } from "../interfaces/index.js";
4
4
  import { RabbitMQProvider } from "../providers/rabbitmq/index.js";
5
5
  import { Communicator } from "./communicator.js";
@@ -2,7 +2,7 @@ import { QueueTypes } from "../interfaces/messageBrokerServiceConfig.js";
2
2
  import "../interfaces/index.js";
3
3
  import constants_default from "../constants.js";
4
4
  import Communicator from "./communicator.js";
5
- import _ from "lodash";
5
+ import lodash from "lodash";
6
6
  //#region src/services/task.ts
7
7
  var Task = class extends Communicator {
8
8
  serviceName;
@@ -18,8 +18,8 @@ var Task = class extends Communicator {
18
18
  }
19
19
  async onInit() {
20
20
  const { queuesOptions, exchangesOptions } = await this.init();
21
- const queuesOptionsMap = _.keyBy(queuesOptions, "name");
22
- const exchangesOptionsMap = _.keyBy(exchangesOptions, "name");
21
+ const queuesOptionsMap = lodash.keyBy(queuesOptions, "name");
22
+ const exchangesOptionsMap = lodash.keyBy(exchangesOptions, "name");
23
23
  for (const task of this.taskList) {
24
24
  const { name: taskName, isDelayed = false, queueNames = [] } = task;
25
25
  if (queueNames.length === 0) {
@@ -69,8 +69,8 @@ var Task = class extends Communicator {
69
69
  getUnicastListeners() {
70
70
  const listeners = [];
71
71
  const { queuesOptions, exchangesOptions } = this.queueProvider.getMessageBrokerServiceConfig();
72
- const queuesOptionsMap = _.keyBy(queuesOptions, "name");
73
- const exchangesOptionsMap = _.keyBy(exchangesOptions, "name");
72
+ const queuesOptionsMap = lodash.keyBy(queuesOptions, "name");
73
+ const exchangesOptionsMap = lodash.keyBy(exchangesOptions, "name");
74
74
  for (const task of this.taskList) {
75
75
  const { queueNames = [], name: taskName, isDelayed = false } = task;
76
76
  if (queueNames.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diia-inhouse/diia-queue",
3
- "version": "14.0.20",
3
+ "version": "14.0.22",
4
4
  "type": "module",
5
5
  "description": "Package provide queue functionality",
6
6
  "main": "dist/index.js",
@@ -37,8 +37,7 @@
37
37
  "dependencies": {
38
38
  "@types/amqplib": "0.10.8",
39
39
  "amqplib": "0.10.9",
40
- "lodash": "4.18.1",
41
- "p-timeout": "4.1.0"
40
+ "lodash": "4.18.1"
42
41
  },
43
42
  "peerDependencies": {
44
43
  "@diia-inhouse/diia-logger": ">=4.0.0",
@@ -52,15 +51,15 @@
52
51
  },
53
52
  "devDependencies": {
54
53
  "@diia-inhouse/configs": "7.0.1",
55
- "@diia-inhouse/diia-logger": "4.3.12",
54
+ "@diia-inhouse/diia-logger": "4.3.13",
56
55
  "@diia-inhouse/diia-metrics": "7.1.23",
57
- "@diia-inhouse/env": "3.3.11",
58
- "@diia-inhouse/errors": "2.1.10",
59
- "@diia-inhouse/oxc-config": "1.10.2",
60
- "@diia-inhouse/test": "8.2.8",
56
+ "@diia-inhouse/env": "3.3.12",
57
+ "@diia-inhouse/errors": "2.1.11",
58
+ "@diia-inhouse/oxc-config": "1.11.0",
59
+ "@diia-inhouse/test": "8.2.9",
61
60
  "@diia-inhouse/types": "13.2.2",
62
- "@diia-inhouse/utils": "6.0.20",
63
- "@diia-inhouse/validators": "2.2.16",
61
+ "@diia-inhouse/utils": "6.0.21",
62
+ "@diia-inhouse/validators": "2.2.17",
64
63
  "@opentelemetry/api": "1.9.0",
65
64
  "@types/lodash": "4.17.24",
66
65
  "@types/node": "25.6.2",
@@ -1,20 +0,0 @@
1
- import { Headers } from "./index.js";
2
- import { MessagePropertyHeaders } from "amqplib/properties";
3
-
4
- //#region src/interfaces/providers/rabbitmq/amqpPublisher.d.ts
5
- type MessagePayload = unknown;
6
- interface MessageHeaders {
7
- traceId: string;
8
- serviceCode?: string;
9
- "x-delay"?: number;
10
- }
11
- interface DirectResponseHeaders extends MessagePropertyHeaders {
12
- [Headers.handledBy]?: string;
13
- }
14
- interface DirectResponse<T = unknown> extends MessagePropertyHeaders {
15
- body: T;
16
- headers: DirectResponseHeaders;
17
- }
18
- type PublishingResult = void;
19
- //#endregion
20
- export { DirectResponse, DirectResponseHeaders, MessageHeaders, MessagePayload, PublishingResult };