Skip to content

Commit

Permalink
📦 NEW: [BREAKING] Support localStorage to run task (#58)
Browse files Browse the repository at this point in the history
- Drop Node.js <= 14 support
  • Loading branch information
fengmk2 authored Dec 11, 2022
1 parent 7672269 commit 66e7aeb
Show file tree
Hide file tree
Showing 17 changed files with 160 additions and 70 deletions.
21 changes: 0 additions & 21 deletions .autod.conf.js

This file was deleted.

10 changes: 5 additions & 5 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,25 @@ jobs:
strategy:
fail-fast: false
matrix:
node-version: [10, 12]
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [14, 16, 18]
os: [ubuntu-latest]

steps:
- name: Checkout Git Source
uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Install Dependencies
run: npm i -g npminstall@5 && npminstall
run: npm i

- name: Continuous Integration
run: npm run ci

- name: Code Coverage
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
7 changes: 1 addition & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
# egg-schedule

[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Node.js CI](https://github.com/eggjs/egg-schedule/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/egg-schedule/actions/workflows/nodejs.yml)
[![Test coverage][codecov-image]][codecov-url]
[![David deps][david-image]][david-url]
[![Known Vulnerabilities][snyk-image]][snyk-url]
[![npm download][download-image]][download-url]

[npm-image]: https://img.shields.io/npm/v/egg-schedule.svg?style=flat-square
[npm-url]: https://npmjs.org/package/egg-schedule
[travis-image]: https://img.shields.io/travis/eggjs/egg-schedule.svg?style=flat-square
[travis-url]: https://travis-ci.org/eggjs/egg-schedule
[codecov-image]: https://codecov.io/github/eggjs/egg-schedule/coverage.svg?branch=master
[codecov-url]: https://codecov.io/github/eggjs/egg-schedule?branch=master
[david-image]: https://img.shields.io/david/eggjs/egg-schedule.svg?style=flat-square
[david-url]: https://david-dm.org/eggjs/egg-schedule
[snyk-image]: https://snyk.io/test/npm/egg-schedule/badge.svg?style=flat-square
[snyk-url]: https://snyk.io/test/npm/egg-schedule
[download-image]: https://img.shields.io/npm/dm/egg-schedule.svg?style=flat-square
Expand Down
46 changes: 25 additions & 21 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,29 @@ module.exports = app => {
const start = Date.now();

// execute
return schedule.task(ctx, ...info.args)
.catch(err => {
return is.error(err) ? err : new Error(err);
})
.then(err => {
const success = !is.error(err);
const rt = Date.now() - start;

const msg = `[Job#${id}] ${key} execute ${success ? 'succeed' : 'failed'}, used ${rt}ms.`;
logger[success ? 'info' : 'error'](msg, success ? '' : err);

Object.assign(info, {
success,
workerId: process.pid,
rt,
message: err && err.message,
return app.ctxStorage.run(ctx, () => {
return schedule.task(ctx, ...info.args)
.catch(err => {
return is.error(err) ? err : new Error(err);
})
.then(err => {
const success = !is.error(err);
const rt = Date.now() - start;

const msg = `[Job#${id}] ${key} execute ${success ? 'succeed' : 'failed'}, used ${rt}ms.`;
logger[success ? 'info' : 'error'](msg, success ? '' : err);

Object.assign(info, {
success,
workerId: process.pid,
rt,
message: err && err.message,
});

// notify agent job finish
app.messenger.sendToAgent('egg-schedule', info);
});

// notify agent job finish
app.messenger.sendToAgent('egg-schedule', info);
});
});
});

// for test purpose
Expand Down Expand Up @@ -102,6 +104,8 @@ module.exports = app => {
url: `/__schedule?path=${schedulePath}&${qs.stringify(schedule.schedule)}`,
});

return schedule.task(ctx, ...args);
return app.ctxStorage.run(ctx, () => {
return schedule.task(ctx, ...args);
});
};
};
1 change: 1 addition & 0 deletions app/extend/application.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const ScheduleWorker = require('../../lib/schedule_worker');

const SCHEDULE_WORKER = Symbol('application#scheduleWorker');

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion lib/strategy/timer.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ module.exports = class TimerStrategy extends Strategy {
/**
* calculate next tick
*
* @return {Number} time interval, if out of range then return `undefined`
* @return {Number|undefined} time interval, if out of range then return `undefined`
*/
getNextTick() {
// interval-style
Expand Down
25 changes: 12 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,27 @@
"utility": "^1.16.3"
},
"devDependencies": {
"autod": "^3.1.0",
"egg": "^2.27.0",
"egg-bin": "^4.15.0",
"egg-ci": "^1.15.0",
"egg-mock": "^4.0.1",
"eslint": "^7.8.0",
"eslint-config-egg": "^8.1.1",
"mz-modules": "^2.1.0"
"egg": "^3.7.0",
"egg-bin": "^5.5.0",
"egg-ci": "^2.2.0",
"egg-mock": "^5.3.0",
"egg-tracer": "^1.1.0",
"eslint": "^8.29.0",
"eslint-config-egg": "^12.1.0"
},
"engines": {
"node": ">=8.0.0"
"node": ">=14.17.0"
},
"scripts": {
"lint": "eslint .",
"test": "npm run lint -- --fix && egg-bin pkgfiles && npm run test-local",
"test": "npm run lint -- --fix && npm run test-local",
"test-local": "egg-bin test",
"cov": "egg-bin cov",
"ci": "npm run lint && egg-bin pkgfiles --check && npm run cov",
"autod": "autod"
"ci": "npm run lint && npm run cov"
},
"ci": {
"version": "10, 12",
"version": "14, 16, 18",
"os": "linux",
"license": true
},
"author": "dead_horse",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const Subscription = require('egg').Subscription;

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

* subscribe() {
this.app.logger.info('interval');
}
}

