diff --git a/agent.js b/agent.js index d89f66d..6ec7805 100644 --- a/agent.js +++ b/agent.js @@ -3,42 +3,41 @@ const SCHEDULE_HANDLER = Symbol.for('egg#scheduleHandler'); const WorkerStrategy = require('./lib/strategy/worker'); const AllStrategy = require('./lib/strategy/all'); -const BaseStrategy = require('./lib/strategy/base'); -const Schedule = require('./lib/schedule'); module.exports = agent => { - const handlers = agent[SCHEDULE_HANDLER] = {}; - agent.schedule = new Schedule(agent); - agent.ScheduleStrategy = BaseStrategy; + // register built-in strategy + agent.schedule.use('worker', WorkerStrategy); + agent.schedule.use('all', AllStrategy); - agent.beforeClose(() => { - return agent.schedule.close(); + // TODO: compatible, will remove at next major + const handlers = {}; + Object.defineProperty(agent, SCHEDULE_HANDLER, { + get() { + agent.deprecate('should use `agent.schedule.use()` instead of `agent[Symbol.for(\'egg#scheduleHandler\')]` to register handler.'); + return handlers; + }, }); agent.messenger.once('egg-ready', () => { - agent.schedule.use('worker', WorkerStrategy); - agent.schedule.use('all', AllStrategy); - //TODO: compatible, will remove at next major const keys = Object.keys(handlers); - if (keys.length) agent.deprecate('should use `schedule.use()` instead of `agent[Symbol.for(\'egg#scheduleHandler\')]` to register handler.'); for (const type of keys) { agent.schedule.use(type, handler2Class(type, handlers[type])); } + // start schedule agent.schedule.start(); }); function handler2Class(type, fn) { - return class CustomStrategy extends BaseStrategy { - constructor(...args) { - super(...args); - this.type = type; - } + return class CustomStrategy extends agent.ScheduleStrategy { start() { fn(this.schedule, { one: this.sendOne.bind(this), all: this.sendAll.bind(this), }); } + close() { + this.agent.logger.warn(`schedule type [${type}] stop is not implemented yet`); + } }; } }; diff --git a/app.js b/app.js index 5468a91..d9c1cd6 100644 --- a/app.js +++ b/app.js @@ -51,17 +51,17 @@ module.exports = app => { const start = Date.now(); task(ctx) - .then(() => true) // succeed - .catch(err => { - err.message = `[egg-schedule] ${key} excute error. ${err.message}`; - app.logger.error(err); - return false; // failed - }) - .then(success => { - const rt = Date.now() - start; - const status = success ? 'succeed' : 'failed'; - app.coreLogger.info(`[egg-schedule] ${key} excute ${status}, used ${rt}ms`); - }); + .then(() => true) // succeed + .catch(err => { + err.message = `[egg-schedule] ${key} excute error. ${err.message}`; + app.logger.error(err); + return false; // failed + }) + .then(success => { + const rt = Date.now() - start; + const status = success ? 'succeed' : 'failed'; + app.coreLogger.info(`[egg-schedule] ${key} excute ${status}, used ${rt}ms`); + }); }); } }; diff --git a/app/extend/agent.js b/app/extend/agent.js new file mode 100644 index 0000000..9b3f956 --- /dev/null +++ b/app/extend/agent.js @@ -0,0 +1,25 @@ +'use strict'; + +const Strategy = require('../../lib/strategy/base'); +const Schedule = require('../../lib/schedule'); +const SCHEDULE = Symbol('agent#schedule'); + +module.exports = { + /** + * @member agent#ScheduleStrategy + */ + ScheduleStrategy: Strategy, + + /** + * @member agent#schedule + */ + get schedule() { + if (!this[SCHEDULE]) { + this[SCHEDULE] = new Schedule(this); + this.beforeClose(() => { + return this[SCHEDULE].close(); + }); + } + return this[SCHEDULE]; + }, +}; diff --git a/lib/schedule.js b/lib/schedule.js index 53821a3..0e4509a 100644 --- a/lib/schedule.js +++ b/lib/schedule.js @@ -10,11 +10,11 @@ module.exports = class Schedule { this.agent = agent; this[STRATEGY] = new Map(); this[HANDLER] = new Map(); + this.closed = false; } use(type, clz) { - assert(typeof clz.prototype.start === 'function', `schedule type [${type}] should implement \`start\` method`) - clz.prototype.type = type; + assert(typeof clz.prototype.start === 'function', `schedule type [${type}] should implement \`start\` method`); this[STRATEGY].set(type, clz); } @@ -42,9 +42,9 @@ module.exports = class Schedule { close() { this.closed = true; - for (const handler of this[HANDLER].values()) { + for (const [ key, handler ] of this[HANDLER].entries()) { + this.agent.coreLogger.info(`[egg-schedule] close tasks: ${key}`); handler.close(); } - this.agent.coreLogger.info('[egg-schedule] close tasks.'); } }; diff --git a/lib/strategy/base.js b/lib/strategy/base.js index 370c5f0..4960f39 100644 --- a/lib/strategy/base.js +++ b/lib/strategy/base.js @@ -26,10 +26,4 @@ module.exports = class BaseStrategy { this.agent.coreLogger.info(`[egg-schedule] send message to all worker: ${this.key}`); this.agent.messenger.send(this.key); } - - /* istanbul ignore next */ - close() { - /* istanbul ignore next */ - this.agent.logger.warn(`schedule type [${this.type}] stop is not implemented yet`); - } }; diff --git a/lib/timer.js b/lib/timer.js index db3b472..1fdd242 100644 --- a/lib/timer.js +++ b/lib/timer.js @@ -79,4 +79,4 @@ class Timer { } } -module.exports = Timer; \ No newline at end of file +module.exports = Timer; diff --git a/test/schedule.test.js b/test/schedule.test.js index 41ec57d..b475087 100644 --- a/test/schedule.test.js +++ b/test/schedule.test.js @@ -90,7 +90,6 @@ describe('test/schedule.test.js', () => { yield app.ready(); yield sleep(5000); const log = getLogContent('customType'); - const errorLog = getErrorLogContent('customType'); // console.log(log); assert(contains(log, 'custom_log') === 1); assert(contains(log, 'cluster_log') === 1);