@athenna/cron 4.0.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/LICENSE.md +9 -0
- package/README.md +42 -0
- package/package.json +187 -0
- package/src/annotations/Scheduler.d.ts +14 -0
- package/src/annotations/Scheduler.js +38 -0
- package/src/commands/MakeSchedulerCommand.d.ts +15 -0
- package/src/commands/MakeSchedulerCommand.js +47 -0
- package/src/cron/CronBuilder.d.ts +123 -0
- package/src/cron/CronBuilder.js +185 -0
- package/src/cron/CronImpl.d.ts +72 -0
- package/src/cron/CronImpl.js +92 -0
- package/src/debug/index.d.ts +9 -0
- package/src/debug/index.js +10 -0
- package/src/facades/Cron.d.ts +10 -0
- package/src/facades/Cron.js +10 -0
- package/src/handlers/CronExceptionHandler.d.ts +26 -0
- package/src/handlers/CronExceptionHandler.js +59 -0
- package/src/index.d.ts +16 -0
- package/src/index.js +16 -0
- package/src/kernels/CronKernel.d.ts +28 -0
- package/src/kernels/CronKernel.js +95 -0
- package/src/providers/CronProvider.d.ts +13 -0
- package/src/providers/CronProvider.js +22 -0
- package/src/types/Context.d.ts +16 -0
- package/src/types/Context.js +9 -0
- package/src/types/CronHandler.d.ts +10 -0
- package/src/types/CronHandler.js +9 -0
- package/src/types/ScheduledTask.d.ts +18 -0
- package/src/types/ScheduledTask.js +9 -0
- package/src/types/index.d.ts +12 -0
- package/src/types/index.js +12 -0
- package/src/types/schedulers/SchedulerOptions.d.ts +76 -0
- package/src/types/schedulers/SchedulerOptions.js +9 -0
- package/templates/scheduler.edge +8 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import type { ScheduledTask } from '#src/types';
|
|
10
|
+
import { CronBuilder } from '#src/cron/CronBuilder';
|
|
11
|
+
export declare class CronImpl {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new instance of CronBuilder to register
|
|
14
|
+
* your scheduler.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* Cron.schedule().pattern('59 * * * *')
|
|
19
|
+
* .handler((ctx) => console.log(`my cron pattern is ${ctx.pattern}`))
|
|
20
|
+
* .register()
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
schedule(): CronBuilder;
|
|
24
|
+
/**
|
|
25
|
+
* Validate if CRON pattern is correct.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const valid = Cron.validate('59 * * * *')
|
|
30
|
+
* const invalid = Cron.validate('60 * * * *')
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
validate(pattern: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Register the error handler for all tasks.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* Cron.setErrorHandler((err) => console.error(err))
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
setErrorHandler(handler: any): this;
|
|
43
|
+
/**
|
|
44
|
+
* Returns a map with all tasks that has been scheduled.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const tasks = Cron.getTasks()
|
|
49
|
+
*
|
|
50
|
+
* task.map(task => task.stop())
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
getTasks(): Map<string, ScheduledTask>;
|
|
54
|
+
/**
|
|
55
|
+
* Close all scheduled tasks.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* Cron.close()
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
close(): this;
|
|
63
|
+
/**
|
|
64
|
+
* Delete all scheduled tasks.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* Cron.truncate()
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
truncate(): this;
|
|
72
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { getTasks, validate } from 'node-cron';
|
|
10
|
+
import { CronBuilder } from '#src/cron/CronBuilder';
|
|
11
|
+
export class CronImpl {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new instance of CronBuilder to register
|
|
14
|
+
* your scheduler.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* Cron.schedule().pattern('59 * * * *')
|
|
19
|
+
* .handler((ctx) => console.log(`my cron pattern is ${ctx.pattern}`))
|
|
20
|
+
* .register()
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
schedule() {
|
|
24
|
+
return new CronBuilder();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate if CRON pattern is correct.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const valid = Cron.validate('59 * * * *')
|
|
32
|
+
* const invalid = Cron.validate('60 * * * *')
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
validate(pattern) {
|
|
36
|
+
return validate(pattern);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Register the error handler for all tasks.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* Cron.setErrorHandler((err) => console.error(err))
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
setErrorHandler(handler) {
|
|
47
|
+
CronBuilder.exceptionHandler = handler;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns a map with all tasks that has been scheduled.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const tasks = Cron.getTasks()
|
|
56
|
+
*
|
|
57
|
+
* task.map(task => task.stop())
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
getTasks() {
|
|
61
|
+
return getTasks();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Close all scheduled tasks.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* Cron.close()
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
close() {
|
|
72
|
+
for (const task of this.getTasks().values()) {
|
|
73
|
+
task.stop();
|
|
74
|
+
}
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Delete all scheduled tasks.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* Cron.truncate()
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
truncate() {
|
|
86
|
+
const tasks = this.getTasks();
|
|
87
|
+
for (const task of tasks.keys()) {
|
|
88
|
+
tasks.delete(task);
|
|
89
|
+
}
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { debuglog } from 'node:util';
|
|
10
|
+
export const debug = debuglog('athenna:cron');
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import type { CronImpl } from '#src/cron/CronImpl';
|
|
10
|
+
export declare const Cron: import("@athenna/ioc").FacadeType<CronImpl>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { Facade } from '@athenna/ioc';
|
|
10
|
+
export const Cron = Facade.createFor('Athenna/Core/Cron');
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
export declare class CronExceptionHandler {
|
|
10
|
+
/**
|
|
11
|
+
* Error codes that should be ignored from logging.
|
|
12
|
+
*/
|
|
13
|
+
get ignoreCodes(): string[];
|
|
14
|
+
/**
|
|
15
|
+
* Error statuses that should be ignored from logging.
|
|
16
|
+
*/
|
|
17
|
+
get ignoreStatuses(): number[];
|
|
18
|
+
/**
|
|
19
|
+
* The exception handler of all Artisan commands.
|
|
20
|
+
*/
|
|
21
|
+
handle(error: any): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Return a boolean indicating if the error can be logged or not.
|
|
24
|
+
*/
|
|
25
|
+
private canBeLogged;
|
|
26
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { Log } from '@athenna/logger';
|
|
10
|
+
import { Config } from '@athenna/config';
|
|
11
|
+
import { Is, String } from '@athenna/common';
|
|
12
|
+
export class CronExceptionHandler {
|
|
13
|
+
/**
|
|
14
|
+
* Error codes that should be ignored from logging.
|
|
15
|
+
*/
|
|
16
|
+
get ignoreCodes() {
|
|
17
|
+
return Config.get('cron.logger.ignoreCodes', []);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error statuses that should be ignored from logging.
|
|
21
|
+
*/
|
|
22
|
+
get ignoreStatuses() {
|
|
23
|
+
return Config.get('cron.logger.ignoreStatuses', []);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The exception handler of all Artisan commands.
|
|
27
|
+
*/
|
|
28
|
+
async handle(error) {
|
|
29
|
+
error.code = String.toSnakeCase(error.code || error.name).toUpperCase();
|
|
30
|
+
const isException = Is.Exception(error);
|
|
31
|
+
const isDebugMode = Config.get('app.debug', true);
|
|
32
|
+
const isInternalServerError = Is.Error(error) && !isException;
|
|
33
|
+
if (!isException) {
|
|
34
|
+
error = error.toAthennaException();
|
|
35
|
+
}
|
|
36
|
+
if (isInternalServerError && !isDebugMode) {
|
|
37
|
+
error.name = 'Internal error';
|
|
38
|
+
error.code = 'E_INTERNAL_ERROR';
|
|
39
|
+
error.message = 'An internal error has occurred.';
|
|
40
|
+
delete error.stack;
|
|
41
|
+
}
|
|
42
|
+
if (!this.canBeLogged(error)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
Log.channelOrVanilla('exception').error(await error.prettify());
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Return a boolean indicating if the error can be logged or not.
|
|
49
|
+
*/
|
|
50
|
+
canBeLogged(error) {
|
|
51
|
+
if (this.ignoreCodes.includes(error.code)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (this.ignoreStatuses.includes(error.status || error.statusCode)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
export * from '#src/types';
|
|
10
|
+
export * from '#src/cron/CronImpl';
|
|
11
|
+
export * from '#src/cron/CronBuilder';
|
|
12
|
+
export * from '#src/facades/Cron';
|
|
13
|
+
export * from '#src/annotations/Scheduler';
|
|
14
|
+
export * from '#src/kernels/CronKernel';
|
|
15
|
+
export * from '#src/handlers/CronExceptionHandler';
|
|
16
|
+
export * from '#src/providers/CronProvider';
|
package/src/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
export * from '#src/types';
|
|
10
|
+
export * from '#src/cron/CronImpl';
|
|
11
|
+
export * from '#src/cron/CronBuilder';
|
|
12
|
+
export * from '#src/facades/Cron';
|
|
13
|
+
export * from '#src/annotations/Scheduler';
|
|
14
|
+
export * from '#src/kernels/CronKernel';
|
|
15
|
+
export * from '#src/handlers/CronExceptionHandler';
|
|
16
|
+
export * from '#src/providers/CronProvider';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare class CronKernel {
|
|
2
|
+
/**
|
|
3
|
+
* Register the cls-rtracer plugin in the Cron.
|
|
4
|
+
*/
|
|
5
|
+
registerRTracer(trace?: boolean): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Register the exception handler for all Cron tasks.
|
|
8
|
+
*/
|
|
9
|
+
registerExceptionHandler(path?: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Register all the schedulers found inside "rc.schedulers" config
|
|
12
|
+
* inside the service provider.
|
|
13
|
+
*/
|
|
14
|
+
registerSchedulers(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Register the route file by importing the file.
|
|
17
|
+
*/
|
|
18
|
+
registerRoutes(path: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Register the schedulers using the meta information
|
|
21
|
+
* defined by annotations.
|
|
22
|
+
*/
|
|
23
|
+
private registerUsingMeta;
|
|
24
|
+
/**
|
|
25
|
+
* Get the parent URL of the project.
|
|
26
|
+
*/
|
|
27
|
+
private getParentURL;
|
|
28
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { sep } from 'node:path';
|
|
2
|
+
import { debug } from '#src/debug';
|
|
3
|
+
import { Cron } from '#src/facades/Cron';
|
|
4
|
+
import { CronBuilder } from '#src/cron/CronBuilder';
|
|
5
|
+
import { Exec, Module, Path } from '@athenna/common';
|
|
6
|
+
import { Annotation } from '@athenna/ioc';
|
|
7
|
+
import { CronExceptionHandler } from '#src/handlers/CronExceptionHandler';
|
|
8
|
+
const rTracerPlugin = await Module.safeImport('cls-rtracer');
|
|
9
|
+
export class CronKernel {
|
|
10
|
+
/**
|
|
11
|
+
* Register the cls-rtracer plugin in the Cron.
|
|
12
|
+
*/
|
|
13
|
+
async registerRTracer(trace) {
|
|
14
|
+
if (trace === false) {
|
|
15
|
+
debug('Not able to register rTracer plugin. Set the trace option as true in your cron options.');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (trace === undefined && Config.is('cron.rTracer.enabled', false)) {
|
|
19
|
+
debug('Not able to register rTracer plugin. Set the cron.rTracer.enabled configuration as true.');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!rTracerPlugin) {
|
|
23
|
+
debug('Not able to register tracer plugin. Install cls-rtracer package.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
CronBuilder.registerRTracer(rTracerPlugin);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Register the exception handler for all Cron tasks.
|
|
30
|
+
*/
|
|
31
|
+
async registerExceptionHandler(path) {
|
|
32
|
+
if (!path) {
|
|
33
|
+
CronBuilder.exceptionHandler = new CronExceptionHandler();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const Handler = await Module.resolve(path, this.getParentURL());
|
|
37
|
+
CronBuilder.exceptionHandler = new Handler();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Register all the schedulers found inside "rc.schedulers" config
|
|
41
|
+
* inside the service provider.
|
|
42
|
+
*/
|
|
43
|
+
async registerSchedulers() {
|
|
44
|
+
const schedulers = Config.get('rc.schedulers', []);
|
|
45
|
+
await Exec.concurrently(schedulers, async (path) => {
|
|
46
|
+
const Scheduler = await Module.resolve(path, this.getParentURL());
|
|
47
|
+
if (Annotation.isAnnotated(Scheduler)) {
|
|
48
|
+
this.registerUsingMeta(Scheduler);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
ioc.transient(`App/Cron/Schedulers/${Scheduler.name}`, Scheduler);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Register the route file by importing the file.
|
|
56
|
+
*/
|
|
57
|
+
async registerRoutes(path) {
|
|
58
|
+
await Module.resolve(path, this.getParentURL());
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Register the schedulers using the meta information
|
|
62
|
+
* defined by annotations.
|
|
63
|
+
*/
|
|
64
|
+
registerUsingMeta(target) {
|
|
65
|
+
const meta = Annotation.getMeta(target);
|
|
66
|
+
const builder = Cron.schedule();
|
|
67
|
+
ioc[meta.type](meta.alias, target);
|
|
68
|
+
if (meta.name) {
|
|
69
|
+
builder.name(meta.name);
|
|
70
|
+
ioc.alias(meta.name, meta.alias);
|
|
71
|
+
}
|
|
72
|
+
if (meta.camelAlias) {
|
|
73
|
+
ioc.alias(meta.camelAlias, meta.alias);
|
|
74
|
+
}
|
|
75
|
+
builder
|
|
76
|
+
.pattern(meta.pattern)
|
|
77
|
+
.timezone(meta.timezone)
|
|
78
|
+
.scheduled(meta.scheduled)
|
|
79
|
+
.runOnInit(meta.runOnInit)
|
|
80
|
+
.recoverMissedExecutions(meta.recoverMissedExecutions)
|
|
81
|
+
.handler(ctx => {
|
|
82
|
+
const scheduler = ioc.use(meta.name) ||
|
|
83
|
+
ioc.use(meta.camelAlias) ||
|
|
84
|
+
ioc.safeUse(meta.alias);
|
|
85
|
+
return scheduler.handler(ctx);
|
|
86
|
+
});
|
|
87
|
+
return meta;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get the parent URL of the project.
|
|
91
|
+
*/
|
|
92
|
+
getParentURL() {
|
|
93
|
+
return Config.get('rc.parentURL', Path.toHref(Path.pwd() + sep));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { ServiceProvider } from '@athenna/ioc';
|
|
10
|
+
export declare class CronProvider extends ServiceProvider {
|
|
11
|
+
register(): void;
|
|
12
|
+
shutdown(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { CronImpl } from '#src/cron/CronImpl';
|
|
10
|
+
import { ServiceProvider } from '@athenna/ioc';
|
|
11
|
+
export class CronProvider extends ServiceProvider {
|
|
12
|
+
register() {
|
|
13
|
+
this.container.instance('Athenna/Core/Cron', new CronImpl());
|
|
14
|
+
}
|
|
15
|
+
async shutdown() {
|
|
16
|
+
const Cron = this.container.use('Athenna/Core/Cron');
|
|
17
|
+
if (!Cron) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
Cron.close().truncate();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
export interface Context {
|
|
10
|
+
name?: string;
|
|
11
|
+
traceId?: string;
|
|
12
|
+
pattern?: string;
|
|
13
|
+
timezone?: string;
|
|
14
|
+
runOnInit?: boolean;
|
|
15
|
+
recoverMissedExecutions?: boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import type { Context } from '#src/types/Context';
|
|
10
|
+
export type CronHandler = (ctx?: Context) => any | Promise<any>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import type { ScheduledTask as NodeCronScheduledTask } from 'node-cron';
|
|
10
|
+
export type ScheduledTask = NodeCronScheduledTask & {
|
|
11
|
+
options: {
|
|
12
|
+
name?: string;
|
|
13
|
+
timezone?: string;
|
|
14
|
+
runOnInit?: boolean;
|
|
15
|
+
scheduled?: boolean;
|
|
16
|
+
recoverMissedExecutions?: boolean;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
export * from '#src/types/Context';
|
|
10
|
+
export * from '#src/types/CronHandler';
|
|
11
|
+
export * from '#src/types/ScheduledTask';
|
|
12
|
+
export * from '#src/types/schedulers/SchedulerOptions';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
export * from '#src/types/Context';
|
|
10
|
+
export * from '#src/types/CronHandler';
|
|
11
|
+
export * from '#src/types/ScheduledTask';
|
|
12
|
+
export * from '#src/types/schedulers/SchedulerOptions';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @athenna/cron
|
|
3
|
+
*
|
|
4
|
+
* (c) João Lenon <lenon@athenna.io>
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
export type SchedulerOptions = {
|
|
10
|
+
/**
|
|
11
|
+
* The CRON expression that will determined when the scheduler
|
|
12
|
+
* will run.
|
|
13
|
+
*
|
|
14
|
+
* @example '* * * * *'
|
|
15
|
+
*/
|
|
16
|
+
pattern: string;
|
|
17
|
+
/**
|
|
18
|
+
* The timezone that the CRON expression needs to respect when
|
|
19
|
+
* running the scheduler.
|
|
20
|
+
*/
|
|
21
|
+
timezone?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Defines if the scheduler should run when initiating the application,
|
|
24
|
+
* not matter the CRON expression, it will always run on boot.
|
|
25
|
+
*
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
runOnInit?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Defines if the scheduler should already be registered when booting
|
|
31
|
+
* the application. This option is not like `runOnInit`, if you set it
|
|
32
|
+
* as `false`, it will basically register your CRON but disabled, meaning
|
|
33
|
+
* you need to manually start it using `Cron` facade.
|
|
34
|
+
*
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
scheduled?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* If this option is `true`, when the main thread froze for any reason,
|
|
40
|
+
* the elapsed time since last execution will be considered an all the
|
|
41
|
+
* missed executions will be triggered.
|
|
42
|
+
*
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
recoverMissedExecutions?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* The name that will be used to register the scheduler node-cron
|
|
48
|
+
* and also inside the service container as an alias.
|
|
49
|
+
*
|
|
50
|
+
* @default YourSchedulerClassName
|
|
51
|
+
*/
|
|
52
|
+
name?: string;
|
|
53
|
+
/**
|
|
54
|
+
* The alias that will be used to register the scheduler inside
|
|
55
|
+
* the service container.
|
|
56
|
+
*
|
|
57
|
+
* @default App/Cron/Schedulers/YourSchedulerClassName
|
|
58
|
+
*/
|
|
59
|
+
alias?: string;
|
|
60
|
+
/**
|
|
61
|
+
* The camel alias that will be used as an alias of the real
|
|
62
|
+
* scheduler alias. Camel alias is important when you want to
|
|
63
|
+
* work with constructor injection. By default, Athenna doesn't
|
|
64
|
+
* create camel alias for schedulers.
|
|
65
|
+
*
|
|
66
|
+
* @default undefined
|
|
67
|
+
*/
|
|
68
|
+
camelAlias?: string;
|
|
69
|
+
/**
|
|
70
|
+
* The registration type that will be used to register your scheduler
|
|
71
|
+
* inside the service container.
|
|
72
|
+
*
|
|
73
|
+
* @default 'transient'
|
|
74
|
+
*/
|
|
75
|
+
type?: 'fake' | 'scoped' | 'singleton' | 'transient';
|
|
76
|
+
};
|