diff --git a/agent.js b/agent.js index b2afcc6..e9a2035 100644 --- a/agent.js +++ b/agent.js @@ -4,7 +4,6 @@ const loadSchedule = require('./lib/load_schedule'); const parser = require('cron-parser'); const ms = require('humanize-ms'); const safetimers = require('safe-timers'); -const MAX_SAFE_TIME = Math.pow(2, 31) - 1; const SCHEDULE_HANDLER = Symbol.for('egg#scheduleHandler'); module.exports = agent => { @@ -106,7 +105,7 @@ function startCron(interval, listener) { } function safeTimeout(fn, delay, ...args) { - if (delay >= MAX_SAFE_TIME) { + if (delay < safetimers.maxInterval) { setTimeout(fn, delay, ...args); } else { safetimers.setTimeout(fn, delay, ...args); @@ -114,7 +113,7 @@ function safeTimeout(fn, delay, ...args) { } function safeInterval(fn, delay, ...args) { - if (delay >= MAX_SAFE_TIME) { + if (delay < safetimers.maxInterval) { setInterval(fn, delay, ...args); } else { safetimers.setInterval(fn, delay, ...args); diff --git a/test/fixtures/safe-timers/agent.js b/test/fixtures/safe-timers/agent.js new file mode 100644 index 0000000..032bcd8 --- /dev/null +++ b/test/fixtures/safe-timers/agent.js @@ -0,0 +1,15 @@ +'use strict'; + +const safetimers = require('safe-timers'); + +module.exports = agent => { + safetimers.maxInterval = 4000; + + const proto = safetimers.Timeout.prototype; + const originFn = proto.reschedule; + + proto.reschedule = function(...args) { + agent.logger.info('reschedule', ...args); + originFn.call(this, ...args); + }; +} \ No newline at end of file diff --git a/test/fixtures/safe-timers/app/schedule/interval.js b/test/fixtures/safe-timers/app/schedule/interval.js new file mode 100644 index 0000000..aae8c22 --- /dev/null +++ b/test/fixtures/safe-timers/app/schedule/interval.js @@ -0,0 +1,10 @@ +'use strict'; + +exports.schedule = { + type: 'worker', + interval: 4321, +}; + +exports.task = function* (ctx) { + ctx.logger.info('interval'); +}; diff --git a/test/fixtures/safe-timers/app/schedule/sub/cron.js b/test/fixtures/safe-timers/app/schedule/sub/cron.js new file mode 100644 index 0000000..f427b45 --- /dev/null +++ b/test/fixtures/safe-timers/app/schedule/sub/cron.js @@ -0,0 +1,10 @@ +'use strict'; + +exports.schedule = { + type: 'worker', + cron: '*/5 * * * * *', +}; + +exports.task = function* (ctx) { + ctx.logger.info('cron'); +}; diff --git a/test/fixtures/safe-timers/config/plugin.js b/test/fixtures/safe-timers/config/plugin.js new file mode 100644 index 0000000..a682a4c --- /dev/null +++ b/test/fixtures/safe-timers/config/plugin.js @@ -0,0 +1,3 @@ +'use strict'; + +exports.logrotator = false; diff --git a/test/fixtures/safe-timers/package.json b/test/fixtures/safe-timers/package.json new file mode 100644 index 0000000..f08c74a --- /dev/null +++ b/test/fixtures/safe-timers/package.json @@ -0,0 +1,3 @@ +{ + "name": "safe-timers" +} diff --git a/test/schedule.test.js b/test/schedule.test.js index b372274..966957d 100644 --- a/test/schedule.test.js +++ b/test/schedule.test.js @@ -11,7 +11,7 @@ describe('test/schedule.test.js', () => { describe('schedule type worker', () => { it('should support interval and cron', function* () { - app = mm.cluster({ baseDir: 'worker', workers: 2 }); + app = mm.cluster({ baseDir: 'worker', workers: 2, cache: false }); yield app.ready(); yield sleep(5000); const log = getLogContent('worker'); @@ -54,8 +54,8 @@ describe('test/schedule.test.js', () => { yield sleep(5000); const log = getLogContent('immediate'); console.log(log); - assert(contains(log, 'immediate-interval') === 2); - assert(contains(log, 'immediate-cron') === 2); + assert(contains(log, 'immediate-interval') >= 2); + assert(contains(log, 'immediate-cron') >= 2); }); }); @@ -203,14 +203,31 @@ describe('test/schedule.test.js', () => { }); }); - describe('export schedules', () => { it('should export app.schedules', function* () { - app = mm.app({ baseDir: 'worker' }); + app = mm.app({ baseDir: 'worker', cache: false }); yield app.ready(); assert(app.schedules); }); }); + + describe('safe-timers', () => { + it('should support interval and cron', function* () { + app = mm.cluster({ baseDir: 'safe-timers', workers: 2, cache: false }); + yield app.ready(); + yield sleep(5000); + + const log = getLogContent('safe-timers'); + console.log(log); + assert(contains(log, 'interval') === 1); + assert(contains(log, 'cron') === 1); + + const agentLog = getAgentLogContent('safe-timers'); + console.log(agentLog); + assert(contains(agentLog, 'reschedule 4321') === 2); + assert(contains(agentLog, 'reschedule') >= 4); + }); + }); }); function sleep(time) { @@ -229,6 +246,11 @@ function getErrorLogContent(name) { return fs.readFileSync(logPath, 'utf8'); } +function getAgentLogContent(name) { + const logPath = path.join(__dirname, 'fixtures', name, 'logs', name, 'egg-agent.log'); + return fs.readFileSync(logPath, 'utf8'); +} + function contains(content, match) { return content.split('\n').filter(line => line.indexOf(match) >= 0).length; }