"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MagicAsyncTask = void 0;
const bull = require("@midwayjs/bull");
const decorator_1 = require("@midwayjs/decorator");
const constant_1 = require("../constant");
const core_1 = require("./core");
const definition_1 = require("./definition");
let MagicAsyncTask = class MagicAsyncTask {
    constructor() {
        this.type = 'asyncTask';
        this.idInMappingPath = new Map();
    }
    async init(reInit = false) {
        if (reInit) {
            this.logger.info('重新初始化MagicAsyncTask');
            for (const key of this.idInMappingPath.keys()) {
                await this.removeById(key);
            }
            this.idInMappingPath.clear();
        }
        else {
            this.logger.info('初始化MagicAsyncTask');
        }
        const resources = await this.magicResourceService.findByType(constant_1.RESOURCE_TYPE.AsyncTask);
        for (const resource of resources) {
            await this.add(resource);
        }
    }
    /**
     * 添加异步任务
     * @param resource
     */
    async add(resource) {
        var _a;
        const { id, script } = resource;
        await this.removeById(id);
        const mappingPath = await this.magicResourceService.getMappingPath(resource);
        this.idInMappingPath.set(id, mappingPath);
        const asyncTaskDefinition = (0, definition_1.AsyncTaskDefinition)(script);
        const currentQueue = this.bullFramework.ensureQueue(`asyncTask:${mappingPath}`);
        if (this.bullConfig.bullClearRepeatJobWhenStart) {
            const jobs = await currentQueue.getRepeatableJobs();
            for (const job of jobs) {
                await currentQueue.removeRepeatableByKey(job.key);
            }
        }
        currentQueue.process((_a = this.bullConfig.defaultConcurrency) !== null && _a !== void 0 ? _a : 1, async (job) => {
            const ctx = this.bullFramework.app.createAnonymousContext({
                type: '异步任务',
                jobId: job.id,
                job,
                from: {
                    name: `asyncTask:${mappingPath}`,
                },
            });
            ctx.logger.info(`start process job ${job.id} from asyncTask:${mappingPath}`);
            try {
                const result = await (0, definition_1.AsyncTaskHandler)(ctx, job.data, job, asyncTaskDefinition);
                ctx.logger.info(`complete process job ${job.id} from asyncTask:${mappingPath}`);
                return result;
            }
            catch (err) {
                ctx.logger.error(err);
                return Promise.reject(err);
            }
        });
        this.logger.info('注册异步任务:[%s]', mappingPath);
    }
    /**
     * 删除异步任务
     * @param id
     */
    async removeById(id) {
        if (this.idInMappingPath.has(id)) {
            const mappingPath = this.idInMappingPath.get(id);
            this.idInMappingPath.delete(id);
            const bullQueue = this.bullFramework.getQueue(`asyncTask:${mappingPath}`);
            if (bullQueue) {
                await bullQueue.close();
                this.logger.info('删除异步任务成功:[%s]', mappingPath);
            }
        }
    }
    /**
     * 执行任务
     * @param mappingPath 路径
     * @param data 执行参数
     * @param options 任务选项
     */
    async execute(mappingPath, data, options) {
        const bullQueue = this.bullFramework.getQueue(`asyncTask:${mappingPath}`);
        return await (bullQueue === null || bullQueue === void 0 ? void 0 : bullQueue.runJob(data, options));
    }
    /**
     * 停止任务
     * @param mappingPath 路径
     * @param jobId 任务id
     */
    async removeTask(mappingPath, jobId) {
        const bullQueue = this.bullFramework.getQueue(`asyncTask:${mappingPath}`);
        if (bullQueue) {
            await bullQueue.removeJobs(`${mappingPath}:${jobId}`);
        }
    }
    /**
     * 获取任务
     * @param mappingPath 路径
     * @param id 任务id
     */
    async getTask(mappingPath, id) {
        const bullQueue = this.bullFramework.getQueue(`asyncTask:${mappingPath}`);
        if (bullQueue) {
            return await bullQueue.getJob(`${mappingPath}:${id}`);
        }
    }
};
__decorate([
    (0, decorator_1.Inject)(),
    __metadata("design:type", bull.Framework)
], MagicAsyncTask.prototype, "bullFramework", void 0);
__decorate([
    (0, decorator_1.Inject)(),
    __metadata("design:type", core_1.MagicResourceService)
], MagicAsyncTask.prototype, "magicResourceService", void 0);
__decorate([
    (0, decorator_1.Logger)('magic'),
    __metadata("design:type", Object)
], MagicAsyncTask.prototype, "logger", void 0);
__decorate([
    (0, decorator_1.Config)('bull'),
    __metadata("design:type", Object)
], MagicAsyncTask.prototype, "bullConfig", void 0);
MagicAsyncTask = __decorate([
    (0, decorator_1.Provide)(),
    (0, decorator_1.Scope)(decorator_1.ScopeEnum.Singleton)
], MagicAsyncTask);
exports.MagicAsyncTask = MagicAsyncTask;
//# sourceMappingURL=magic.async.task.js.map