"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DataRetentionTask = void 0;
const const_1 = require("../../../../../schema-definitions/const");
const integration_engine_1 = require("@golemio/core/dist/integration-engine");
const workers_1 = require("@golemio/core/dist/integration-engine/workers");
const redis_semaphore_1 = require("@golemio/core/dist/shared/redis-semaphore");
const sequelize_1 = require("@golemio/core/dist/shared/sequelize");
const const_2 = require("../../../../../const");
class DataRetentionTask extends workers_1.AbstractEmptyTask {
    constructor(queuePrefix) {
        super(queuePrefix);
        this.queueName = "dataRetention";
        this.queueTtl = 1 * 10 * 60 * 1000; // 10 minutes
        this.LOCKKEYPHRASE = "vehiclePositionsDataRetentionTask";
        this.maintenanceEnabled = integration_engine_1.config.vehiclePositions.dataMaintenanceEnabled;
        this.lockTimeout = integration_engine_1.config.vehiclePositions.dataRetentionLockTimeout;
        this.refreshInterval = this.lockTimeout * 0.8; // recommended
    }
    async execute() {
        const mutex = this.createMutex();
        const lockAcquired = await mutex.tryAcquire();
        if (!lockAcquired) {
            integration_engine_1.log.error(`VP Worker - unable to obtain mutex lock.`);
            return;
        }
        try {
            const sequelize = integration_engine_1.PostgresConnector.getConnection();
            const result = await sequelize.query(`CALL ${const_1.PG_SCHEMA}.vehiclepositions_data_retention(0,${const_2.DATA_RETENTION_IN_MINUTES});`, {
                plain: true,
                type: sequelize_1.QueryTypes.SELECT,
            });
            integration_engine_1.log.silly(`VP Worker - dataRention ${JSON.stringify(result?.numberofrows)} transformed to historic tables.`);
            if (!mutex.isAcquired) {
                integration_engine_1.log.warn(`VP Worker - mutex lock was lost after procedure vehiclepositions_data_retention.`);
                return;
            }
            await this.maintainTables(result, sequelize, mutex);
        }
        finally {
            await mutex.release();
        }
    }
    createMutex() {
        const redisClient = integration_engine_1.RedisConnector.getConnection();
        return new redis_semaphore_1.Mutex(redisClient, this.LOCKKEYPHRASE, {
            acquireAttemptsLimit: 1,
            lockTimeout: this.lockTimeout,
            refreshInterval: this.refreshInterval,
            onLockLost: (err) => {
                integration_engine_1.log.warn(`VP Worker - ${err.message}`);
            },
        });
    }
    async maintainTables(result, sequelize, mutex) {
        if (this.maintenanceEnabled && result?.numberofrows) {
            integration_engine_1.log.silly(`VP Worker - dataRention starting maintenance`);
            const commands = this.getMaintenanceCommands();
            for (const command of commands) {
                await sequelize.query(command);
                integration_engine_1.log.silly(`VP Worker - ${command} done`);
                if (!mutex.isAcquired) {
                    integration_engine_1.log.warn(`VP Worker - mutex lock was lost after command: ${command}`);
                    return;
                }
            }
        }
    }
    getMaintenanceCommands() {
        return [
            `REINDEX TABLE CONCURRENTLY ${const_1.PG_SCHEMA}.vehiclepositions_trips;`,
            `REINDEX TABLE CONCURRENTLY ${const_1.PG_SCHEMA}.vehiclepositions_positions;`,
        ];
    }
}
exports.DataRetentionTask = DataRetentionTask;
//# sourceMappingURL=DataRetentionTask.js.map