Skip to content

Commit

Permalink
f
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Dec 17, 2024
1 parent 7208139 commit 798efeb
Show file tree
Hide file tree
Showing 30 changed files with 176 additions and 137 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"cron"
],
"dependencies": {
"@eggjs/utils": "^4.0.3",
"cron-parser": "^4.9.0",
"humanize-ms": "^2.0.0",
"is-type-of": "^2.1.0",
Expand All @@ -38,6 +39,7 @@
"@types/safe-timers": "^1.1.2",
"egg": "beta",
"egg-bin": "6",
"egg-logrotator": "^3.2.0",
"egg-mock": "beta",
"egg-tracer": "2",
"eslint": "8",
Expand Down
11 changes: 6 additions & 5 deletions src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ export default class Boot implements ILifecycleBoot {
// get job info from worker
this.#agent.schedule.onJobFinish(info);
});
debug('didLoad');
}

this.#agent.messenger.once('egg-ready', () => {
// start schedule after worker ready
this.#agent.schedule.start();
debug('got egg-ready event, schedule start');
});
async serverDidReady(): Promise<void> {
// start schedule after worker ready
this.#agent.schedule.start();
debug('serverDidReady, schedule start');
}
}
24 changes: 15 additions & 9 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'node:path';
import type {
Application, ILifecycleBoot, EggLogger,
} from 'egg';
import { importResolve } from '@eggjs/utils';
import { ScheduleItem, ScheduleJobInfo } from './lib/types.js';

const debug = debuglog('@eggjs/schedule/app');
Expand All @@ -16,15 +17,14 @@ export default class Boot implements ILifecycleBoot {
}

async didLoad(): Promise<void> {
debug('didLoad');
const scheduleWorker = this.#app.scheduleWorker;
await scheduleWorker.init();

// log schedule list
for (const s in scheduleWorker.scheduleItems) {
const schedule = scheduleWorker.scheduleItems[s];
if (!schedule.schedule.disable) {
this.#logger.info('[egg-schedule]: register schedule %s', schedule.key);
this.#logger.info('[@eggjs/schedule]: register schedule %s', schedule.key);
}
}

Expand Down Expand Up @@ -66,9 +66,9 @@ export default class Boot implements ILifecycleBoot {
return await schedule.task(ctx, ...info.args);
});
success = true;
} catch (err) {
} catch (err: any) {
success = false;
throw err;
e = err;
}

const rt = Date.now() - start;
Expand Down Expand Up @@ -97,28 +97,32 @@ export default class Boot implements ILifecycleBoot {
...config.schedule.directory,
];
const runSchedule = async (schedulePath: string, ...args: any[]) => {
debug('[runSchedule] start schedulePath: %o, args: %o', schedulePath, args);

// resolve real path
if (path.isAbsolute(schedulePath)) {
schedulePath = require.resolve(schedulePath);
schedulePath = importResolve(schedulePath);
} else {
for (const dir of directory) {
const trySchedulePath = path.join(dir, schedulePath);
try {
schedulePath = require.resolve(path.join(dir, schedulePath));
schedulePath = importResolve(trySchedulePath);
break;
} catch (_) {
/* istanbul ignore next */
} catch (err) {
debug('[runSchedule] importResolve %o error: %s', trySchedulePath, err);
}
}
}

debug('[runSchedule] resolve schedulePath: %o', schedulePath);
let schedule: ScheduleItem;
try {
schedule = scheduleWorker.scheduleItems[schedulePath];
if (!schedule) {
throw new Error(`Cannot find schedule ${schedulePath}`);
}
} catch (err: any) {
err.message = `[egg-schedule] ${err.message}`;
err.message = `[@eggjs/schedule] ${err.message}`;
throw err;
}

Expand All @@ -132,5 +136,7 @@ export default class Boot implements ILifecycleBoot {
});
};
Reflect.set(this.#app, 'runSchedule', runSchedule);

debug('didLoad');
}
}
8 changes: 6 additions & 2 deletions src/lib/load_schedule.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'node:path';
import assert from 'node:assert';
import { stringify } from 'node:querystring';
import { isClass, isFunction } from 'is-type-of';
import { isClass, isFunction, isGeneratorFunction } from 'is-type-of';
import type { EggApplicationCore, EggContext } from 'egg';
import type { ScheduleConfig, ScheduleTask, ScheduleItem } from './types.js';

