@eggjs/schedule 5.0.2 → 6.0.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -12
- package/dist/agent.d.ts +13 -0
- package/dist/agent.js +32 -0
- package/dist/app/extend/agent.d.ts +22 -0
- package/dist/app/extend/agent.js +32 -0
- package/dist/app/extend/application.d.ts +16 -0
- package/dist/app/extend/application.js +18 -0
- package/dist/app/extend/application.unittest.d.ts +13 -0
- package/dist/app/extend/application.unittest.js +43 -0
- package/dist/app.d.ts +11 -0
- package/dist/app.js +69 -0
- package/dist/config/config.default.d.ts +6 -0
- package/dist/config/config.default.js +13 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/lib/load_schedule.d.ts +7 -0
- package/dist/lib/load_schedule.js +61 -0
- package/dist/lib/schedule.d.ts +35 -0
- package/dist/lib/schedule.js +77 -0
- package/dist/lib/schedule_worker.d.ts +14 -0
- package/dist/lib/schedule_worker.js +22 -0
- package/dist/lib/strategy/all.d.ts +8 -0
- package/dist/lib/strategy/all.js +11 -0
- package/dist/lib/strategy/base.d.ts +35 -0
- package/dist/lib/strategy/base.js +73 -0
- package/dist/lib/strategy/timer.d.ts +24 -0
- package/dist/lib/strategy/timer.js +71 -0
- package/dist/lib/strategy/worker.d.ts +8 -0
- package/dist/lib/strategy/worker.js +11 -0
- package/dist/lib/types.d.ts +44 -0
- package/dist/lib/types.js +1 -0
- package/package.json +51 -55
- package/dist/commonjs/agent.d.ts +0 -7
- package/dist/commonjs/agent.js +0 -32
- package/dist/commonjs/app/extend/agent.d.ts +0 -2
- package/dist/commonjs/app/extend/agent.js +0 -29
- package/dist/commonjs/app/extend/application.d.ts +0 -2
- package/dist/commonjs/app/extend/application.js +0 -16
- package/dist/commonjs/app/extend/application.unittest.d.ts +0 -2
- package/dist/commonjs/app/extend/application.unittest.js +0 -58
- package/dist/commonjs/app.d.ts +0 -6
- package/dist/commonjs/app.js +0 -80
- package/dist/commonjs/config/config.default.d.ts +0 -2
- package/dist/commonjs/config/config.default.js +0 -17
- package/dist/commonjs/index.d.ts +0 -1
- package/dist/commonjs/index.js +0 -18
- package/dist/commonjs/lib/load_schedule.d.ts +0 -3
- package/dist/commonjs/lib/load_schedule.js +0 -71
- package/dist/commonjs/lib/schedule.d.ts +0 -31
- package/dist/commonjs/lib/schedule.js +0 -89
- package/dist/commonjs/lib/schedule_worker.d.ts +0 -10
- package/dist/commonjs/lib/schedule_worker.js +0 -22
- package/dist/commonjs/lib/strategy/all.d.ts +0 -4
- package/dist/commonjs/lib/strategy/all.js +0 -11
- package/dist/commonjs/lib/strategy/base.d.ts +0 -30
- package/dist/commonjs/lib/strategy/base.js +0 -79
- package/dist/commonjs/lib/strategy/timer.d.ts +0 -20
- package/dist/commonjs/lib/strategy/timer.js +0 -99
- package/dist/commonjs/lib/strategy/worker.d.ts +0 -4
- package/dist/commonjs/lib/strategy/worker.js +0 -11
- package/dist/commonjs/lib/types.d.ts +0 -53
- package/dist/commonjs/lib/types.js +0 -3
- package/dist/commonjs/package.json +0 -3
- package/dist/esm/agent.d.ts +0 -7
- package/dist/esm/agent.js +0 -29
- package/dist/esm/app/extend/agent.d.ts +0 -2
- package/dist/esm/app/extend/agent.js +0 -27
- package/dist/esm/app/extend/application.d.ts +0 -2
- package/dist/esm/app/extend/application.js +0 -14
- package/dist/esm/app/extend/application.unittest.d.ts +0 -2
- package/dist/esm/app/extend/application.unittest.js +0 -53
- package/dist/esm/app.d.ts +0 -6
- package/dist/esm/app.js +0 -77
- package/dist/esm/config/config.default.d.ts +0 -2
- package/dist/esm/config/config.default.js +0 -15
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/lib/load_schedule.d.ts +0 -3
- package/dist/esm/lib/load_schedule.js +0 -65
- package/dist/esm/lib/schedule.d.ts +0 -31
- package/dist/esm/lib/schedule.js +0 -85
- package/dist/esm/lib/schedule_worker.d.ts +0 -10
- package/dist/esm/lib/schedule_worker.js +0 -18
- package/dist/esm/lib/strategy/all.d.ts +0 -4
- package/dist/esm/lib/strategy/all.js +0 -7
- package/dist/esm/lib/strategy/base.d.ts +0 -30
- package/dist/esm/lib/strategy/base.js +0 -75
- package/dist/esm/lib/strategy/timer.d.ts +0 -20
- package/dist/esm/lib/strategy/timer.js +0 -92
- package/dist/esm/lib/strategy/worker.d.ts +0 -4
- package/dist/esm/lib/strategy/worker.js +0 -7
- package/dist/esm/lib/types.d.ts +0 -53
- package/dist/esm/lib/types.js +0 -2
- package/dist/esm/package.json +0 -3
- package/dist/package.json +0 -4
- package/src/agent.ts +0 -36
- package/src/app/extend/agent.ts +0 -30
- package/src/app/extend/application.ts +0 -16
- package/src/app/extend/application.unittest.ts +0 -57
- package/src/app.ts +0 -92
- package/src/config/config.default.ts +0 -17
- package/src/index.ts +0 -1
- package/src/lib/load_schedule.ts +0 -74
- package/src/lib/schedule.ts +0 -100
- package/src/lib/schedule_worker.ts +0 -24
- package/src/lib/strategy/all.ts +0 -7
- package/src/lib/strategy/base.ts +0 -91
- package/src/lib/strategy/timer.ts +0 -107
- package/src/lib/strategy/worker.ts +0 -7
- package/src/lib/types.ts +0 -58
package/README.md
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
# @eggjs/schedule
|
|
2
2
|
|
|
3
3
|
[![NPM version][npm-image]][npm-url]
|
|
4
|
-
[](https://github.com/eggjs/schedule/actions/workflows/nodejs.yml)
|
|
5
|
-
[![Test coverage][codecov-image]][codecov-url]
|
|
6
4
|
[![Known Vulnerabilities][snyk-image]][snyk-url]
|
|
7
5
|
[![npm download][download-image]][download-url]
|
|
8
6
|
[](https://nodejs.org/en/download/)
|
|
9
7
|
|
|
10
8
|
[npm-image]: https://img.shields.io/npm/v/@eggjs/schedule.svg?style=flat-square
|
|
11
9
|
[npm-url]: https://npmjs.org/package/@eggjs/schedule
|
|
12
|
-
[codecov-image]: https://codecov.io/github/eggjs/schedule/coverage.svg?branch=master
|
|
13
|
-
[codecov-url]: https://codecov.io/github/eggjs/schedule?branch=master
|
|
14
10
|
[snyk-image]: https://snyk.io/test/npm/@eggjs/schedule/badge.svg?style=flat-square
|
|
15
11
|
[snyk-url]: https://snyk.io/test/npm/@eggjs/schedule
|
|
16
12
|
[download-image]: https://img.shields.io/npm/dm/@eggjs/schedule.svg?style=flat-square
|
|
@@ -64,7 +60,7 @@ export const schedule = {
|
|
|
64
60
|
cron: '0 0 3 * * *',
|
|
65
61
|
// interval: '1h',
|
|
66
62
|
// immediate: true,
|
|
67
|
-
}
|
|
63
|
+
};
|
|
68
64
|
|
|
69
65
|
export async function task(ctx: EggContext) {
|
|
70
66
|
await ctx.service.db.cleandb();
|
|
@@ -197,7 +193,7 @@ export default (agent: Agent) => {
|
|
|
197
193
|
}
|
|
198
194
|
|
|
199
195
|
agent.schedule.use('custom', CustomStrategy);
|
|
200
|
-
}
|
|
196
|
+
};
|
|
201
197
|
```
|
|
202
198
|
|
|
203
199
|
Then you could use it to defined your job:
|
|
@@ -235,7 +231,7 @@ export default (app: Application) => {
|
|
|
235
231
|
// only start task when hostname match
|
|
236
232
|
disable: require('os').hostname() !== app.config.sync.hostname,
|
|
237
233
|
// only start task at prod mode
|
|
238
|
-
env: [
|
|
234
|
+
env: ['prod'],
|
|
239
235
|
};
|
|
240
236
|
}
|
|
241
237
|
|
|
@@ -245,7 +241,7 @@ export default (app: Application) => {
|
|
|
245
241
|
}
|
|
246
242
|
|
|
247
243
|
return SyncTask;
|
|
248
|
-
}
|
|
244
|
+
};
|
|
249
245
|
```
|
|
250
246
|
|
|
251
247
|
## Configuration
|
|
@@ -278,9 +274,7 @@ import { EggAppConfig } from 'egg';
|
|
|
278
274
|
|
|
279
275
|
export default {
|
|
280
276
|
schedule: {
|
|
281
|
-
directory: [
|
|
282
|
-
'path/to/otherSchedule',
|
|
283
|
-
],
|
|
277
|
+
directory: ['path/to/otherSchedule'],
|
|
284
278
|
},
|
|
285
279
|
} as Partial<EggAppConfig>;
|
|
286
280
|
```
|
|
@@ -308,6 +302,6 @@ Please open an issue [here](https://github.com/eggjs/egg/issues).
|
|
|
308
302
|
|
|
309
303
|
## Contributors
|
|
310
304
|
|
|
311
|
-
[](https://github.com/eggjs/egg/graphs/contributors)
|
|
312
306
|
|
|
313
307
|
Made with [contributors-img](https://contrib.rocks).
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Agent$1 from "./app/extend/agent.js";
|
|
2
|
+
import { ILifecycleBoot } from "egg";
|
|
3
|
+
|
|
4
|
+
//#region src/agent.d.ts
|
|
5
|
+
declare class Boot implements ILifecycleBoot {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(agent: Agent$1);
|
|
8
|
+
configDidLoad(): Promise<void>;
|
|
9
|
+
serverDidReady(): Promise<void>;
|
|
10
|
+
beforeClose(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Boot as default };
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { WorkerStrategy } from "./lib/strategy/worker.js";
|
|
2
|
+
import { AllStrategy } from "./lib/strategy/all.js";
|
|
3
|
+
import { debuglog } from "node:util";
|
|
4
|
+
|
|
5
|
+
//#region src/agent.ts
|
|
6
|
+
const debug = debuglog("egg/schedule/agent");
|
|
7
|
+
var Boot = class {
|
|
8
|
+
#agent;
|
|
9
|
+
constructor(agent) {
|
|
10
|
+
this.#agent = agent;
|
|
11
|
+
}
|
|
12
|
+
async configDidLoad() {
|
|
13
|
+
this.#agent.schedule.use("worker", WorkerStrategy);
|
|
14
|
+
this.#agent.schedule.use("all", AllStrategy);
|
|
15
|
+
await this.#agent.schedule.init();
|
|
16
|
+
this.#agent.messenger.on("egg-schedule", (info) => {
|
|
17
|
+
this.#agent.schedule.onJobFinish(info);
|
|
18
|
+
});
|
|
19
|
+
debug("configDidLoad");
|
|
20
|
+
}
|
|
21
|
+
async serverDidReady() {
|
|
22
|
+
await this.#agent.schedule.start();
|
|
23
|
+
debug("serverDidReady, schedule start");
|
|
24
|
+
}
|
|
25
|
+
async beforeClose() {
|
|
26
|
+
await this.#agent.schedule.close();
|
|
27
|
+
debug("beforeClose, schedule close");
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
export { Boot as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseStrategy } from "../../lib/strategy/base.js";
|
|
2
|
+
import { TimerStrategy } from "../../lib/strategy/timer.js";
|
|
3
|
+
import { Schedule } from "../../lib/schedule.js";
|
|
4
|
+
import { Agent as Agent$1 } from "egg";
|
|
5
|
+
|
|
6
|
+
//#region src/app/extend/agent.d.ts
|
|
7
|
+
declare class Agent extends Agent$1 {
|
|
8
|
+
/**
|
|
9
|
+
* @member agent#ScheduleStrategy
|
|
10
|
+
*/
|
|
11
|
+
get ScheduleStrategy(): typeof BaseStrategy;
|
|
12
|
+
/**
|
|
13
|
+
* @member agent#TimerScheduleStrategy
|
|
14
|
+
*/
|
|
15
|
+
get TimerScheduleStrategy(): typeof TimerStrategy;
|
|
16
|
+
/**
|
|
17
|
+
* @member agent#schedule
|
|
18
|
+
*/
|
|
19
|
+
get schedule(): Schedule;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { Agent as default };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { BaseStrategy } from "../../lib/strategy/base.js";
|
|
2
|
+
import { TimerStrategy } from "../../lib/strategy/timer.js";
|
|
3
|
+
import { Schedule } from "../../lib/schedule.js";
|
|
4
|
+
import { Agent as Agent$1 } from "egg";
|
|
5
|
+
|
|
6
|
+
//#region src/app/extend/agent.ts
|
|
7
|
+
const SCHEDULE = Symbol("agent schedule");
|
|
8
|
+
var Agent = class extends Agent$1 {
|
|
9
|
+
/**
|
|
10
|
+
* @member agent#ScheduleStrategy
|
|
11
|
+
*/
|
|
12
|
+
get ScheduleStrategy() {
|
|
13
|
+
return BaseStrategy;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @member agent#TimerScheduleStrategy
|
|
17
|
+
*/
|
|
18
|
+
get TimerScheduleStrategy() {
|
|
19
|
+
return TimerStrategy;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* @member agent#schedule
|
|
23
|
+
*/
|
|
24
|
+
get schedule() {
|
|
25
|
+
let schedule = this[SCHEDULE];
|
|
26
|
+
if (!schedule) this[SCHEDULE] = schedule = new Schedule(this);
|
|
27
|
+
return schedule;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
export { Agent as default };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ScheduleWorker } from "../../lib/schedule_worker.js";
|
|
2
|
+
import { Application as Application$1 } from "egg";
|
|
3
|
+
|
|
4
|
+
//#region src/app/extend/application.d.ts
|
|
5
|
+
declare class Application extends Application$1 {
|
|
6
|
+
/**
|
|
7
|
+
* @member app#schedule
|
|
8
|
+
*/
|
|
9
|
+
get scheduleWorker(): ScheduleWorker;
|
|
10
|
+
/**
|
|
11
|
+
* For unittest only - run a specific schedule task
|
|
12
|
+
*/
|
|
13
|
+
runSchedule?(schedulePath: string, ...args: any[]): Promise<any>;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { Application as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ScheduleWorker } from "../../lib/schedule_worker.js";
|
|
2
|
+
import { Application as Application$1 } from "egg";
|
|
3
|
+
|
|
4
|
+
//#region src/app/extend/application.ts
|
|
5
|
+
const SCHEDULE_WORKER = Symbol("application scheduleWorker");
|
|
6
|
+
var Application = class extends Application$1 {
|
|
7
|
+
/**
|
|
8
|
+
* @member app#schedule
|
|
9
|
+
*/
|
|
10
|
+
get scheduleWorker() {
|
|
11
|
+
let scheduleWorker = this[SCHEDULE_WORKER];
|
|
12
|
+
if (!scheduleWorker) this[SCHEDULE_WORKER] = scheduleWorker = new ScheduleWorker(this);
|
|
13
|
+
return scheduleWorker;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Application as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Application from "./application.js";
|
|
2
|
+
|
|
3
|
+
//#region src/app/extend/application.unittest.d.ts
|
|
4
|
+
declare class ApplicationUnittest extends Application {
|
|
5
|
+
runSchedule(schedulePath: string, ...args: any[]): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
declare module '@eggjs/mock' {
|
|
8
|
+
interface MockApplication {
|
|
9
|
+
runSchedule(schedulePath: string, ...args: any[]): Promise<any>;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { ApplicationUnittest as default };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import Application from "./application.js";
|
|
2
|
+
import { debuglog } from "node:util";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { importResolve } from "@eggjs/utils";
|
|
5
|
+
|
|
6
|
+
//#region src/app/extend/application.unittest.ts
|
|
7
|
+
const debug = debuglog("egg/schedule/app");
|
|
8
|
+
var ApplicationUnittest = class extends Application {
|
|
9
|
+
async runSchedule(schedulePath, ...args) {
|
|
10
|
+
debug("[runSchedule] start schedulePath: %o, args: %o", schedulePath, args);
|
|
11
|
+
const config = this.config;
|
|
12
|
+
const directory = [path.join(config.baseDir, "app/schedule"), ...config.schedule.directory];
|
|
13
|
+
if (path.isAbsolute(schedulePath)) schedulePath = importResolve(schedulePath);
|
|
14
|
+
else for (const dir of directory) {
|
|
15
|
+
const trySchedulePath = path.join(dir, schedulePath);
|
|
16
|
+
try {
|
|
17
|
+
schedulePath = importResolve(trySchedulePath);
|
|
18
|
+
break;
|
|
19
|
+
} catch (err) {
|
|
20
|
+
debug("[runSchedule] importResolve %o error: %s", trySchedulePath, err);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
debug("[runSchedule] resolve schedulePath: %o", schedulePath);
|
|
24
|
+
let schedule;
|
|
25
|
+
try {
|
|
26
|
+
schedule = this.scheduleWorker.scheduleItems[schedulePath];
|
|
27
|
+
if (!schedule) throw new TypeError(`Cannot find schedule ${schedulePath}`);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
err.message = `[@eggjs/schedule] ${err.message}`;
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
const ctx = this.createAnonymousContext({
|
|
33
|
+
method: "SCHEDULE",
|
|
34
|
+
url: `/__schedule?path=${schedulePath}&${schedule.scheduleQueryString}`
|
|
35
|
+
});
|
|
36
|
+
return await this.ctxStorage.run(ctx, async () => {
|
|
37
|
+
return await schedule.task(ctx, ...args);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
export { ApplicationUnittest as default };
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Application$1 from "./app/extend/application.js";
|
|
2
|
+
import { ILifecycleBoot } from "egg";
|
|
3
|
+
|
|
4
|
+
//#region src/app.d.ts
|
|
5
|
+
declare class Boot implements ILifecycleBoot {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(app: Application$1);
|
|
8
|
+
configDidLoad(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { Boot as default };
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { debuglog } from "node:util";
|
|
2
|
+
|
|
3
|
+
//#region src/app.ts
|
|
4
|
+
const debug = debuglog("egg/schedule/app");
|
|
5
|
+
var Boot = class {
|
|
6
|
+
#app;
|
|
7
|
+
#logger;
|
|
8
|
+
constructor(app) {
|
|
9
|
+
this.#app = app;
|
|
10
|
+
this.#logger = app.getLogger("scheduleLogger");
|
|
11
|
+
}
|
|
12
|
+
async configDidLoad() {
|
|
13
|
+
const scheduleWorker = this.#app.scheduleWorker;
|
|
14
|
+
await scheduleWorker.init();
|
|
15
|
+
for (const s in scheduleWorker.scheduleItems) {
|
|
16
|
+
const schedule = scheduleWorker.scheduleItems[s];
|
|
17
|
+
if (!schedule.schedule.disable) this.#logger.info("[@eggjs/schedule]: register schedule %s", schedule.key);
|
|
18
|
+
}
|
|
19
|
+
this.#app.messenger.on("egg-schedule", async (info) => {
|
|
20
|
+
debug("app got \"egg-schedule\" message: %o", info);
|
|
21
|
+
const { id, key } = info;
|
|
22
|
+
this.#logger.debug(`[Job#${id}] ${key} await app ready`);
|
|
23
|
+
await this.#app.ready();
|
|
24
|
+
const schedule = scheduleWorker.scheduleItems[key];
|
|
25
|
+
this.#logger.debug(`[Job#${id}] ${key} task received by app`);
|
|
26
|
+
if (!schedule) {
|
|
27
|
+
this.#logger.warn(`[Job#${id}] ${key} unknown task`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
/* istanbul ignore next */
|
|
31
|
+
if (schedule.schedule.disable) {
|
|
32
|
+
this.#logger.warn(`[Job#${id}] ${key} disable`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.#logger.info(`[Job#${id}] ${key} executing by app`);
|
|
36
|
+
const ctx = this.#app.createAnonymousContext({
|
|
37
|
+
method: "SCHEDULE",
|
|
38
|
+
url: `/__schedule?path=${key}&${schedule.scheduleQueryString}`
|
|
39
|
+
});
|
|
40
|
+
const start = Date.now();
|
|
41
|
+
let success;
|
|
42
|
+
let e;
|
|
43
|
+
try {
|
|
44
|
+
await this.#app.ctxStorage.run(ctx, async () => {
|
|
45
|
+
return await schedule.task(ctx, ...info.args);
|
|
46
|
+
});
|
|
47
|
+
success = true;
|
|
48
|
+
} catch (err) {
|
|
49
|
+
success = false;
|
|
50
|
+
e = err;
|
|
51
|
+
}
|
|
52
|
+
const rt = Date.now() - start;
|
|
53
|
+
const msg = `[Job#${id}] ${key} execute ${success ? "succeed" : "failed"}, used ${rt}ms.`;
|
|
54
|
+
if (success) this.#logger.info(msg);
|
|
55
|
+
else this.#logger.error(msg, e);
|
|
56
|
+
this.#app.messenger.sendToAgent("egg-schedule", {
|
|
57
|
+
...info,
|
|
58
|
+
success,
|
|
59
|
+
workerId: process.pid,
|
|
60
|
+
rt,
|
|
61
|
+
message: e?.message
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
debug("configDidLoad");
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
export { Boot as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "egg";
|
|
2
|
+
|
|
3
|
+
//#region src/config/config.default.ts
|
|
4
|
+
var config_default_default = {
|
|
5
|
+
customLogger: { scheduleLogger: {
|
|
6
|
+
consoleLevel: "NONE",
|
|
7
|
+
file: "egg-schedule.log"
|
|
8
|
+
} },
|
|
9
|
+
schedule: { directory: [] }
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
export { config_default_default as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { EggScheduleConfig, EggScheduleItem, EggScheduleJobInfo, EggScheduleTask } from "./lib/types.js";
|
|
2
|
+
import { Schedule } from "./lib/schedule.js";
|
|
3
|
+
import Agent from "./app/extend/agent.js";
|
|
4
|
+
import { ScheduleWorker } from "./lib/schedule_worker.js";
|
|
5
|
+
import Application from "./app/extend/application.js";
|
|
6
|
+
import ApplicationUnittest from "./app/extend/application.unittest.js";
|
|
7
|
+
export { Agent, Application, ApplicationUnittest, EggScheduleConfig, EggScheduleItem, EggScheduleJobInfo, EggScheduleTask, Schedule, ScheduleWorker };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Schedule } from "./lib/schedule.js";
|
|
2
|
+
import Agent from "./app/extend/agent.js";
|
|
3
|
+
import { ScheduleWorker } from "./lib/schedule_worker.js";
|
|
4
|
+
import Application from "./app/extend/application.js";
|
|
5
|
+
import ApplicationUnittest from "./app/extend/application.unittest.js";
|
|
6
|
+
|
|
7
|
+
export { Agent, Application, ApplicationUnittest, Schedule, ScheduleWorker };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { EggScheduleItem } from "./types.js";
|
|
2
|
+
import { EggApplicationCore } from "egg";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/load_schedule.d.ts
|
|
5
|
+
declare function loadSchedule(app: EggApplicationCore): Promise<Record<string, EggScheduleItem>>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { loadSchedule };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { stringify } from "node:querystring";
|
|
4
|
+
import { isClass, isFunction, isGeneratorFunction } from "is-type-of";
|
|
5
|
+
import { importResolve } from "@eggjs/utils";
|
|
6
|
+
|
|
7
|
+
//#region src/lib/load_schedule.ts
|
|
8
|
+
function getScheduleLoader(app) {
|
|
9
|
+
return class ScheduleLoader extends app.loader.FileLoader {
|
|
10
|
+
async load() {
|
|
11
|
+
const target = this.options.target;
|
|
12
|
+
const items = await this.parse();
|
|
13
|
+
for (const item of items) {
|
|
14
|
+
const schedule = item.exports;
|
|
15
|
+
const fullpath = item.fullpath;
|
|
16
|
+
const scheduleConfig = schedule.schedule;
|
|
17
|
+
assert(scheduleConfig, `schedule(${fullpath}): must have "schedule" and "task" properties`);
|
|
18
|
+
assert(isClass(schedule) || isFunction(schedule.task), `schedule(${fullpath}: \`schedule.task\` should be function or \`schedule\` should be class`);
|
|
19
|
+
let task;
|
|
20
|
+
if (isClass(schedule)) {
|
|
21
|
+
assert(!isGeneratorFunction(schedule.prototype.subscribe), `schedule(${fullpath}): "schedule" generator function is not support, should use async function instead`);
|
|
22
|
+
task = async (ctx, ...args) => {
|
|
23
|
+
return new schedule(ctx).subscribe(...args);
|
|
24
|
+
};
|
|
25
|
+
} else {
|
|
26
|
+
assert(!isGeneratorFunction(schedule.task), `schedule(${fullpath}): "task" generator function is not support, should use async function instead`);
|
|
27
|
+
task = schedule.task;
|
|
28
|
+
}
|
|
29
|
+
const env = app.config.env;
|
|
30
|
+
const envList = schedule.schedule.env;
|
|
31
|
+
if (Array.isArray(envList) && !envList.includes(env)) {
|
|
32
|
+
app.coreLogger.info(`[@eggjs/schedule]: ignore schedule ${fullpath} due to \`schedule.env\` not match`);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const realFullpath = importResolve(fullpath);
|
|
36
|
+
target[realFullpath] = {
|
|
37
|
+
schedule: scheduleConfig,
|
|
38
|
+
scheduleQueryString: stringify(scheduleConfig),
|
|
39
|
+
task,
|
|
40
|
+
key: realFullpath
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return target;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async function loadSchedule(app) {
|
|
48
|
+
const dirs = [...app.loader.getLoadUnits().map((unit) => path.join(unit.path, "app/schedule")), ...app.config.schedule.directory];
|
|
49
|
+
const Loader = getScheduleLoader(app);
|
|
50
|
+
const schedules = {};
|
|
51
|
+
await new Loader({
|
|
52
|
+
directory: dirs,
|
|
53
|
+
target: schedules,
|
|
54
|
+
inject: app
|
|
55
|
+
}).load();
|
|
56
|
+
Reflect.set(app, "schedules", schedules);
|
|
57
|
+
return schedules;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { loadSchedule };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EggScheduleItem, EggScheduleJobInfo } from "./types.js";
|
|
2
|
+
import { BaseStrategy } from "./strategy/base.js";
|
|
3
|
+
import Agent from "../app/extend/agent.js";
|
|
4
|
+
|
|
5
|
+
//#region src/lib/schedule.d.ts
|
|
6
|
+
declare class Schedule {
|
|
7
|
+
#private;
|
|
8
|
+
closed: boolean;
|
|
9
|
+
constructor(agent: Agent);
|
|
10
|
+
/**
|
|
11
|
+
* register a custom Schedule Strategy
|
|
12
|
+
* @param {String} type - strategy type
|
|
13
|
+
* @param {Strategy} clz - Strategy class
|
|
14
|
+
*/
|
|
15
|
+
use(type: string, clz: typeof BaseStrategy): void;
|
|
16
|
+
/**
|
|
17
|
+
* load all schedule jobs, then initialize and register special strategy
|
|
18
|
+
*/
|
|
19
|
+
init(): Promise<void>;
|
|
20
|
+
registerSchedule(scheduleItem: EggScheduleItem): void;
|
|
21
|
+
unregisterSchedule(key: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* job finish event handler
|
|
24
|
+
*
|
|
25
|
+
* @param {Object} info - { id, key, success, message, workerId }
|
|
26
|
+
*/
|
|
27
|
+
onJobFinish(info: EggScheduleJobInfo): void;
|
|
28
|
+
/**
|
|
29
|
+
* start schedule
|
|
30
|
+
*/
|
|
31
|
+
start(): Promise<void>;
|
|
32
|
+
close(): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { Schedule };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { loadSchedule } from "./load_schedule.js";
|
|
2
|
+
import { debuglog } from "node:util";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/schedule.ts
|
|
5
|
+
const debug = debuglog("egg/schedule/lib/schedule");
|
|
6
|
+
var Schedule = class {
|
|
7
|
+
closed = false;
|
|
8
|
+
#agent;
|
|
9
|
+
#logger;
|
|
10
|
+
#strategyClassMap = /* @__PURE__ */ new Map();
|
|
11
|
+
#strategyInstanceMap = /* @__PURE__ */ new Map();
|
|
12
|
+
constructor(agent) {
|
|
13
|
+
this.#agent = agent;
|
|
14
|
+
this.#logger = agent.getLogger("scheduleLogger");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* register a custom Schedule Strategy
|
|
18
|
+
* @param {String} type - strategy type
|
|
19
|
+
* @param {Strategy} clz - Strategy class
|
|
20
|
+
*/
|
|
21
|
+
use(type, clz) {
|
|
22
|
+
this.#strategyClassMap.set(type, clz);
|
|
23
|
+
debug("use type: %o", type);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* load all schedule jobs, then initialize and register special strategy
|
|
27
|
+
*/
|
|
28
|
+
async init() {
|
|
29
|
+
const scheduleItems = await loadSchedule(this.#agent);
|
|
30
|
+
for (const scheduleItem of Object.values(scheduleItems)) this.registerSchedule(scheduleItem);
|
|
31
|
+
}
|
|
32
|
+
registerSchedule(scheduleItem) {
|
|
33
|
+
const { key, schedule } = scheduleItem;
|
|
34
|
+
const type = schedule.type;
|
|
35
|
+
if (schedule.disable) return;
|
|
36
|
+
const Strategy = this.#strategyClassMap.get(type);
|
|
37
|
+
if (!Strategy) {
|
|
38
|
+
const err = /* @__PURE__ */ new Error(`schedule type [${type}] is not defined`);
|
|
39
|
+
err.name = "EggScheduleError";
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
const instance = new Strategy(schedule, this.#agent, key);
|
|
43
|
+
this.#strategyInstanceMap.set(key, instance);
|
|
44
|
+
debug("registerSchedule type: %o, config: %o, key: %o", type, schedule, key);
|
|
45
|
+
}
|
|
46
|
+
unregisterSchedule(key) {
|
|
47
|
+
debug("unregisterSchedule key: %o", key);
|
|
48
|
+
return this.#strategyInstanceMap.delete(key);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* job finish event handler
|
|
52
|
+
*
|
|
53
|
+
* @param {Object} info - { id, key, success, message, workerId }
|
|
54
|
+
*/
|
|
55
|
+
onJobFinish(info) {
|
|
56
|
+
this.#logger.debug(`[Job#${info.id}] ${info.key} finish event received by agent from worker#${info.workerId}`);
|
|
57
|
+
const instance = this.#strategyInstanceMap.get(info.key);
|
|
58
|
+
/* istanbul ignore else */
|
|
59
|
+
if (instance) instance.onJobFinish(info);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* start schedule
|
|
63
|
+
*/
|
|
64
|
+
async start() {
|
|
65
|
+
debug("start");
|
|
66
|
+
this.closed = false;
|
|
67
|
+
for (const instance of this.#strategyInstanceMap.values()) instance.start();
|
|
68
|
+
}
|
|
69
|
+
async close() {
|
|
70
|
+
this.closed = true;
|
|
71
|
+
for (const instance of this.#strategyInstanceMap.values()) await instance.close();
|
|
72
|
+
debug("close");
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
export { Schedule };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EggScheduleItem } from "./types.js";
|
|
2
|
+
import Application from "../app/extend/application.js";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/schedule_worker.d.ts
|
|
5
|
+
declare class ScheduleWorker {
|
|
6
|
+
#private;
|
|
7
|
+
scheduleItems: Record<string, EggScheduleItem>;
|
|
8
|
+
constructor(app: Application);
|
|
9
|
+
init(): Promise<void>;
|
|
10
|
+
registerSchedule(scheduleItem: EggScheduleItem): void;
|
|
11
|
+
unregisterSchedule(key: string): void;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ScheduleWorker };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { loadSchedule } from "./load_schedule.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/schedule_worker.ts
|
|
4
|
+
var ScheduleWorker = class {
|
|
5
|
+
#app;
|
|
6
|
+
scheduleItems = {};
|
|
7
|
+
constructor(app) {
|
|
8
|
+
this.#app = app;
|
|
9
|
+
}
|
|
10
|
+
async init() {
|
|
11
|
+
this.scheduleItems = await loadSchedule(this.#app);
|
|
12
|
+
}
|
|
13
|
+
registerSchedule(scheduleItem) {
|
|
14
|
+
this.scheduleItems[scheduleItem.key] = scheduleItem;
|
|
15
|
+
}
|
|
16
|
+
unregisterSchedule(key) {
|
|
17
|
+
delete this.scheduleItems[key];
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { ScheduleWorker };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EggScheduleConfig, EggScheduleJobInfo } from "../types.js";
|
|
2
|
+
import Agent$1 from "../../app/extend/agent.js";
|
|
3
|
+
import { EggLogger } from "egg";
|
|
4
|
+
|
|
5
|
+
//#region src/lib/strategy/base.d.ts
|
|
6
|
+
declare class BaseStrategy {
|
|
7
|
+
protected agent: Agent$1;
|
|
8
|
+
protected scheduleConfig: EggScheduleConfig;
|
|
9
|
+
protected key: string;
|
|
10
|
+
protected logger: EggLogger;
|
|
11
|
+
protected closed: boolean;
|
|
12
|
+
count: number;
|
|
13
|
+
constructor(scheduleConfig: EggScheduleConfig, agent: Agent$1, key: string);
|
|
14
|
+
/** keep compatibility */
|
|
15
|
+
get schedule(): EggScheduleConfig;
|
|
16
|
+
start(): Promise<void>;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
onJobStart(_info: EggScheduleJobInfo): void;
|
|
19
|
+
onJobFinish(_info: EggScheduleJobInfo): void;
|
|
20
|
+
/**
|
|
21
|
+
* trigger one worker
|
|
22
|
+
*
|
|
23
|
+
* @param {...any} args - pass to job task
|
|
24
|
+
*/
|
|
25
|
+
sendOne(...args: any[]): void;
|
|
26
|
+
/**
|
|
27
|
+
* trigger all worker
|
|
28
|
+
*
|
|
29
|
+
* @param {...any} args - pass to job task
|
|
30
|
+
*/
|
|
31
|
+
sendAll(...args: any[]): void;
|
|
32
|
+
getSeqId(): string;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { BaseStrategy };
|