UNPKG

gamecloud

Version:
149 lines (137 loc) 5.12 kB
let facade = require('../Facade') let CoreOfBase = facade.CoreOfBase let um = facade.tools.updateMgr /** * 通用监控对象 * 在系统启动时,会创建一个唯一的监控对象,并持久保存在缓存列表中 */ class commonMonitor { /** * 可以直接传入闭包,也可以传入对象或者类(interface.RunMonitor) * @param {*} cls */ constructor(cls){ if(!!cls.name){ this.id = `system.${cls.name}`; //特殊任务编号 } else { this.id = `system.${(Math.random()*10000000)|0}`; //特殊任务编号 } this.cls = cls; } /** * 执行逻辑 * @param {CoreOfBase} fo * @return * true :状态失效,监控任务将被移出队列,不再接受检测 * false :状态有效,监控任务继续停留在队列中,接受后续检测 */ async execute(fo) { let ret = true; if(!!this.cls) { if(!!this.cls.RunMonitor && this.cls.RunMonitor.constructor == Function) { try { ret = await this.cls.RunMonitor(fo) } catch(e) { console.log('commonMonitor', e); } } else if(this.cls.constructor == Function){ try { ret = await this.cls(fo); } catch(e) { console.log('commonMonitor', e); } } } return ret; } } /** * 自动任务管理器,目前只支持同步任务 */ class AutoTaskManager { /** * 构造函数 * @param {CoreOfBase} core 核心对象 */ constructor(core){ this.core = core; //注入核心对象 //延期自动执行任务的缓存列表 this.updateRecord = {}; //持续监控任务的缓存列表 this.monitorRecord = {}; //tick检测 let self = this; (new um(1000)).tick(0, () => { //每秒检测一次、持续不断 return self.checkTask.apply(self); }); } /** * 添加一个自动任务,延迟执行后自动销毁 * @param {*} task 任务对象 * @param {Number} delay 延迟时间,单位毫秒,默认30s * 应用场景: * 1、实体类的实例的延迟写。例如在user数据变化时添加一个自动任务,一定时间内发生的多个自动任务会合并为同一个条目 * @note * id相同的自动任务会相互覆盖 */ addTask(task, delay=30000){ if(!this.updateRecord[task.id]){ task.$taskTime = new um(delay); this.updateRecord[task.id] = task; } } /** * 添加一个监视器,定期进行状态检测,当状态失效时退出监视、销毁监视器 * @note * id相同的监控器会相互覆盖 * @param {*} monitor 监视器对象或者闭包 * @param {Number} recy 检测周期,单位毫秒,默认30秒 */ addMonitor(monitor, recy=30000){ if(!this.monitorRecord[monitor.id]){ monitor.$taskTime = new um(recy); this.monitorRecord[monitor.id] = monitor; } } addCommonMonitor(func, recy=30000){ this.addMonitor(new commonMonitor(func), recy); } /** * tick事件句柄 */ async checkTask() { try { let curTime = (new Date()).valueOf(); //检测监视器状态,当状态失效时,就从监控列表中删除 for(let id of Object.keys(this.monitorRecord)) { if(this.monitorRecord[id].$taskTime.check()) { //监控周期时间检测 let ret = await this.monitorRecord[id].execute(this.core); if(!!ret) { delete this.monitorRecord[id]; } } } //执行自动任务,其主要目的是在延迟期内合并一系列同类任务,以降低IO压力 let recy = this.core.options.PoolMax / 2; //控制并发数量的循环变量 for(let id of Object.keys(this.updateRecord)){ if(recy > 0){//并发控制检测 if(this.updateRecord[id].$taskTime.check()) {//延迟时间检测 recy--; //并发数量减1 this.updateRecord[id].execute(this.core); //执行自动任务 delete this.updateRecord[id]; //删除自动任务 } } } //在系统关闭前必须反复调用checkTask,直至列表尺寸为0,以保证所有自动任务得以执行 return Object.keys(this.updateRecord).length; } catch(e){ console.error(e); } } } module.exports = AutoTaskManager;