Skip to content

Commit 47d97bd

Browse files
committed
feat: impl Schedule decorator
1 parent 43b885a commit 47d97bd

37 files changed

+707
-3
lines changed

core/schedule-decorator/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# `@eggjs/tegg-schedule-decorator`
2+
3+
## Install
4+
5+
```shell
6+
npm i --save @eggjs/tegg-schedule-decorator
7+
```
8+
9+
## Define schedule subscriber
10+
11+
```ts
12+
import { Schedule } from '@eggjs/tegg';
13+
14+
// use number to define schedule interval
15+
@Schedule<IntervalParams>({
16+
type: ScheduleType.WORKER,
17+
scheduleData: {
18+
// run every 100ms
19+
interval: 100,
20+
},
21+
})
22+
export class FooSubscriber {
23+
@Inject()
24+
private readonly logger: EggLogger;
25+
26+
async subscribe() {
27+
this.logger.info('schedule called');
28+
}
29+
}
30+
31+
// use cron to define schedule interval
32+
@Schedule<CronParams>({
33+
type: ScheduleType.WORKER,
34+
scheduleData: {
35+
cron: '0 0 3 * * *',
36+
},
37+
})
38+
export class FooSubscriber {
39+
@Inject()
40+
private readonly logger: EggLogger;
41+
42+
async subscribe() {
43+
this.logger.info('schedule called');
44+
}
45+
}
46+
```