module.exports = Interval;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const Subscription = require('egg').Subscription;

class Interval extends Subscription {
static get schedule() {
return {
type: 'worker',
cron: '*/5 * * * * *',
};
}

* subscribe() {
this.app.logger.info('cron');
}
}

module.exports = Interval;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.logger = {
enableFastContextLogger: true,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
exports.logrotator = true;
exports.tracer = {
enable: true,
package: 'egg-tracer',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "subscription-enableFastContextLogger"
}
8 changes: 8 additions & 0 deletions test/fixtures/worker2/app/schedule/interval.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports.schedule = {
type: 'worker',
interval: '4s',
};

exports.task = async ctx => {
ctx.app.logger.info('interval');
};
8 changes: 8 additions & 0 deletions test/fixtures/worker2/app/schedule/sub/foobar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
exports.schedule = {
type: 'worker',
cron: '*/5 * * * * *',
};

exports.task = async (ctx, ...args) => {
ctx.app.logger.info('foobar', ...args);
};
1 change: 1 addition & 0 deletions test/fixtures/worker2/config/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.logrotator = true;
3 changes: 3 additions & 0 deletions test/fixtures/worker2/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "worker2"
}
55 changes: 52 additions & 3 deletions test/schedule.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
'use strict';

const mm = require('egg-mock');
const path = require('path');
const fs = require('fs');
const assert = require('assert');
const { sleep } = require('mz-modules');
const is = require('is-type-of');

function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}

describe('test/schedule.test.js', () => {
let app;
afterEach(() => app.close());
Expand All @@ -29,6 +32,24 @@ describe('test/schedule.test.js', () => {
assert(contains(scheduleLog, 'interval.js execute succeed') === 1);
});

it('should support ctxStorage', async () => {
app = mm.cluster({ baseDir: 'worker2', workers: 2, cache: false });
// app.debug();
await app.ready();
await sleep(5000);
const log = getLogContent('worker2');
// console.log(log);
assert(contains(log, 'interval') === 1);
assert(contains(log, 'foobar') === 1);

const scheduleLog = getScheduleLogContent('worker2');
// console.log(scheduleLog);
assert(contains(scheduleLog, 'foobar.js executing by app') === 1);
assert(contains(scheduleLog, 'foobar.js execute succeed') === 1);
assert(contains(scheduleLog, 'interval.js executing by app') === 1);
assert(contains(scheduleLog, 'interval.js execute succeed') === 1);
});

it('should support cronOptions', async () => {
app = mm.cluster({ baseDir: 'cronOptions', workers: 2 });
// app.debug();
Expand Down Expand Up @@ -341,6 +362,21 @@ describe('test/schedule.test.js', () => {
assert(contains(log, 'cron test') === 1);
});

it('should run schedule support ctxStorage', async () => {
app = mm.app({ baseDir: 'worker2', cache: false });
await app.ready();
app.mockContext({
tracer: {
traceId: 'mock-trace-123',
},
});
await app.runSchedule('sub/foobar', 'use app.logger.info should work');
await sleep(1000);
const log = getLogContent('worker2');
// console.log(log);
assert.match(log, / \[-\/127.0.0.1\/mock-trace-123\/\d+ms GET \/] foobar use app.logger.info should work/);
});

it('should run schedule with symlink js file success', async () => {
const realPath = path.join(__dirname, 'fixtures/symlink/realFile.js');
const targetPath = path.join(__dirname, 'fixtures/symlink/runDir/app/schedule/realFile.js');
Expand Down Expand Up @@ -450,6 +486,19 @@ describe('test/schedule.test.js', () => {
assert(contains(log, 'interval') === 1);
assert(contains(log, 'cron') === 1);
});

it('should support interval and cron when config.logger.enableFastContextLogger = true', async () => {
app = mm.cluster({ baseDir: 'subscription-enableFastContextLogger', workers: 2, cache: false });
// app.debug();
await app.ready();
await sleep(5000);
const log = getLogContent('subscription-enableFastContextLogger');
// console.log(log);
assert(contains(log, 'interval') === 1);
assert(contains(log, 'cron') === 1);
// 2022-12-11 16:44:55,009 INFO 22958 [-/127.0.0.1/15d62420-7930-11ed-86ce-31ec9c2e0d18/3ms SCHEDULE /__schedule
assert.match(log, / INFO \w+ \[-\/127\.0\.0\.1\/\w+\-\w+\-\w+\-\w+\-\w+\/\d+ms SCHEDULE \/__schedule/);
});
});

describe('send with params', () => {
Expand Down

0 comments on commit 66e7aeb

Please sign in to comment.