UNPKG

zamza

Version:

Apache Kafka discovery, indexing, searches, storage, hooks and HTTP gateway

135 lines (134 loc) 4.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Debug = require("debug"); const debug = Debug("zamza:replayhandler"); const uuid = require("uuid"); const MirrorConsumer_1 = require("./kafka/MirrorConsumer"); const MessageHandler_1 = require("./MessageHandler"); class ReplayHandler { constructor(zamza) { this.zamza = zamza; this.instanceId = uuid.v4(); debug("Instance Replay ID:", this.instanceId); this.replayModel = zamza.mongoWrapper.getReplay(); this.replayProducer = zamza.replayProducer; this.metrics = zamza.metrics; this.mirrorConsumer = null; this.currentTargetTopic = null; this.currentConsumerGroup = null; } createConsumerGroupId() { return `zamza-internal-mirror-${uuid.v4()}`; } async messageHandle(message) { const replayMessage = { message, }; this.metrics.inc("mirrored_messages"); await this.replayProducer.produceMessage(MessageHandler_1.INTERNAL_TOPICS.REPLAY_TOPIC, undefined, undefined, JSON.stringify(replayMessage)); } isCurrentlyRunning() { if (this.mirrorConsumer) { return true; } else { return false; } } dealsWithTopic(topic) { if (this.currentTargetTopic === topic) { return true; } else { return false; } } async getCurrentReplay() { // clean-up const replayForInstanceId = await this.replayModel.getForInstanceId(this.instanceId); if (replayForInstanceId && !this.isCurrentlyRunning()) { await this.replayModel.delete(replayForInstanceId.topic); } // clean-up if (!replayForInstanceId && this.isCurrentlyRunning()) { await this.replayModel.upsert({ instanceId: this.instanceId, topic: this.currentTargetTopic, consumerGroup: this.currentConsumerGroup, timestamp: Date.now(), }); } return { instanceId: this.instanceId, replay: await this.replayModel.getForInstanceId(this.instanceId), }; } async isBeingReplayedByAnyInstance(topic) { const replay = await this.replayModel.get(topic); return !!replay; } async flushall() { debug("Flushing all instances.."); await this.flushone(); await this.replayModel.truncate(); debug("Flushed."); return true; } async flushone() { debug("Flushing current instance"); if (this.currentTargetTopic) { await this.replayModel.delete(this.currentTargetTopic); } await this.replayModel.deleteForInstanceId(this.instanceId); if (this.mirrorConsumer) { await this.mirrorConsumer.close(); } this.mirrorConsumer = null; this.currentConsumerGroup = null; this.currentTargetTopic = null; debug("Flushed."); return true; } listReplays() { return this.replayModel.list(); } async startReplay(topic, consumerGroup) { if (this.mirrorConsumer) { throw new Error("Consumer is already running on this instance."); } debug("Starting replay.."); const replay = { instanceId: this.instanceId, topic, consumerGroup: consumerGroup ? consumerGroup : this.createConsumerGroupId(), timestamp: Date.now(), }; this.currentConsumerGroup = replay.consumerGroup; this.currentTargetTopic = topic; await this.replayModel.upsert(replay); this.mirrorConsumer = new MirrorConsumer_1.default(Object.assign(this.zamza.config.kafka, { consumer: this.zamza.cloneKafkaConsumerConfig(replay.consumerGroup, this.zamza.config.kafka), }), this.zamza); this.mirrorConsumer.start(this.messageHandle.bind(this)); this.mirrorConsumer.adjustSubscriptions([replay.topic]); return replay; } async stopReplay() { if (!this.mirrorConsumer) { throw new Error("No consumer running on this instance."); } debug("Stopping replay.."); await this.mirrorConsumer.close(); await this.replayModel.delete(this.currentTargetTopic); this.mirrorConsumer = null; this.currentTargetTopic = null; this.currentConsumerGroup = null; return true; } async close() { if (this.mirrorConsumer) { await this.mirrorConsumer.close(); } } } exports.ReplayHandler = ReplayHandler;