@awesomeniko/kafka-trail
Version:
A Node.js library for managing message queue with Kafka
140 lines • 5.52 kB
JavaScript
import { context, SpanKind, trace } from "@opentelemetry/api";
import { pino } from "pino";
import { ArgumentIsRequired, NoHandlersError } from "../custom-errors/kafka-errors.js";
import { KTKafkaConsumer } from "../kafka/kafka-consumer.js";
import { KTKafkaProducer } from "../kafka/kafka-producer.js";
import { KafkaTopicName } from "../libs/branded-types/kafka/index.js";
class KTMessageQueue {
constructor(params) {
let ctx = params?.ctx();
if (!ctx) {
ctx = {};
}
if (!ctx.logger) {
ctx.logger = pino();
}
this.
}
getConsumer() {
return this.
}
getProducer() {
return this.
}
async initProducer(params) {
const { kafkaSettings: { brokerUrls } } = params;
if (!brokerUrls || !brokerUrls.length) {
throw new ArgumentIsRequired('brokerUrls');
}
this.
await this.
}
async initConsumer(params) {
const registeredHandlers = [...this.
if (registeredHandlers.length === 0) {
throw new NoHandlersError('subscribe to consumer');
}
this.
await this.
await this.
}
async destroyAll() {
await Promise.all([
this.destroyProducer(),
this.destroyConsumer(),
]);
}
async destroyProducer() {
if (this.
await this.
}
}
async destroyConsumer() {
if (this.
await this.
}
}
async
const topicNames = [...this.
await this.
await this.
eachBatchAutoResolve: false,
partitionsConsumedConcurrently: 1,
eachBatch: async (eachBatchPayload) => {
const tracer = trace.getTracer(`kafka-trail`, '1.0.0');
const span = tracer.startSpan(`kafka-trail: eachBatch`, {
kind: SpanKind.CONSUMER,
attributes: {
'messaging.system': 'kafka',
'messaging.destination': topicNames,
},
});
await context.with(trace.setSpan(context.active(), span), async () => {
const { batch: { topic, messages, partition } } = eachBatchPayload;
const topicName = KafkaTopicName.fromString(topic);
const handler = this.
if (handler) {
const batchedValues = [];
let lastOffset = undefined;
for (const message of messages) {
if (batchedValues.length < handler.topic.topicSettings.batchMessageSizeToConsume) {
if (message.value) {
const decodedMessage = handler.topic.decode(message.value);
batchedValues.push(decodedMessage);
lastOffset = message.offset;
}
}
else {
break;
}
}
await handler.run(batchedValues, this.
partition,
lastOffset,
});
if (lastOffset) {
eachBatchPayload.resolveOffset(lastOffset);
}
}
await eachBatchPayload.heartbeat();
span.end();
});
},
});
}
async initTopics(topicEvents) {
if (!this.
throw new Error("Producer field is required");
}
for (const topicEvent of topicEvents) {
await this.
}
}
getRegisteredHandler(topic) {
return this.
}
registerHandlers(mqHandlers) {
for (const handler of mqHandlers) {
if (!this.
this.
}
else {
this.
}
}
}
publishSingleMessage(topic) {
return this.
topicName: topic.topicName,
message: topic.message,
messageKey: topic.messageKey,
}, topic.meta);
}
}
export { KTMessageQueue };
//# sourceMappingURL=index.js.map