Skip to content

Commit

Permalink
feat: egg-schedule.log && support send with args (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
atian25 authored and dead-horse committed Feb 6, 2018
1 parent 80252ef commit 2003369
Show file tree
Hide file tree
Showing 20 changed files with 193 additions and 33 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017 Alibaba Group Holding Limited and other contributors.
Copyright (c) 2017-present Alibaba Group Holding Limited and other contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,16 +178,17 @@ exports.schedule = {
**Custom schedule**

To create a custom schedule, simply extend `agent.ScheduleStrategy` and register it by `agent.schedule.use(type, clz)`.
You can schedule the task to be executed by one random worker or all workers with the built-in method `this.sendOne()` or `this.sendAll()`.
You can schedule the task to be executed by one random worker or all workers with the built-in method `this.sendOne(...args)` or `this.sendAll(...args)` which support params, it will pass to `subscribe(...args)` or `task(ctx, ...args)`.

```js
// {app_root}/agent.js
module.exports = function(agent) {
class CustomStrategy extends agent.ScheduleStrategy {
start() {
this.interval = setInterval(() => {
this.sendOne();
}, this.schedule.interval);
// such as mq / redis subscribe
agent.notify.subscribe('remote_task', data =>
this.sendOne(data);
});
}
}
agent.schedule.use('custsom', CustomStrategy);
Expand All @@ -205,7 +206,8 @@ class ClusterTask extends Subscription {
type: 'custom',
};
}
async subscribe() {
async subscribe(data) {
console.log('got custom data:', data);
await this.ctx.service.someTask.run();
}
}
Expand Down Expand Up @@ -233,6 +235,10 @@ module.exports = app => {
}
```

## Logging

See `${appInfo.root}/logs/egg-schedule.log` which provided by [config.customLogger.scheduleLogger](config/config.default.js).

## Testing

`app.runSchedule(scheduleName)` is provided by `egg-schedule` plugin only for test purpose.
Expand Down
3 changes: 3 additions & 0 deletions agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const WorkerStrategy = require('./lib/strategy/worker');
const AllStrategy = require('./lib/strategy/all');

module.exports = agent => {
// don't redirect scheduleLogger
agent.loggers.scheduleLogger.unredirect('error');

// register built-in strategy
agent.schedule.use('worker', WorkerStrategy);
agent.schedule.use('all', AllStrategy);
Expand Down
11 changes: 8 additions & 3 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const qs = require('querystring');
const path = require('path');

module.exports = app => {
// don't redirect scheduleLogger
app.loggers.scheduleLogger.unredirect('error');

const schedules = loadSchedule(app);

// for test purpose
Expand Down Expand Up @@ -61,17 +64,19 @@ module.exports = app => {

const start = Date.now();
const task = schedule.task;
task(ctx)
task(ctx, ...data.args)
.then(() => true) // succeed
.catch(err => {
err.message = `[egg-schedule] ${key} excute error. ${err.message}`;
err.message = `[egg-schedule] ${key} execute error. ${err.message}`;
app.logger.error(err);
app.loggers.scheduleLogger.error(err);
return false; // failed
})
.then(success => {
const rt = Date.now() - start;
const status = success ? 'succeed' : 'failed';
ctx.coreLogger.info(`[egg-schedule] ${key} excute ${status}, used ${rt}ms`);
ctx.coreLogger.info(`[egg-schedule] ${key} execute ${status}, used ${rt}ms`);
app.loggers.scheduleLogger.info(`[egg-schedule] ${key} execute ${status}, used ${rt}ms`);
});
});
};
16 changes: 16 additions & 0 deletions config/config.default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const path = require('path');

module.exports = appInfo => {
const config = {};

config.customLogger = {
scheduleLogger: {
consoleLevel: 'NONE',
file: path.join(appInfo.root, 'logs', appInfo.name, 'egg-schedule.log'),
},
};

return config;
};
4 changes: 2 additions & 2 deletions lib/load_schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ function getScheduleLoader(app) {

let task;
if (is.class(schedule)) {
task = ctx => {
task = (ctx, data) => {
const s = new schedule(ctx);
s.subscribe = app.toAsyncFunction(s.subscribe);
return s.subscribe();
return s.subscribe(data);
};
} else {
task = app.toAsyncFunction(schedule.task);
Expand Down
8 changes: 4 additions & 4 deletions lib/strategy/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ module.exports = class BaseStrategy {

start() {}

sendOne() {
sendOne(...args) {
/* istanbul ignore next */
if (this.agent.schedule.closed) {
this.agent.coreLogger.warn(`[egg-schedule] message ${this.key} did not sent`);
return;
}
this.agent.coreLogger.info(`[egg-schedule] send message to random worker: ${this.key}`);
this.agent.messenger.sendRandom('egg-schedule', { key: this.key });
this.agent.messenger.sendRandom('egg-schedule', { key: this.key, args });
}

sendAll() {
sendAll(...args) {
/* istanbul ignore next */
if (this.agent.schedule.closed) {
this.agent.coreLogger.warn(`[egg-schedule] message ${this.key} did not sent`);
return;
}
this.agent.coreLogger.info(`[egg-schedule] send message to all worker: ${this.key}`);
this.agent.messenger.send('egg-schedule', { key: this.key });
this.agent.messenger.send('egg-schedule', { key: this.key, args });
}
};
17 changes: 15 additions & 2 deletions lib/timer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ const parser = require('cron-parser');
const ms = require('humanize-ms');
const safetimers = require('safe-timers');
const assert = require('assert');
const utility = require('utility');

class Timer {
constructor(agent) {
this.agent = agent;
this.logger = agent.loggers.scheduleLogger;
this.interval = new Map();
this.timer = new Map();
}
Expand All @@ -22,6 +24,12 @@ class Timer {
const { interval, cron, cronOptions, immediate } = schedule;
assert(interval || cron || immediate, '[egg-schedule] schedule.interval or schedule.cron or schedule.immediate must be present');

const originListener = listener;
listener = (...args) => {
this.logger.info(`[egg-schedule] ${key} triggered.`);
return originListener(...args);
};

if (interval) {
const tid = this.safeInterval(listener, ms(interval));
this.interval.set(key, tid);
Expand Down Expand Up @@ -60,14 +68,19 @@ class Timer {

startCron(key, interval, listener) {
const now = Date.now();
let nextInterval;
let nextTick;
try {
do {
nextTick = interval.next().getTime();
nextInterval = interval.next();
nextTick = nextInterval.getTime();
} while (now >= nextTick);
this.logger.info(`[egg-schedule] ${key} next time will execute at ${utility.logDate(nextInterval.toDate())}`);
} catch (err) {
// when reach endDate
this.agent.coreLogger.warn(`[egg-schedule] ${key} reach endDate, will stop.`);
const msg = `[egg-schedule] ${key} reach endDate, will stop.`;
this.logger.warn(msg);
this.agent.coreLogger.warn(msg);
return;
}

Expand Down
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"files": [
"app",
"lib",
"config",
"agent.js",
"app.js"
],
Expand All @@ -23,19 +24,20 @@
"cron"
],
"dependencies": {
"cron-parser": "^2.4.3",
"cron-parser": "^2.4.4",
"humanize-ms": "^1.2.1",
"is-type-of": "^1.2.0",
"safe-timers": "^1.1.0"
"safe-timers": "^1.1.0",
"utility": "^1.13.1"
},
"devDependencies": {
"autod": "^3.0.1",
"egg": "next",
"egg-bin": "^4.3.5",
"egg": "^2.3.0",
"egg-bin": "^4.3.7",
"egg-ci": "^1.8.0",
"egg-mock": "^3.13.1",
"eslint": "^4.11.0",
"eslint-config-egg": "^5.1.1"
"egg-mock": "^3.14.0",
"eslint": "^4.16.0",
"eslint-config-egg": "^6.0.0"
},
"engines": {
"node": ">=8.0.0"
Expand Down
21 changes: 21 additions & 0 deletions test/fixtures/customTypeParams/agent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

module.exports = function(agent) {
class ClusterStrategy extends agent.ScheduleStrategy {
start() {
this.interval = setInterval(() => {
this.sendOne({ foo: 'worker' });
}, this.schedule.interval);
}
}
agent.schedule.use('cluster', ClusterStrategy);

class ClusterAllStrategy extends agent.ScheduleStrategy {
start() {
this.interval = setInterval(() => {
this.sendAll({ foo: 'all' });
}, this.schedule.interval);
}
}
agent.schedule.use('cluster-all', ClusterAllStrategy);
};
18 changes: 18 additions & 0 deletions test/fixtures/customTypeParams/app/schedule/cluster-all-clz.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

const Subscription = require('egg').Subscription;

class Interval extends Subscription {
static get schedule() {
return {
type: 'cluster-all',
interval: 4000,
};
}

* subscribe(data) {
this.ctx.logger.info('cluster_all_log_clz', data);
}
}

module.exports = Interval;
10 changes: 10 additions & 0 deletions test/fixtures/customTypeParams/app/schedule/cluster-all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

exports.schedule = {
type: 'cluster-all',
interval: 4000,
};

exports.task = async function (ctx, data) {
ctx.logger.info('cluster_all_log', data);
};
18 changes: 18 additions & 0 deletions test/fixtures/customTypeParams/app/schedule/cluster-clz.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

const Subscription = require('egg').Subscription;

class Interval extends Subscription {
static get schedule() {
return {
type: 'cluster',
interval: 4000,
};
}

* subscribe(data) {
this.ctx.logger.info('cluster_log_clz', data);
}
}

module.exports = Interval;
10 changes: 10 additions & 0 deletions test/fixtures/customTypeParams/app/schedule/cluster.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

exports.schedule = {
type: 'cluster',
interval: 4000,
};

exports.task = async function (ctx, data) {
ctx.logger.info('cluster_log', data);
};
3 changes: 3 additions & 0 deletions test/fixtures/customTypeParams/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "customTypeParams"
}
3 changes: 0 additions & 3 deletions test/fixtures/excuteError/package.json

This file was deleted.

3 changes: 3 additions & 0 deletions test/fixtures/executeError/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "executeError"
}
Loading

0 comments on commit 2003369

Please sign in to comment.