-
Notifications
You must be signed in to change notification settings - Fork 576
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
376 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const wrapped = require('egg-schedule/agent'); | ||
|
||
module.exports = (agent) => { | ||
if (!agent.loggers.scheduleLogger) { | ||
agent.loggers.scheduleLogger = { | ||
unredirect: () => {}, | ||
warn: console.warn, | ||
}; | ||
} | ||
wrapped(agent); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
'use strict'; | ||
|
||
import * as qs from 'querystring'; | ||
import * as path from 'path'; | ||
import loadSchedule from './lib/load_schedule'; | ||
|
||
module.exports = (app) => { | ||
// don't redirect scheduleLogger | ||
// app.loggers.scheduleLogger.unredirect('error'); | ||
|
||
const schedules = loadSchedule(app); | ||
|
||
// for test purpose | ||
app.runSchedule = (schedulePath) => { | ||
if (!path.isAbsolute(schedulePath)) { | ||
schedulePath = path.join( | ||
app.config.baseDir, | ||
'app/schedule', | ||
schedulePath, | ||
); | ||
} | ||
schedulePath = require.resolve(schedulePath); | ||
let schedule; | ||
|
||
try { | ||
schedule = schedules[schedulePath]; | ||
if (!schedule) { | ||
throw new Error(`Cannot find schedule ${schedulePath}`); | ||
} | ||
} catch (err) { | ||
err.message = `[egg-schedule] ${err.message}`; | ||
return Promise.reject(err); | ||
} | ||
|
||
// run with anonymous context | ||
const ctx = app.createAnonymousContext({ | ||
method: 'SCHEDULE', | ||
url: `/__schedule?path=${schedulePath}&${qs.stringify( | ||
schedule.schedule, | ||
)}`, | ||
}); | ||
|
||
return schedule.task(ctx); | ||
}; | ||
|
||
// log schedule list | ||
for (const s in schedules) { | ||
const schedule = schedules[s]; | ||
if (!schedule.schedule.disable) | ||
app.coreLogger.info('[egg-schedule]: register schedule %s', schedule.key); | ||
} | ||
|
||
// register schedule event | ||
app.messenger.on('egg-schedule', (data) => { | ||
throw new Error('hahaha'); | ||
const id = data.id; | ||
const key = data.key; | ||
const schedule = schedules[key]; | ||
const logger = app.loggers.scheduleLogger; | ||
logger.info(`[${id}] ${key} task received by app`); | ||
|
||
if (!schedule) { | ||
logger.warn(`[${id}] ${key} unknown task`); | ||
return; | ||
} | ||
/* istanbul ignore next */ | ||
if (schedule.schedule.disable) return; | ||
|
||
// run with anonymous context | ||
const ctx = app.createAnonymousContext({ | ||
method: 'SCHEDULE', | ||
url: `/__schedule?path=${key}&${qs.stringify(schedule.schedule)}`, | ||
}); | ||
|
||
const start = Date.now(); | ||
const task = schedule.task; | ||
logger.info(`[${id}] ${key} executing by app`); | ||
console.log('hi ctx', ctx); | ||
console.log('hi ctx.logger', ctx.logger); | ||
// execute | ||
task(ctx, ...data.args) | ||
.then(() => true) // succeed | ||
.catch((err) => { | ||
logger.error(`[${id}] ${key} execute error.`, err); | ||
err.message = `[egg-schedule] ${key} execute error. ${err.message}`; | ||
app.logger.error(err); | ||
return false; // failed | ||
}) | ||
.then((success) => { | ||
const rt = Date.now() - start; | ||
const status = success ? 'succeed' : 'failed'; | ||
ctx.coreLogger.info( | ||
`[egg-schedule] ${key} execute ${status}, used ${rt}ms`, | ||
); | ||
logger[success ? 'info' : 'error']( | ||
`[${id}] ${key} execute ${status}, used ${rt}ms`, | ||
); | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('egg-schedule/app/extend/agent'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import 'reflect-metadata'; | ||
import * as assert from 'assert'; | ||
import * as is from 'is-type-of'; | ||
import { SCHEDULE_CLASS } from './metaKeys'; | ||
|
||
interface SchedueOpts { | ||
interval: number; | ||
type: string; | ||
env?: string[]; | ||
} | ||
|
||
export default (app) => { | ||
const dirs = app.loader | ||
.getLoadUnits() | ||
.map((unit) => require('path').join(unit.path, 'lib/schedule')); | ||
const Loader = getScheduleLoader(app); | ||
const schedules = (app.schedules = {}); | ||
new Loader({ | ||
directory: dirs, | ||
target: schedules, | ||
inject: app, | ||
}).load(); | ||
return schedules; | ||
}; | ||
|
||
function getScheduleLoader(app) { | ||
return class ScheduleLoader extends app.loader.FileLoader { | ||
constructor(...args) { | ||
super(...args); | ||
} | ||
|
||
load() { | ||
const target = this.options.target; | ||
const items = this.parse(); | ||
for (const item of items) { | ||
const schedule = item.exports; | ||
const fullpath = item.fullpath; | ||
|
||
assert(is.class(schedule), `schedule(${fullpath}: should be class`); | ||
const opts: SchedueOpts | string = Reflect.getMetadata( | ||
SCHEDULE_CLASS, | ||
schedule, | ||
); | ||
assert(opts, `schedule(${fullpath}): must use @schedule to setup.`); | ||
|
||
const task = (ctx, data) => { | ||
const ins = ctx.getAsync(schedule); | ||
ins.exec = app.toAsyncFunction(ins.exec); | ||
return ins.exec(data); | ||
}; | ||
|
||
const env = app.config.env; | ||
const envList = (opts as SchedueOpts).env; | ||
if (is.array(envList) && !envList.includes(env)) { | ||
app.coreLogger.info( | ||
`[egg-schedule]: ignore schedule ${fullpath} due to \`schedule.env\` not match`, | ||
); | ||
continue; | ||
} | ||
|
||
target[fullpath] = { | ||
schedule: opts, | ||
task, | ||
key: fullpath, | ||
}; | ||
} | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/** | ||
* for @schedule | ||
*/ | ||
export const SCHEDULE_CLASS = 'midway:schedule_class'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "midway-schedule", | ||
"version": "0.1.1", | ||
"description": "", | ||
"main": "index.js", | ||
"directories": { | ||
"lib": "lib" | ||
}, | ||
"eggPlugin": { | ||
"name": "schedule" | ||
}, | ||
"scripts": { | ||
"lint": "../../node_modules/.bin/tslint --format prose -c ../../tslint.json src/**/*.ts test/**/*.ts", | ||
"test": "npm run lint && midway-bin clean && NODE_ENV=test midway-bin test --ts" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"egg-schedule": "^3.4.0", | ||
"reflect-metadata": "^0.1.12" | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
packages/midway-schedule/test/fixtures/worker/config/plugin.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
'use strict'; | ||
|
||
exports.logrotator = true; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"name": "worker" | ||
} |
21 changes: 21 additions & 0 deletions
21
packages/midway-schedule/test/fixtures/worker/src/lib/schedule/interval.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
'use strict'; | ||
|
||
import { schedule } from '../../../../../../../midway/dist'; | ||
// import * as fs from 'fs'; | ||
|
||
@schedule({ | ||
type: 'worker', | ||
interval: 200, | ||
}) | ||
export default class IntervalCron { | ||
async exec(ctx) { | ||
throw new Error('hahaha'); | ||
// console.log(1234); | ||
// ctx.logger.info('interval'); | ||
// ctx.app.coreLogger.info('hello world'); | ||
// fs.writeFileSync( | ||
// require('path').join(__dirname, '../../logs/worker/hello.log'), | ||
// 'hello world', | ||
// ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
'use strict'; | ||
|
||
const { mm } = require('../../midway-mock/dist'); | ||
const path = require('path'); | ||
const fs = require('fs'); | ||
const assert = require('assert'); | ||
|
||
describe('test/schedule.test.js', () => { | ||
let app; | ||
// afterEach(() => app.close()); | ||
|
||
describe('schedule type worker', () => { | ||
it('should support interval and cron', async () => { | ||
app = mm.app({ | ||
baseDir: 'worker', | ||
framework: path.join(__dirname, '../../midway'), | ||
}); | ||
// app.debug(); | ||
await app.ready(); | ||
console.log(app.schedules); | ||
}); | ||
}); | ||
}); | ||
|
||
function sleep(time) { | ||
return new Promise((resolve) => { | ||
setTimeout(resolve, time); | ||
}); | ||
} | ||
|
||
function getCoreLogContent(name) { | ||
const logPath = path.join( | ||
__dirname, | ||
'fixtures', | ||
name, | ||
'logs', | ||
name, | ||
'egg-web.log', | ||
); | ||
return fs.readFileSync(logPath, 'utf8'); | ||
} | ||
|
||
function getLogContent(name) { | ||
const logPath = path.join( | ||
__dirname, | ||
'fixtures', | ||
name, | ||
'dist', | ||
'logs', | ||
name, | ||
`midway-web.log`, | ||
); | ||
return fs.readFileSync(logPath, 'utf8'); | ||
} | ||
|
||
function getErrorLogContent(name) { | ||
const logPath = path.join( | ||
__dirname, | ||
'fixtures', | ||
name, | ||
'logs', | ||
name, | ||
'common-error.log', | ||
); | ||
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 getScheduleLogContent(name) { | ||
const logPath = path.join( | ||
__dirname, | ||
'fixtures', | ||
name, | ||
'logs', | ||
name, | ||
'egg-schedule.log', | ||
); | ||
return fs.readFileSync(logPath, 'utf8'); | ||
} | ||
|
||
function contains(content, match) { | ||
return content.split('\n').filter((line) => line.indexOf(match) >= 0).length; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "ES2017", | ||
"module": "commonjs", | ||
"moduleResolution": "node", | ||
"experimentalDecorators": true, | ||
"noImplicitThis": true, | ||
"noUnusedLocals": true, | ||
"stripInternal": true, | ||
"pretty": true, | ||
"declaration": true, | ||
"outDir": "dist", | ||
"lib": ["es2017", "dom"], | ||
"sourceMap": true | ||
}, | ||
"exclude": [ | ||
"dist", | ||
"node_modules", | ||
"test" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
schedule: { | ||
enable: true, | ||
package: 'midway-schedule', | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.