UNPKG

sdg

Version:

pomelo ts

303 lines 22.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const lodash_1 = tslib_1.__importDefault(require("lodash")); const node_schedule_1 = tslib_1.__importDefault(require("node-schedule")); const sdg_loader_1 = require("sdg-loader"); const base_1 = tslib_1.__importDefault(require("../base")); const handlerService_1 = tslib_1.__importDefault(require("../common/service/handlerService")); const filterService_1 = tslib_1.__importDefault(require("../common/service/filterService")); const events_1 = tslib_1.__importDefault(require("../util/events")); const Constants = tslib_1.__importStar(require("../util/constants")); const pathUtil_1 = require("../util/pathUtil"); const { INIT, STARTED, STOPPED } = Constants.STATE; class Server extends base_1.default { constructor(app, opts) { super(app, opts); this.cronHandlers = {}; this.crons = []; this.cronConfigs = {}; this.jobs = {}; this.state = INIT; this.cronConfigs = opts.cronConfigs || {}; app.event.on(events_1.default.ADD_CRONS, this.addCrons.bind(this)); app.event.on(events_1.default.REMOVE_CRONS, this.removeCrons.bind(this)); } start() { if (this.state > INIT) return; this.handlerService = this.initHandler(); this.globalFilterService = this.initFilter(); this.filterService = this.initFilter(false); this.initCrons(true, true); this.state = STARTED; } afterStart() { } stop() { this.state = STOPPED; } /** * 初始化crons * @param manualReload 是否替换 * @param clear 是否清空 */ initCrons(manualReload = false, clear = false) { if (manualReload) { this.app.logger.debug('loadCrons remove crons', { crons: this.crons }); this.removeCrons(this.crons.map(c => c.id)); if (clear) { this.crons = []; } } this.cronHandlers = this.loadCronHandlers(manualReload); this.loadCrons(manualReload); if (manualReload) { this.createSchedule(this.crons); } } /** * 获取所有定时器 */ getCrons() { return this.crons.map(c => { return Object.assign(Object.assign({}, c), { active: !!this.jobs[c.id] }); }); } async globalHandle(msg, session) { const routeRecord = this.parseRoute(msg.__route__); if (!routeRecord) throw `invalid route ${msg.__route__}`; let res; const errorHandler = this.app.get(Constants.RESERVED.GLOBAL_ERROR_HANDLER); try { await this.beforeFilter(true, routeRecord, msg, session); // 校验路由,如果是本服,直接handle if (this.app.getServerType() === routeRecord.serverType) { res = await this.doHandle(msg, session, routeRecord); } else { // 非本地路由,交给sysRpc处理 res = await this.doForward(msg, session, routeRecord); } } catch (err) { if (errorHandler) err = await errorHandler(err, msg, session); throw err; } finally { await this.afterFilter(true, routeRecord, msg, session); } return res; } async handle(msg, session) { if (this.state !== STARTED) throw 'server not started'; const routeRecord = this.parseRoute(msg.__route__); if (!routeRecord) throw `[${msg.__route__}] is invalid`; return this.doHandle(msg, session, routeRecord); } async doHandle(msg, session, routeRecord) { let res; const errHandler = this.app.get(Constants.RESERVED.ERROR_HANDLER); try { await this.beforeFilter(false, routeRecord, msg, session); res = await this.handlerService.handle(routeRecord, msg, session); } catch (e) { if (errHandler) e = await errHandler(e, msg, session); throw e; } finally { await this.afterFilter(false, routeRecord, msg, session); } return res; } async doForward(msg, session, routeRecord) { return this.app.sysRpc[routeRecord.serverType].msgRemote.forwardMessage(session, msg, session.export()); } initHandler() { return new handlerService_1.default(this.app, this.opts); } initFilter(isGlobal = true) { const app = this.app; let service = new filterService_1.default(); let befores, afters; if (isGlobal) { befores = app.get(Constants.KEYWORDS.GLOBAL_BEFORE_FILTER); afters = app.get(Constants.KEYWORDS.GLOBAL_AFTER_FILTER); } else { befores = app.get(Constants.KEYWORDS.BEFORE_FILTER); afters = app.get(Constants.KEYWORDS.AFTER_FILTER); } if (befores) befores.map(i => service.addBefore(i)); if (afters) afters.map(i => service.addAfter(i)); return service; } async beforeFilter(isGlobal, routeRecord, msg, session) { const fm = isGlobal ? this.globalFilterService : this.filterService; if (fm) { await fm.beforeFilter(routeRecord, msg, session); } } async afterFilter(isGlobal, routeRecord, msg, session) { const fm = isGlobal ? this.globalFilterService : this.filterService; if (fm) { if (isGlobal) { // 全局filter,延迟执行afterFilter,防止影响res; process.nextTick(() => fm.afterFilter(routeRecord, msg, session).then()); } else { await fm.afterFilter(routeRecord, msg, session); } } } /** * 加载定时器handler * @param manualReload */ loadCronHandlers(manualReload = false) { const app = this.app; let all = {}; let p = pathUtil_1.getCronPath(app.getBase(), app.getServerType()); if (p) { const cron = sdg_loader_1.load(p, app, manualReload); for (let name in cron) { all[name] = cron[name]; } } for (let plugin of app.usedPlugins) { if (plugin.cronPath) { const cron = sdg_loader_1.load(plugin.cronPath, app, manualReload); for (let name in cron) { all[name] = cron[name]; } } } return all; } /** * 根据配置加载定时器 * @param manualReload 是否替换旧的 */ loadCrons(manualReload = false) { const cronConfigs = this.cronConfigs; if (!cronConfigs) return; const app = this.app; for (let serverType in cronConfigs) { if (app.serverType === serverType) { for (const c of cronConfigs[serverType]) { if (!c.serverId) { this.checkAndAdd(c, manualReload); } else if (c.serverId === app.serverId) { this.checkAndAdd(c, manualReload); } } } } } /** * 增加定时器 * @param crons */ addCrons(crons) { this.app.logger.debug('add crons', { crons }); const newCrons = []; crons.forEach(c => { const nc = this.checkAndAdd(c, true); // 记录符合条件的cron if (nc) newCrons.push(nc); }); // 移除已存在的cron this.removeCrons(newCrons.map(n => n.id)); this.createSchedule(newCrons); } /** * 检查并添加cron * @param cron * @param replace */ checkAndAdd(cron, replace = false) { const oldCron = lodash_1.default.find(this.crons, { id: cron.id }); if (!oldCron) { this.crons.push(cron); return cron; } if (replace) { this.app.logger.debug('replace cron:', { cron }); oldCron.time = cron.time; oldCron.action = cron.action; return oldCron; } return null; } /** * 生成schedule */ createSchedule(crons) { this.app.logger.debug('create new schedule', { crons }); for (const cron of crons) { const { id, action, time } = cron; const [name, method] = action.split('.'); const handler = this.cronHandlers[name]; if (!handler) { this.app.logger.warn('could not find handler', { cron }); continue; } if (typeof handler[method] !== 'function') { this.app.logger.warn('could not find cron job', { cron, method }); continue; } const args = cron.args || []; // @ts-ignore this.jobs[id] = node_schedule_1.default.scheduleJob(time, handler[method].bind(handler, ...args)); } } /** * 移除现有的cron * @param ids */ removeCrons(ids) { if (!lodash_1.default.isArray(ids)) ids = [ids]; this.app.logger.debug('remove old schedule', { ids }); for (const id of ids) { if (this.jobs[id]) { node_schedule_1.default.cancelJob(this.jobs[id]); delete this.jobs[id]; } else { this.app.logger.warn(`cron is not in application: ${id}`); } } } /** * 解析路由 * @param route eg: gate.gateHandler.login */ parseRoute(route) { if (!route) return null; const ts = route.split('.'); if (ts.length !== 3) return null; return { route, serverType: ts[0], handler: ts[1], method: ts[2] }; } ; } exports.default = Server; ; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZlci9zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNERBQXVCO0FBQ3ZCLDBFQUFxQztBQUNyQywyQ0FBa0M7QUFFbEMsMkRBQTJCO0FBRTNCLDhGQUE4RDtBQUM5RCw0RkFBNEQ7QUFDNUQsb0VBQXVDO0FBSXZDLHFFQUErQztBQUMvQywrQ0FBK0M7QUFFL0MsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQztBQUVuRCxNQUFxQixNQUFPLFNBQVEsY0FBSTtJQVN0QyxZQUFhLEdBQWdCLEVBQUUsSUFBb0I7UUFDakQsS0FBSyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQU5aLGlCQUFZLEdBQTRELEVBQUUsQ0FBQztRQUMzRSxVQUFLLEdBQVksRUFBRSxDQUFDO1FBQ3BCLGdCQUFXLEdBQWlCLEVBQUUsQ0FBQztRQUMvQixTQUFJLEdBQXVDLEVBQUUsQ0FBQztRQUluRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztRQUVsQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDO1FBQzFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLGdCQUFTLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDNUQsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsZ0JBQVMsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRU0sS0FBSztRQUNWLElBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJO1lBQUUsT0FBTztRQUU3QixJQUFJLENBQUMsY0FBYyxH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