import { Client, Producer, Message, MessageId } from "pulsar-client";
import { Container, Scope, Singleton, Inject } from "typescript-ioc";
import { PulsarMasterFactory } from "../pulsar/PulsarMasterFactory";
import { BaseEventHandler } from "./BaseEventHandler";
import { Payload } from "../model/Payload";
import { RedisUtil } from '../redis/RedisUtil';
import { Config } from '../config/Config'


@Singleton
export class Consumer {
    @Inject
    private pulsarMasterFactory: PulsarMasterFactory;

    async consume(payload: Payload, baseEventHandler: BaseEventHandler) {
        await this.consumeFromMaster(payload, baseEventHandler)
    }

    private async consumeFromMaster(payload: Payload, baseEventHandler: BaseEventHandler) {
        let subscriptionId = Config.getSubscriptionId()
        let majorVersion = payload.getVersion().toString().split(".")[0]
        let client: Client = await this.pulsarMasterFactory.get();
        const redsiLock = Container.get(RedisUtil)
        await client.subscribe({
            topic: payload.getTopic(),
            subscription: `${subscriptionId}-${majorVersion}`,
            subscriptionType: 'Shared',
            listener: async (msg, msgConsumer) => {
                let msgId = msg.getData().getMsgId();
                //使用Redis分布式锁锁5秒
                const lock = await redsiLock.lock(msgId, 5000)
                if (!lock) {
                    console.info('获取redis分布式锁失败....')
                    msgConsumer.acknowledge(msg);
                    return
                }
                const currentVersion: number = msg.getProperties()["version"];
                try {
                    await baseEventHandler.handle(msg.getData())
                    msgConsumer.acknowledge(msg);
                } catch (e) {
                    console.log('执行事件处理器发生异常:' + e)
                } finally {
                    await redsiLock.unlock(lock)
                }
            },
        });
    }
}