UNPKG

@awesomeniko/kafka-trail

Version:

A Node.js library for managing message queue with Kafka

80 lines 3.6 kB
import { PartitionAssigners } from "kafkajs"; import { ConsumerSubscribeError } from "../custom-errors/kafka-errors.js"; import { ifNanUseDefaultNumber } from "../libs/helpers/castings.js"; import { retry } from "../libs/helpers/retry.js"; import { KTKafkaBroker } from "./kafka-broker.js"; class KTKafkaConsumer extends KTKafkaBroker { #isConnected = false; #logger; heartBeatInterval; consumer; #subscribeRetry = { interval: 2000, retries: 50, }; #subscribeFromBeginning = false; heartbeatEarlyFactor = 0.1; constructor(params) { super(params); const { consumerGroupId, subscribeFromBeginning, subscribeRetries, subscribeRetryInterval, heartbeatInterval, heartbeatEarlyFactor, sessionTimeout, maxWaitTimeInMs, maxBytesPerPartition, maxInFlightRequests, rebalanceTimeout, maxBytes, partitionAssignerFn, } = params.kafkaSettings; if (!consumerGroupId) { throw new Error("group id must be provided"); } const { logger } = params; this.#logger = logger; this.#subscribeRetry.retries = ifNanUseDefaultNumber(subscribeRetries, 30); this.#subscribeRetry.interval = ifNanUseDefaultNumber(subscribeRetryInterval, 2000); this.#subscribeFromBeginning = subscribeFromBeginning ?? true; this.heartBeatInterval = ifNanUseDefaultNumber(heartbeatInterval, 5000); this.heartbeatEarlyFactor = ifNanUseDefaultNumber(heartbeatEarlyFactor, 0.1); const maxWaitTimeInMsParam = ifNanUseDefaultNumber(maxWaitTimeInMs, 5000); const sessionTimeoutParam = ifNanUseDefaultNumber(sessionTimeout, 60000); const maxBytesPerPartitionParam = ifNanUseDefaultNumber(maxBytesPerPartition, 10_485_760); const maxInFlightRequestsParam = ifNanUseDefaultNumber(maxInFlightRequests, 1); const rebalanceTimeoutParam = ifNanUseDefaultNumber(rebalanceTimeout, 60_000); const maxBytesParam = ifNanUseDefaultNumber(maxBytes, 10_485_760); const partitionsAssignersFunctions = [PartitionAssigners.roundRobin]; if (partitionAssignerFn) { partitionsAssignersFunctions.unshift(partitionAssignerFn); } this.consumer = this._kafka.consumer({ groupId: consumerGroupId, allowAutoTopicCreation: false, heartbeatInterval: this.heartBeatInterval, sessionTimeout: sessionTimeoutParam, maxWaitTimeInMs: maxWaitTimeInMsParam, maxBytesPerPartition: maxBytesPerPartitionParam, maxInFlightRequests: maxInFlightRequestsParam, rebalanceTimeout: rebalanceTimeoutParam, partitionAssigners: partitionsAssignersFunctions, maxBytes: maxBytesParam, }); } isConnected() { return this.#isConnected; } async init() { await this.consumer.connect(); this.#isConnected = true; return this.isConnected(); } async destroy() { await this.consumer.stop(); this.#isConnected = false; await this.consumer.disconnect(); } async subscribeTopic(topics) { const isSubscribed = await retry(async () => await this.consumer.subscribe({ topics, fromBeginning: this.#subscribeFromBeginning, }), this.#logger, { maxRetries: this.#subscribeRetry.retries, interval: this.#subscribeRetry.interval, }); if (!isSubscribed) { throw new ConsumerSubscribeError(); } } } export { KTKafkaConsumer }; //# sourceMappingURL=kafka-consumer.js.map