core/schedule-decorator/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './src/model/ScheduleMetadata';
2+
export * from './src/util/ScheduleInfoUtil';
3+
export * from './src/util/ScheduleMetadataUtil';
4+
export * from './src/decorator/Schedule';
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"name": "@eggjs/tegg-schedule-decorator",
3+
"version": "1.4.1",
4+
"description": "tegg schedule decorator",
5+
"main": "dist/index.js",
6+
"files": [
7+
"dist/**/*.js",
8+
"dist/**/*.d.ts"
9+
],
10+
"typings": "dist/index.d.ts",
11+
"keywords": [
12+
"egg",
13+
"typescript",
14+
"runtime",
15+
"tegg"
16+
],
17+
"scripts": {
18+
"clean": "tsc -b --clean",
19+
"tsc": "npm run clean && tsc -p ./tsconfig.json",
20+
"tsc:pub": "npm run clean && tsc -p ./tsconfig.pub.json",
21+
"prepublishOnly": "npm run tsc:pub",
22+
"autod": "autod"
23+
},
24+
"author": "killagu <[email protected]>",
25+
"license": "MIT",
26+
"homepage": "https://github.com/eggjs/tegg",
27+
"bugs": {
28+
"url": "https://github.com/eggjs/tegg/issues"
29+
},
30+
"repository": {
31+
"type": "git",
32+
"url": "[email protected]:eggjs/tegg.git",
33+
"directory": "core/schedule-decorator"
34+
},
35+
"engines": {
36+
"node": ">=14.0.0"
37+
},
38+
"dependencies": {
39+
"@eggjs/core-decorator": "^1.3.0",
40+
"@eggjs/tegg-common-util": "^1.1.1",
41+
"@eggjs/tegg-metadata": "^1.3.0",
42+
"cron-parser": "^2.18.0"
43+
},
44+
"devDependencies": {
45+
"egg-schedule": "^3.6.6"
46+
},
47+
"publishConfig": {
48+
"access": "public"
49+
}
50+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { EggProtoImplClass } from '@eggjs/core-decorator';
2+
import { ScheduleMetadata } from '../model/ScheduleMetadata';
3+
import { ScheduleInfoUtil } from '../util/ScheduleInfoUtil';
4+
import { ScheduleOptions } from '../decorator/Schedule';
5+
6+
const DEFAULT_SCHEDULE_OPTIONS: ScheduleOptions = {
7+
immediate: false,
8+
disable: false,
9+
env: undefined,
10+
};
11+
12+
export class ScheduleMetaBuilder {
13+
private readonly clazz: EggProtoImplClass;
14+
15+
constructor(clazz: EggProtoImplClass) {
16+
this.clazz = clazz;
17+
}
18+
19+
build(): ScheduleMetadata<object> {
20+
const params = ScheduleInfoUtil.getScheduleParams(this.clazz);
21+
if (!params) {
22+
throw new Error(`class ${this.clazz.name} is not a schedule`);
23+
}
24+
const options = ScheduleInfoUtil.getScheduleOptions(this.clazz);
25+
const scheduleOptions = Object.assign({}, DEFAULT_SCHEDULE_OPTIONS, options);
26+
return new ScheduleMetadata<object>(
27+
params.type,
28+
params.scheduleData,
29+
scheduleOptions.immediate!,
30+
scheduleOptions.disable!,
31+
scheduleOptions.env);
32+
}
33+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { ScheduleTypeLike } from '../model/ScheduleMetadata';
2+
import { AccessLevel, ContextProto, EggProtoImplClass, PrototypeUtil } from '@eggjs/core-decorator';
3+
import { ScheduleInfoUtil } from '../util/ScheduleInfoUtil';
4+
import { StackUtil } from '@eggjs/tegg-common-util';
5+
6+
export interface ScheduleParams<T> {
7+
type: ScheduleTypeLike;
8+
scheduleData: T;
9+
}
10+
11+
export interface CronParams {
12+
cron: string;
13+
cronOptions?: any;
14+
}
15+
16+
export interface IntervalParams {
17+
interval: string | number;
18+
}
19+
20+
export type CronScheduleParams = ScheduleParams<CronParams>;
21+
export type IntervalScheduleParams = ScheduleParams<IntervalParams>;
22+
23+
export interface ScheduleOptions {
24+
// default is false
25+
immediate?: boolean;
26+
// default is false
27+
disable?: boolean;
28+
// if env has value, only run in this envs
29+
env?: Array<string>;
30+
}
31+
32+
export interface ScheduleSubscriber {
33+
subscribe(data?: any): Promise<any>;
34+
}
35+
36+
export function Schedule<T>(param: ScheduleParams<T>, options?: ScheduleOptions) {
37+
return function(clazz: EggProtoImplClass<ScheduleSubscriber>) {
38+
ScheduleInfoUtil.setIsSchedule(true, clazz);
39+
ScheduleInfoUtil.setScheduleParams(param, clazz);
40+
if (options) {
41+
ScheduleInfoUtil.setScheduleOptions(options, clazz);
42+
}
43+
const func = ContextProto({
44+
name: clazz.name,
45+
accessLevel: AccessLevel.PUBLIC,
46+
});
47+
func(clazz);
48+
49+
PrototypeUtil.setFilePath(clazz, StackUtil.getCalleeFromStack(false, 5));
50+
};
51+
}
52+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export enum ScheduleType {
2+
WORKER = 'worker',
3+
ALL = 'all',
4+
}
5+
6+
export type ScheduleTypeLike = ScheduleType | string;
7+
8+
export class ScheduleMetadata<T> {
9+
type: ScheduleTypeLike;
10+
scheduleData: T;
11+
immediate: boolean;
12+
disable: boolean;
13+
env: undefined | Array<string>;
14+
15+
constructor(type: ScheduleTypeLike, data: T, immediate: boolean, disable: boolean, env: undefined | Array<string>) {
16+
this.type = type;
17+
this.scheduleData = data;
18+
this.immediate = immediate;
19+
this.disable = disable;
20+
this.env = env;
21+
}
22+
23+
shouldRegister(env: string): boolean {
24+
if (!this.env) return true;
25+
return this.env.includes(env);
26+
}
27+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { EggProtoImplClass, MetadataUtil } from '@eggjs/core-decorator';
2+
import { ScheduleOptions, ScheduleParams } from '../decorator/Schedule';
3+
4+
export const IS_SCHEDULE = Symbol.for('EggPrototype#isSchedule');
5+
export const SCHEDULE_PARAMS = Symbol.for('EggPrototype#schedule#params');
6+
export const SCHEDULE_OPTIONS = Symbol.for('EggPrototype#schedule#options');
7+
8+
export class ScheduleInfoUtil {
9+
static isSchedule(clazz: EggProtoImplClass): boolean {
10+
return MetadataUtil.getBooleanMetaData(IS_SCHEDULE, clazz);
11+
}
12+
13+
static setIsSchedule(isSchedule: boolean, clazz: EggProtoImplClass) {
14+
MetadataUtil.defineMetaData(IS_SCHEDULE, isSchedule, clazz);
15+
}
16+
17+
static setScheduleParams<T>(scheduleParams: ScheduleParams<T>, clazz: EggProtoImplClass) {
18+
MetadataUtil.defineMetaData(SCHEDULE_PARAMS, scheduleParams, clazz);
19+
}
20+
21+
static setScheduleOptions(scheduleParams: ScheduleOptions, clazz: EggProtoImplClass) {
22+
MetadataUtil.defineMetaData(SCHEDULE_OPTIONS, scheduleParams, clazz);
23+
}
24+
25+
static getScheduleOptions(clazz: EggProtoImplClass): ScheduleOptions | undefined {
26+
return MetadataUtil.getMetaData(SCHEDULE_OPTIONS, clazz);
27+
}
28+
29+
static getScheduleParams(clazz: EggProtoImplClass): ScheduleParams<object> | undefined {
30+
return MetadataUtil.getMetaData(SCHEDULE_PARAMS, clazz);
31+
}
32+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { EggProtoImplClass, MetadataUtil } from '@eggjs/core-decorator';
2+
import { ScheduleMetadata } from '../model/ScheduleMetadata';
3+
4+
export const SCHEDULE_METADATA = Symbol.for('EggPrototype#schedule#metadata');
5+
6+
export class ScheduleMetadataUtil {
7+
static setScheduleMetadata(clazz: EggProtoImplClass, metaData: ScheduleMetadata<object>) {
8+
MetadataUtil.defineMetaData(SCHEDULE_METADATA, metaData, clazz);
9+
}
10+
11+
static getScheduleMetadata(clazz): ScheduleMetadata<object> | undefined {
12+
return MetadataUtil.getMetaData(SCHEDULE_METADATA, clazz);
13+
}
14+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"baseUrl": "./"
6+
},
7+
"exclude": [
8+
"dist",
9+
"node_modules"
10+
]
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"baseUrl": "./"
6+
},
7+
"exclude": [
8+
"dist",
9+
"node_modules",
10+
"test"
11+
]
12+
}

0 commit comments

Comments
 (0)