Expand All @@ -20,20 +20,24 @@ function getScheduleLoader(app: EggApplicationCore) {

let task: ScheduleTask;
if (isClass(schedule)) {
assert(!isGeneratorFunction(schedule.prototype.subscribe),
`schedule(${fullpath}): "schedule" generator function is not support, should use async function instead`);
task = async (ctx: EggContext, ...args: any[]) => {
const instance = new schedule(ctx);
// s.subscribe = app.toAsyncFunction(s.subscribe);
return instance.subscribe(...args);
};
} else {
assert(!isGeneratorFunction(schedule.task),
`schedule(${fullpath}): "task" generator function is not support, should use async function instead`);
task = schedule.task;
// task = app.toAsyncFunction(schedule.task);
}

const env = app.config.env;
const envList = schedule.schedule.env;
if (Array.isArray(envList) && !envList.includes(env)) {
app.coreLogger.info(`[egg-schedule]: ignore schedule ${fullpath} due to \`schedule.env\` not match`);
app.coreLogger.info(`[@eggjs/schedule]: ignore schedule ${fullpath} due to \`schedule.env\` not match`);
continue;
}

Expand Down
12 changes: 11 additions & 1 deletion src/lib/schedule.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { debuglog } from 'node:util';
import type { Agent, EggLogger } from 'egg';
import { loadSchedule } from './load_schedule.js';
import type { ScheduleItem, ScheduleJobInfo } from './types.js';
import type { BaseStrategy } from './strategy/base.js';

const debug = debuglog('@eggjs/schedule/lib/schedule');

export class Schedule {
closed = false;

Expand All @@ -23,6 +26,7 @@ export class Schedule {
*/
use(type: string, clz: typeof BaseStrategy) {
this.#strategyClassMap.set(type, clz);
debug('use type: %o', type);
}

/**
Expand All @@ -38,7 +42,9 @@ export class Schedule {
registerSchedule(scheduleItem: ScheduleItem) {
const { key, schedule } = scheduleItem;
const type = schedule.type;
if (schedule.disable) return;
if (schedule.disable) {
return;
}

// find Strategy by type
const Strategy = this.#strategyClassMap.get(type!);
Expand All @@ -51,9 +57,11 @@ export class Schedule {
// Initialize strategy and register
const instance = new Strategy(schedule, this.#agent, key);
this.#strategyInstanceMap.set(key, instance);
debug('registerSchedule type: %o, config: %o, key: %o', type, schedule, key);
}

unregisterSchedule(key: string) {
debug('unregisterSchedule key: %o', key);
return this.#strategyInstanceMap.delete(key);
}

Expand All @@ -75,6 +83,7 @@ export class Schedule {
* start schedule
*/
start() {
debug('start');
this.closed = false;
for (const instance of this.#strategyInstanceMap.values()) {
instance.start();
Expand All @@ -86,5 +95,6 @@ export class Schedule {
for (const instance of this.#strategyInstanceMap.values()) {
instance.close();
}
debug('close');
}
}
2 changes: 1 addition & 1 deletion src/lib/schedule_worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { ScheduleItem } from './types.js';

export class ScheduleWorker {
#app: Application;
scheduleItems: Record<string, ScheduleItem>;
scheduleItems: Record<string, ScheduleItem> = {};

constructor(app: Application) {
this.#app = app;
Expand Down
6 changes: 3 additions & 3 deletions src/lib/strategy/timer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@ export abstract class TimerStrategy extends BaseStrategy {

const { interval, cron, cronOptions, immediate } = this.scheduleConfig;
assert(interval || cron || immediate,
`[egg-schedule] ${this.key} \`schedule.interval\` or \`schedule.cron]\` or \`schedule.immediate\` must be present`);
`[@eggjs/schedule] ${this.key} \`schedule.interval\` or \`schedule.cron\` or \`schedule.immediate\` must be present`);

// init cron parser
if (cron) {
try {
this.cronInstance = parseExpression(cron, cronOptions);
} catch (err: any) {
throw new TypeError(
`[egg-schedule] ${this.key} parse cron instruction(${cron}) error: ${err.message}`,
`[@eggjs/schedule] ${this.key} parse cron instruction(${cron}) error: ${err.message}`,
{ cause: err });
}
}
}

protected handler() {
throw new TypeError(`[egg-schedule] ${this.key} strategy should override \`handler()\` method`);
throw new TypeError(`[@eggjs/schedule] ${this.key} strategy should override \`handler()\` method`);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Interval extends Subscription {
};
}

* subscribe(data) {
async subscribe(data) {
this.ctx.logger.info('cluster_all_log_clz', data);
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/customTypeParams/app/schedule/cluster-clz.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Interval extends Subscription {
};
}

* subscribe(data) {
async subscribe(data) {
this.ctx.logger.info('cluster_log_clz', data);
}
}
Expand Down
10 changes: 10 additions & 0 deletions test/fixtures/executeError-task-generator/app/schedule/interval.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

exports.schedule = {
type: 'worker',
interval: 2000,
};

exports.task = function* () {
throw new Error('interval error');
};
3 changes: 3 additions & 0 deletions test/fixtures/executeError-task-generator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "executeError"
}
4 changes: 1 addition & 3 deletions test/fixtures/executeError/app/schedule/interval.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
'use strict';

exports.schedule = {
type: 'worker',
interval: 2000,
};

exports.task = function* () {
exports.task = async function() {
throw new Error('interval error');
};
12 changes: 0 additions & 12 deletions test/fixtures/generator/app/schedule/sub/cron.js

This file was deleted.

11 changes: 0 additions & 11 deletions test/fixtures/generator/app/service/user.js

This file was deleted.

3 changes: 0 additions & 3 deletions test/fixtures/generator/package.json

This file was deleted.

2 changes: 0 additions & 2 deletions test/fixtures/scheduleError/app/schedule/interval.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

exports.schedule = {
type: 'worker',
};
Expand Down
2 changes: 0 additions & 2 deletions test/fixtures/scheduleError/app/schedule/sub/cron.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

exports.schedule = {
type: 'worker',
cron: '*/5 * * * * *',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Interval extends Subscription {
};
}

* subscribe() {
async subscribe() {
this.app.logger.info('interval');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Interval extends Subscription {
};
}

* subscribe() {
async subscribe() {
this.app.logger.info('cron');
}
}
Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/subscription-generator/app/schedule/interval.js
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.ctx.logger.info('interval');
}
}

module.exports = Interval;
16 changes: 16 additions & 0 deletions test/fixtures/subscription-generator/app/schedule/sub/cron.js
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 * * * * *',
};
}

async subscribe() {
this.ctx.logger.info('cron');
}
}

module.exports = Interval;
1 change: 1 addition & 0 deletions test/fixtures/subscription-generator/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/subscription-generator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "subscription"
}
Loading

0 comments on commit 798efeb

Please sign in to comment.