@ruiapp/rapid-core 0.6.4 → 0.7.0
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/CHANGELOG.md +4 -0
- package/dist/core/pluginManager.d.ts +2 -0
- package/dist/core/routeContext.d.ts +1 -1
- package/dist/core/server.d.ts +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +35 -8
- package/dist/plugins/cronJob/CronJobPlugin.d.ts +2 -2
- package/dist/plugins/cronJob/CronJobPluginTypes.d.ts +0 -47
- package/dist/server.d.ts +11 -0
- package/dist/types/cron-job-types.d.ts +44 -0
- package/package.json +1 -1
- package/src/core/pluginManager.ts +9 -0
- package/src/core/routeContext.ts +2 -3
- package/src/core/server.ts +6 -0
- package/src/index.ts +1 -0
- package/src/plugins/cronJob/CronJobPlugin.ts +9 -8
- package/src/plugins/cronJob/CronJobPluginTypes.ts +0 -58
- package/src/server.ts +36 -0
- package/src/types/cron-job-types.ts +53 -0
package/CHANGELOG.md
CHANGED
|
@@ -28,6 +28,8 @@ declare class PluginManager {
|
|
|
28
28
|
configureServices(applicationConfig: RpdApplicationConfig): Promise<void>;
|
|
29
29
|
/** 配置路由 */
|
|
30
30
|
configureRoutes(applicationConfig: RpdApplicationConfig): Promise<void>;
|
|
31
|
+
/** 配置定时任务 */
|
|
32
|
+
registerCronJobs(): Promise<void>;
|
|
31
33
|
/** 在应用配置加载完成后调用。此时插件可以进行一些数据的初始化工作。 */
|
|
32
34
|
onApplicationLoaded(applicationConfig: RpdApplicationConfig): Promise<void>;
|
|
33
35
|
/** 在应用准备完成后调用。此时服务器已经可以处理网络请求。 */
|
|
@@ -21,7 +21,7 @@ export declare class RouteContext {
|
|
|
21
21
|
set(headerName: string, headerValue: string): void;
|
|
22
22
|
json(obj: any, status?: HttpStatus, headers?: HeadersInit): void;
|
|
23
23
|
redirect(url: string, status?: HttpStatus): void;
|
|
24
|
-
getDbTransactionClient(): IDatabaseClient |
|
|
24
|
+
getDbTransactionClient(): IDatabaseClient | undefined;
|
|
25
25
|
beginDbTransaction(): Promise<IDatabaseClient>;
|
|
26
26
|
commitDbTransaction(): Promise<void>;
|
|
27
27
|
rollbackDbTransaction(): Promise<void>;
|
package/dist/core/server.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Next, RouteContext } from "./routeContext";
|
|
|
4
4
|
import EntityManager from "../dataAccess/entityManager";
|
|
5
5
|
import { Logger } from "../facilities/log/LogFacility";
|
|
6
6
|
import { FacilityFactory } from "./facility";
|
|
7
|
+
import { CronJobConfiguration } from "../types/cron-job-types";
|
|
7
8
|
export interface IRpdServer {
|
|
8
9
|
config: RapidServerConfig;
|
|
9
10
|
databaseConfig: IDatabaseConfig;
|
|
@@ -32,6 +33,8 @@ export interface IRpdServer {
|
|
|
32
33
|
beforeRunRouteActions(handlerContext: ActionHandlerContext): Promise<void>;
|
|
33
34
|
beforeCreateEntity(model: RpdDataModel, options: CreateEntityOptions): Promise<void>;
|
|
34
35
|
beforeUpdateEntity(model: RpdDataModel, options: UpdateEntityByIdOptions, currentEntity: any): Promise<void>;
|
|
36
|
+
registerCronJob(job: CronJobConfiguration): void;
|
|
37
|
+
listCronJobs(): CronJobConfiguration[];
|
|
35
38
|
}
|
|
36
39
|
export type RpdConfigurationItemTypes = "integer" | "text" | "boolean" | "date" | "datetime" | "json";
|
|
37
40
|
export interface RpdConfigurationItemOptions {
|
|
@@ -94,6 +97,8 @@ export interface RapidPlugin {
|
|
|
94
97
|
configureServices?: (server: IRpdServer, applicationConfig: RpdApplicationConfig) => Promise<any>;
|
|
95
98
|
/** 配置路由 */
|
|
96
99
|
configureRoutes?: (server: IRpdServer, applicationConfig: RpdApplicationConfig) => Promise<any>;
|
|
100
|
+
/** 注册定时任务 */
|
|
101
|
+
registerCronJobs?: (server: IRpdServer) => Promise<any>;
|
|
97
102
|
/** 在应用配置加载完成后调用。此时插件可以进行一些数据的初始化工作。 */
|
|
98
103
|
onApplicationLoaded?: (server: IRpdServer, applicationConfig: RpdApplicationConfig) => Promise<any>;
|
|
99
104
|
/** 在应用准备完成后调用。此时服务器已经可以处理网络请求,可以对外广播消息。 */
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -839,6 +839,14 @@ class PluginManager {
|
|
|
839
839
|
}
|
|
840
840
|
}
|
|
841
841
|
}
|
|
842
|
+
/** 配置定时任务 */
|
|
843
|
+
async registerCronJobs() {
|
|
844
|
+
for (const plugin of this.#plugins) {
|
|
845
|
+
if (plugin.registerCronJobs) {
|
|
846
|
+
await plugin.registerCronJobs(this.#server);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
842
850
|
/** 在应用配置加载完成后调用。此时插件可以进行一些数据的初始化工作。 */
|
|
843
851
|
async onApplicationLoaded(applicationConfig) {
|
|
844
852
|
for (const plugin of this.#plugins) {
|
|
@@ -1067,7 +1075,6 @@ class RouteContext {
|
|
|
1067
1075
|
}
|
|
1068
1076
|
constructor(server, request) {
|
|
1069
1077
|
this.#server = server;
|
|
1070
|
-
this.#dbTransactionClient = null;
|
|
1071
1078
|
this.databaseAccessor = server.getDatabaseAccessor();
|
|
1072
1079
|
this.request = request;
|
|
1073
1080
|
this.state = {};
|
|
@@ -4262,6 +4269,9 @@ class RapidServer {
|
|
|
4262
4269
|
#entityBeforeResponseEventEmitters;
|
|
4263
4270
|
#entityWatchers;
|
|
4264
4271
|
#appEntityWatchers;
|
|
4272
|
+
#cronJobs;
|
|
4273
|
+
#appCronJobs;
|
|
4274
|
+
#disableCronJobs;
|
|
4265
4275
|
#cachedEntityManager;
|
|
4266
4276
|
#services;
|
|
4267
4277
|
queryBuilder;
|
|
@@ -4305,6 +4315,9 @@ class RapidServer {
|
|
|
4305
4315
|
this.registerEventHandler("entity.beforeResponse", this.#handleEntityEvent.bind(this, "entity.beforeResponse"));
|
|
4306
4316
|
this.#entityWatchers = [];
|
|
4307
4317
|
this.#appEntityWatchers = options.entityWatchers || [];
|
|
4318
|
+
this.#cronJobs = [];
|
|
4319
|
+
this.#appCronJobs = options.cronJobs || [];
|
|
4320
|
+
this.#disableCronJobs = !!options.disableCronJobs;
|
|
4308
4321
|
this.#services = new Map();
|
|
4309
4322
|
this.queryBuilder = new QueryBuilder({
|
|
4310
4323
|
dbDefaultSchema: options.databaseConfig.dbDefaultSchema,
|
|
@@ -4457,6 +4470,16 @@ class RapidServer {
|
|
|
4457
4470
|
getService(name) {
|
|
4458
4471
|
return this.#services.get(name);
|
|
4459
4472
|
}
|
|
4473
|
+
registerCronJob(job) {
|
|
4474
|
+
const jobDuplicate = lodash.find(this.#cronJobs, (item) => item.code === job.code);
|
|
4475
|
+
if (jobDuplicate) {
|
|
4476
|
+
this.#logger.warn(`Duplicated cron job with code "${job.code}"`);
|
|
4477
|
+
}
|
|
4478
|
+
this.#cronJobs.push(job);
|
|
4479
|
+
}
|
|
4480
|
+
listCronJobs() {
|
|
4481
|
+
return [...this.#cronJobs, ...this.#appCronJobs];
|
|
4482
|
+
}
|
|
4460
4483
|
async start() {
|
|
4461
4484
|
this.#logger.info("Starting rapid server...");
|
|
4462
4485
|
const pluginManager = this.#pluginManager;
|
|
@@ -4498,6 +4521,9 @@ class RapidServer {
|
|
|
4498
4521
|
}
|
|
4499
4522
|
}
|
|
4500
4523
|
await this.configureApplication();
|
|
4524
|
+
if (!this.#disableCronJobs) {
|
|
4525
|
+
await pluginManager.registerCronJobs();
|
|
4526
|
+
}
|
|
4501
4527
|
this.#logger.info(`Rapid server ready.`);
|
|
4502
4528
|
await pluginManager.onApplicationReady(this.#applicationConfig);
|
|
4503
4529
|
}
|
|
@@ -8421,10 +8447,8 @@ var runCronJob = {
|
|
|
8421
8447
|
var pluginRoutes$1 = [runCronJob];
|
|
8422
8448
|
|
|
8423
8449
|
class CronJobPlugin {
|
|
8424
|
-
#
|
|
8425
|
-
constructor(
|
|
8426
|
-
this.#jobs = options.jobs || [];
|
|
8427
|
-
}
|
|
8450
|
+
#server;
|
|
8451
|
+
constructor() { }
|
|
8428
8452
|
get code() {
|
|
8429
8453
|
return "cronJob";
|
|
8430
8454
|
}
|
|
@@ -8440,7 +8464,9 @@ class CronJobPlugin {
|
|
|
8440
8464
|
get configurations() {
|
|
8441
8465
|
return [];
|
|
8442
8466
|
}
|
|
8443
|
-
async initPlugin(server) {
|
|
8467
|
+
async initPlugin(server) {
|
|
8468
|
+
this.#server = server;
|
|
8469
|
+
}
|
|
8444
8470
|
async registerMiddlewares(server) { }
|
|
8445
8471
|
async registerActionHandlers(server) {
|
|
8446
8472
|
for (const actionHandler of pluginActionHandlers$1) {
|
|
@@ -8458,7 +8484,8 @@ class CronJobPlugin {
|
|
|
8458
8484
|
}
|
|
8459
8485
|
async onApplicationLoaded(server, applicationConfig) { }
|
|
8460
8486
|
async onApplicationReady(server, applicationConfig) {
|
|
8461
|
-
|
|
8487
|
+
const cronJobs = server.listCronJobs();
|
|
8488
|
+
for (const job of cronJobs) {
|
|
8462
8489
|
const jobInstance = cron__namespace.CronJob.from({
|
|
8463
8490
|
...(job.jobOptions || {}),
|
|
8464
8491
|
cronTime: job.cronTime,
|
|
@@ -8471,7 +8498,7 @@ class CronJobPlugin {
|
|
|
8471
8498
|
}
|
|
8472
8499
|
}
|
|
8473
8500
|
getJobConfigurationByCode(code) {
|
|
8474
|
-
return lodash.find(this.#
|
|
8501
|
+
return lodash.find(this.#server.listCronJobs(), (job) => job.code === code);
|
|
8475
8502
|
}
|
|
8476
8503
|
async executeJob(server, job) {
|
|
8477
8504
|
const logger = server.getLogger();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { RpdApplicationConfig } from "../../types";
|
|
2
|
-
import { CronJobConfiguration
|
|
2
|
+
import { CronJobConfiguration } from "../../types/cron-job-types";
|
|
3
3
|
import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
|
|
4
4
|
declare class CronJobPlugin implements RapidPlugin {
|
|
5
5
|
#private;
|
|
6
|
-
constructor(
|
|
6
|
+
constructor();
|
|
7
7
|
get code(): string;
|
|
8
8
|
get description(): string;
|
|
9
9
|
get extendingAbilities(): RpdServerPluginExtendingAbilities[];
|
|
@@ -1,50 +1,3 @@
|
|
|
1
|
-
import { ActionHandlerContext } from "../../core/actionHandler";
|
|
2
|
-
export interface CronJobConfiguration {
|
|
3
|
-
/**
|
|
4
|
-
* 定时任务编号
|
|
5
|
-
*/
|
|
6
|
-
code: string;
|
|
7
|
-
/**
|
|
8
|
-
* 定时任务描述
|
|
9
|
-
*/
|
|
10
|
-
description?: string;
|
|
11
|
-
/**
|
|
12
|
-
* crontab 表达式
|
|
13
|
-
*/
|
|
14
|
-
cronTime: string;
|
|
15
|
-
/**
|
|
16
|
-
* 任务设置
|
|
17
|
-
*/
|
|
18
|
-
jobOptions?: CronJobOptions;
|
|
19
|
-
/**
|
|
20
|
-
* 任务处理程序编号。当指定处理程序编号时,忽略 handler 配置。
|
|
21
|
-
*/
|
|
22
|
-
actionHandlerCode?: string;
|
|
23
|
-
/**
|
|
24
|
-
* 定时任务处理程序
|
|
25
|
-
* @param ctx
|
|
26
|
-
* @param options
|
|
27
|
-
* @returns
|
|
28
|
-
*/
|
|
29
|
-
handler?: (ctx: ActionHandlerContext, options: any) => Promise<void>;
|
|
30
|
-
/**
|
|
31
|
-
* 处理定时任务时的设置选项
|
|
32
|
-
*/
|
|
33
|
-
handleOptions?: any;
|
|
34
|
-
}
|
|
35
|
-
export interface CronJobOptions {
|
|
36
|
-
/**
|
|
37
|
-
* Instantly triggers the onTick function post initialization. Default is false.
|
|
38
|
-
*/
|
|
39
|
-
runOnInit?: boolean;
|
|
40
|
-
/**
|
|
41
|
-
* If true, no additional instances of the onTick callback function will run until the current onTick callback has completed. Any new scheduled executions that occur while the current callback is running will be skipped entirely. Default is false.
|
|
42
|
-
*/
|
|
43
|
-
waitForCompletion?: boolean;
|
|
44
|
-
}
|
|
45
|
-
export interface CronJobPluginInitOptions {
|
|
46
|
-
jobs: CronJobConfiguration[];
|
|
47
|
-
}
|
|
48
1
|
export type RunCronJobActionHandlerOptions = {
|
|
49
2
|
code?: string;
|
|
50
3
|
};
|
package/dist/server.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { Next } from "./core/routeContext";
|
|
|
5
5
|
import EntityManager from "./dataAccess/entityManager";
|
|
6
6
|
import { Logger } from "./facilities/log/LogFacility";
|
|
7
7
|
import { FacilityFactory } from "./core/facility";
|
|
8
|
+
import { CronJobConfiguration } from "./types/cron-job-types";
|
|
8
9
|
export interface InitServerOptions {
|
|
9
10
|
logger: Logger;
|
|
10
11
|
databaseAccessor: IDatabaseAccessor;
|
|
@@ -14,6 +15,14 @@ export interface InitServerOptions {
|
|
|
14
15
|
facilityFactories?: FacilityFactory[];
|
|
15
16
|
plugins?: RapidPlugin[];
|
|
16
17
|
entityWatchers?: EntityWatcherType[];
|
|
18
|
+
/**
|
|
19
|
+
* Application level cron jobs.
|
|
20
|
+
*/
|
|
21
|
+
cronJobs?: CronJobConfiguration[];
|
|
22
|
+
/**
|
|
23
|
+
* All cron jobs of the server will be disabled if set `true`.
|
|
24
|
+
*/
|
|
25
|
+
disableCronJobs?: boolean;
|
|
17
26
|
}
|
|
18
27
|
export declare class RapidServer implements IRpdServer {
|
|
19
28
|
#private;
|
|
@@ -37,6 +46,8 @@ export declare class RapidServer implements IRpdServer {
|
|
|
37
46
|
emitEvent<TEventName extends keyof RpdServerEventTypes>(event: EmitServerEventOptions<TEventName>): Promise<void>;
|
|
38
47
|
registerService(name: string, service: any): void;
|
|
39
48
|
getService<TService>(name: string): TService;
|
|
49
|
+
registerCronJob(job: CronJobConfiguration): void;
|
|
50
|
+
listCronJobs(): CronJobConfiguration[];
|
|
40
51
|
start(): Promise<void>;
|
|
41
52
|
configureApplication(): Promise<void>;
|
|
42
53
|
registerFacilityFactory(factory: FacilityFactory): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ActionHandlerContext } from "../core/actionHandler";
|
|
2
|
+
export interface CronJobConfiguration {
|
|
3
|
+
/**
|
|
4
|
+
* 定时任务编号
|
|
5
|
+
*/
|
|
6
|
+
code: string;
|
|
7
|
+
/**
|
|
8
|
+
* 定时任务描述
|
|
9
|
+
*/
|
|
10
|
+
description?: string;
|
|
11
|
+
/**
|
|
12
|
+
* crontab 表达式
|
|
13
|
+
*/
|
|
14
|
+
cronTime: string;
|
|
15
|
+
/**
|
|
16
|
+
* 任务设置
|
|
17
|
+
*/
|
|
18
|
+
jobOptions?: CronJobOptions;
|
|
19
|
+
/**
|
|
20
|
+
* 任务处理程序编号。当指定处理程序编号时,忽略 handler 配置。
|
|
21
|
+
*/
|
|
22
|
+
actionHandlerCode?: string;
|
|
23
|
+
/**
|
|
24
|
+
* 定时任务处理程序
|
|
25
|
+
* @param ctx
|
|
26
|
+
* @param options
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
handler?: (ctx: ActionHandlerContext, options: any) => Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* 处理定时任务时的设置选项
|
|
32
|
+
*/
|
|
33
|
+
handleOptions?: any;
|
|
34
|
+
}
|
|
35
|
+
export interface CronJobOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Instantly triggers the onTick function post initialization. Default is false.
|
|
38
|
+
*/
|
|
39
|
+
runOnInit?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* If true, no additional instances of the onTick callback function will run until the current onTick callback has completed. Any new scheduled executions that occur while the current callback is running will be skipped entirely. Default is false.
|
|
42
|
+
*/
|
|
43
|
+
waitForCompletion?: boolean;
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -117,6 +117,15 @@ class PluginManager {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
/** 配置定时任务 */
|
|
121
|
+
async registerCronJobs() {
|
|
122
|
+
for (const plugin of this.#plugins) {
|
|
123
|
+
if (plugin.registerCronJobs) {
|
|
124
|
+
await plugin.registerCronJobs(this.#server);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
120
129
|
/** 在应用配置加载完成后调用。此时插件可以进行一些数据的初始化工作。 */
|
|
121
130
|
async onApplicationLoaded(applicationConfig: RpdApplicationConfig) {
|
|
122
131
|
for (const plugin of this.#plugins) {
|
package/src/core/routeContext.ts
CHANGED
|
@@ -20,7 +20,7 @@ export class RouteContext {
|
|
|
20
20
|
params: Record<string, string>;
|
|
21
21
|
routeConfig: any;
|
|
22
22
|
#server: IRpdServer;
|
|
23
|
-
#dbTransactionClient: IDatabaseClient |
|
|
23
|
+
#dbTransactionClient: IDatabaseClient | undefined;
|
|
24
24
|
|
|
25
25
|
static newSystemOperationContext(server: IRpdServer) {
|
|
26
26
|
return new RouteContext(server);
|
|
@@ -28,7 +28,6 @@ export class RouteContext {
|
|
|
28
28
|
|
|
29
29
|
constructor(server: IRpdServer, request?: RapidRequest) {
|
|
30
30
|
this.#server = server;
|
|
31
|
-
this.#dbTransactionClient = null;
|
|
32
31
|
this.databaseAccessor = server.getDatabaseAccessor();
|
|
33
32
|
this.request = request;
|
|
34
33
|
this.state = {};
|
|
@@ -68,7 +67,7 @@ export class RouteContext {
|
|
|
68
67
|
this.response.redirect(url, status);
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
getDbTransactionClient(): IDatabaseClient |
|
|
70
|
+
getDbTransactionClient(): IDatabaseClient | undefined {
|
|
72
71
|
return this.#dbTransactionClient;
|
|
73
72
|
}
|
|
74
73
|
|
package/src/core/server.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { Next, RouteContext } from "./routeContext";
|
|
|
21
21
|
import EntityManager from "~/dataAccess/entityManager";
|
|
22
22
|
import { Logger } from "~/facilities/log/LogFacility";
|
|
23
23
|
import { FacilityFactory } from "./facility";
|
|
24
|
+
import { CronJobConfiguration } from "~/types/cron-job-types";
|
|
24
25
|
|
|
25
26
|
export interface IRpdServer {
|
|
26
27
|
config: RapidServerConfig;
|
|
@@ -53,6 +54,9 @@ export interface IRpdServer {
|
|
|
53
54
|
beforeRunRouteActions(handlerContext: ActionHandlerContext): Promise<void>;
|
|
54
55
|
beforeCreateEntity(model: RpdDataModel, options: CreateEntityOptions): Promise<void>;
|
|
55
56
|
beforeUpdateEntity(model: RpdDataModel, options: UpdateEntityByIdOptions, currentEntity: any): Promise<void>;
|
|
57
|
+
|
|
58
|
+
registerCronJob(job: CronJobConfiguration): void;
|
|
59
|
+
listCronJobs(): CronJobConfiguration[];
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
export type RpdConfigurationItemTypes = "integer" | "text" | "boolean" | "date" | "datetime" | "json";
|
|
@@ -130,6 +134,8 @@ export interface RapidPlugin {
|
|
|
130
134
|
configureServices?: (server: IRpdServer, applicationConfig: RpdApplicationConfig) => Promise<any>;
|
|
131
135
|
/** 配置路由 */
|
|
132
136
|
configureRoutes?: (server: IRpdServer, applicationConfig: RpdApplicationConfig) => Promise<any>;
|
|
137
|
+
/** 注册定时任务 */
|
|
138
|
+
registerCronJobs?: (server: IRpdServer) => Promise<any>;
|
|
133
139
|
/** 在应用配置加载完成后调用。此时插件可以进行一些数据的初始化工作。 */
|
|
134
140
|
onApplicationLoaded?: (server: IRpdServer, applicationConfig: RpdApplicationConfig) => Promise<any>;
|
|
135
141
|
/** 在应用准备完成后调用。此时服务器已经可以处理网络请求,可以对外广播消息。 */
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as cron from "cron";
|
|
|
2
2
|
import type { RpdApplicationConfig } from "~/types";
|
|
3
3
|
import pluginActionHandlers from "./actionHandlers";
|
|
4
4
|
import pluginRoutes from "./routes";
|
|
5
|
-
import { CronJobConfiguration
|
|
5
|
+
import { CronJobConfiguration } from "~/types/cron-job-types";
|
|
6
6
|
import {
|
|
7
7
|
IRpdServer,
|
|
8
8
|
RapidPlugin,
|
|
@@ -14,11 +14,9 @@ import { ActionHandlerContext } from "~/core/actionHandler";
|
|
|
14
14
|
import { find } from "lodash";
|
|
15
15
|
|
|
16
16
|
class CronJobPlugin implements RapidPlugin {
|
|
17
|
-
#
|
|
17
|
+
#server: IRpdServer;
|
|
18
18
|
|
|
19
|
-
constructor(
|
|
20
|
-
this.#jobs = options.jobs || [];
|
|
21
|
-
}
|
|
19
|
+
constructor() {}
|
|
22
20
|
|
|
23
21
|
get code(): string {
|
|
24
22
|
return "cronJob";
|
|
@@ -40,7 +38,9 @@ class CronJobPlugin implements RapidPlugin {
|
|
|
40
38
|
return [];
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
async initPlugin(server: IRpdServer): Promise<any> {
|
|
41
|
+
async initPlugin(server: IRpdServer): Promise<any> {
|
|
42
|
+
this.#server = server;
|
|
43
|
+
}
|
|
44
44
|
|
|
45
45
|
async registerMiddlewares(server: IRpdServer): Promise<any> {}
|
|
46
46
|
|
|
@@ -69,7 +69,8 @@ class CronJobPlugin implements RapidPlugin {
|
|
|
69
69
|
async onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {}
|
|
70
70
|
|
|
71
71
|
async onApplicationReady(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
|
|
72
|
-
|
|
72
|
+
const cronJobs = server.listCronJobs();
|
|
73
|
+
for (const job of cronJobs) {
|
|
73
74
|
const jobInstance = cron.CronJob.from({
|
|
74
75
|
...(job.jobOptions || {}),
|
|
75
76
|
cronTime: job.cronTime,
|
|
@@ -83,7 +84,7 @@ class CronJobPlugin implements RapidPlugin {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
getJobConfigurationByCode(code: string) {
|
|
86
|
-
return find(this.#
|
|
87
|
+
return find(this.#server.listCronJobs(), (job) => job.code === code);
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
async executeJob(server: IRpdServer, job: CronJobConfiguration) {
|
|
@@ -1,61 +1,3 @@
|
|
|
1
|
-
import { ActionHandlerContext } from "~/core/actionHandler";
|
|
2
|
-
|
|
3
|
-
export interface CronJobConfiguration {
|
|
4
|
-
/**
|
|
5
|
-
* 定时任务编号
|
|
6
|
-
*/
|
|
7
|
-
code: string;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 定时任务描述
|
|
11
|
-
*/
|
|
12
|
-
description?: string;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* crontab 表达式
|
|
16
|
-
*/
|
|
17
|
-
cronTime: string;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 任务设置
|
|
21
|
-
*/
|
|
22
|
-
jobOptions?: CronJobOptions;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 任务处理程序编号。当指定处理程序编号时,忽略 handler 配置。
|
|
26
|
-
*/
|
|
27
|
-
actionHandlerCode?: string;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* 定时任务处理程序
|
|
31
|
-
* @param ctx
|
|
32
|
-
* @param options
|
|
33
|
-
* @returns
|
|
34
|
-
*/
|
|
35
|
-
handler?: (ctx: ActionHandlerContext, options: any) => Promise<void>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 处理定时任务时的设置选项
|
|
39
|
-
*/
|
|
40
|
-
handleOptions?: any;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface CronJobOptions {
|
|
44
|
-
/**
|
|
45
|
-
* Instantly triggers the onTick function post initialization. Default is false.
|
|
46
|
-
*/
|
|
47
|
-
runOnInit?: boolean;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* If true, no additional instances of the onTick callback function will run until the current onTick callback has completed. Any new scheduled executions that occur while the current callback is running will be skipped entirely. Default is false.
|
|
51
|
-
*/
|
|
52
|
-
waitForCompletion?: boolean;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface CronJobPluginInitOptions {
|
|
56
|
-
jobs: CronJobConfiguration[];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
1
|
export type RunCronJobActionHandlerOptions = {
|
|
60
2
|
code?: string;
|
|
61
3
|
};
|
package/src/server.ts
CHANGED
|
@@ -33,6 +33,7 @@ import EntityManager from "./dataAccess/entityManager";
|
|
|
33
33
|
import { bind, cloneDeep, find, forEach, merge, omit } from "lodash";
|
|
34
34
|
import { Logger } from "./facilities/log/LogFacility";
|
|
35
35
|
import { FacilityFactory } from "./core/facility";
|
|
36
|
+
import { CronJobConfiguration } from "./types/cron-job-types";
|
|
36
37
|
|
|
37
38
|
export interface InitServerOptions {
|
|
38
39
|
logger: Logger;
|
|
@@ -43,6 +44,16 @@ export interface InitServerOptions {
|
|
|
43
44
|
facilityFactories?: FacilityFactory[];
|
|
44
45
|
plugins?: RapidPlugin[];
|
|
45
46
|
entityWatchers?: EntityWatcherType[];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Application level cron jobs.
|
|
50
|
+
*/
|
|
51
|
+
cronJobs?: CronJobConfiguration[];
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* All cron jobs of the server will be disabled if set `true`.
|
|
55
|
+
*/
|
|
56
|
+
disableCronJobs?: boolean;
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
export class RapidServer implements IRpdServer {
|
|
@@ -70,6 +81,10 @@ export class RapidServer implements IRpdServer {
|
|
|
70
81
|
#entityWatchers: EntityWatcherType[];
|
|
71
82
|
#appEntityWatchers: EntityWatcherType[];
|
|
72
83
|
|
|
84
|
+
#cronJobs: CronJobConfiguration[];
|
|
85
|
+
#appCronJobs: CronJobConfiguration[];
|
|
86
|
+
#disableCronJobs: boolean;
|
|
87
|
+
|
|
73
88
|
#cachedEntityManager: Map<string, EntityManager>;
|
|
74
89
|
#services: Map<string, any>;
|
|
75
90
|
queryBuilder: IQueryBuilder;
|
|
@@ -121,6 +136,10 @@ export class RapidServer implements IRpdServer {
|
|
|
121
136
|
this.#entityWatchers = [];
|
|
122
137
|
this.#appEntityWatchers = options.entityWatchers || [];
|
|
123
138
|
|
|
139
|
+
this.#cronJobs = [];
|
|
140
|
+
this.#appCronJobs = options.cronJobs || [];
|
|
141
|
+
this.#disableCronJobs = !!options.disableCronJobs;
|
|
142
|
+
|
|
124
143
|
this.#services = new Map();
|
|
125
144
|
|
|
126
145
|
this.queryBuilder = new QueryBuilder({
|
|
@@ -298,6 +317,19 @@ export class RapidServer implements IRpdServer {
|
|
|
298
317
|
return this.#services.get(name);
|
|
299
318
|
}
|
|
300
319
|
|
|
320
|
+
registerCronJob(job: CronJobConfiguration): void {
|
|
321
|
+
const jobDuplicate = find(this.#cronJobs, (item: CronJobConfiguration) => item.code === job.code);
|
|
322
|
+
if (jobDuplicate) {
|
|
323
|
+
this.#logger.warn(`Duplicated cron job with code "${job.code}"`);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
this.#cronJobs.push(job);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
listCronJobs() {
|
|
330
|
+
return [...this.#cronJobs, ...this.#appCronJobs];
|
|
331
|
+
}
|
|
332
|
+
|
|
301
333
|
async start() {
|
|
302
334
|
this.#logger.info("Starting rapid server...");
|
|
303
335
|
const pluginManager = this.#pluginManager;
|
|
@@ -336,6 +368,10 @@ export class RapidServer implements IRpdServer {
|
|
|
336
368
|
|
|
337
369
|
await this.configureApplication();
|
|
338
370
|
|
|
371
|
+
if (!this.#disableCronJobs) {
|
|
372
|
+
await pluginManager.registerCronJobs();
|
|
373
|
+
}
|
|
374
|
+
|
|
339
375
|
this.#logger.info(`Rapid server ready.`);
|
|
340
376
|
await pluginManager.onApplicationReady(this.#applicationConfig);
|
|
341
377
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { ActionHandlerContext } from "~/core/actionHandler";
|
|
2
|
+
|
|
3
|
+
export interface CronJobConfiguration {
|
|
4
|
+
/**
|
|
5
|
+
* 定时任务编号
|
|
6
|
+
*/
|
|
7
|
+
code: string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 定时任务描述
|
|
11
|
+
*/
|
|
12
|
+
description?: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* crontab 表达式
|
|
16
|
+
*/
|
|
17
|
+
cronTime: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 任务设置
|
|
21
|
+
*/
|
|
22
|
+
jobOptions?: CronJobOptions;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 任务处理程序编号。当指定处理程序编号时,忽略 handler 配置。
|
|
26
|
+
*/
|
|
27
|
+
actionHandlerCode?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 定时任务处理程序
|
|
31
|
+
* @param ctx
|
|
32
|
+
* @param options
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
35
|
+
handler?: (ctx: ActionHandlerContext, options: any) => Promise<void>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 处理定时任务时的设置选项
|
|
39
|
+
*/
|
|
40
|
+
handleOptions?: any;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface CronJobOptions {
|
|
44
|
+
/**
|
|
45
|
+
* Instantly triggers the onTick function post initialization. Default is false.
|
|
46
|
+
*/
|
|
47
|
+
runOnInit?: boolean;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* If true, no additional instances of the onTick callback function will run until the current onTick callback has completed. Any new scheduled executions that occur while the current callback is running will be skipped entirely. Default is false.
|
|
51
|
+
*/
|
|
52
|
+
waitForCompletion?: boolean;
|
|
53
|
+
}
|