@orion-js/dogs 4.3.5 → 4.4.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 +21 -0
- package/dist/defineJob/index.d.ts +10 -0
- package/dist/index.cjs +33 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -442
- package/dist/index.js +33 -21
- package/dist/index.js.map +1 -1
- package/dist/repos/JobsHistoryRepo.d.ts +7 -0
- package/dist/repos/JobsRepo.d.ts +32 -0
- package/dist/service/index.d.ts +9 -0
- package/dist/services/EventsService.d.ts +6 -0
- package/dist/services/Executor.d.ts +43 -0
- package/dist/services/WorkerService.d.ts +26 -0
- package/dist/services/getNextRunDate.d.ts +12 -0
- package/dist/types/Events.d.ts +63 -0
- package/dist/types/HistoryRecord.d.ts +58 -0
- package/dist/types/JobRecord.d.ts +53 -0
- package/dist/types/JobsDefinition.d.ts +133 -0
- package/dist/types/StartConfig.d.ts +41 -0
- package/dist/types/Worker.d.ts +41 -0
- package/dist/types/index.d.ts +6 -0
- package/package.json +18 -19
- package/dist/index.d.cts +0 -453
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { InferSchemaType } from '@orion-js/schema';
|
|
2
|
+
/**
|
|
3
|
+
* Enum representing the status of a job record.
|
|
4
|
+
* - 'pending': Job is active and can be executed (default for existing records)
|
|
5
|
+
* - 'maxTriesReached': Event job has exhausted all retry attempts and won't be executed
|
|
6
|
+
*/
|
|
7
|
+
export declare const JobStatusEnum: import("@orion-js/schema").FieldType<"maxTriesReached" | "pending">;
|
|
8
|
+
export declare const JobRecordSchema: {
|
|
9
|
+
_id: {
|
|
10
|
+
type: "string";
|
|
11
|
+
};
|
|
12
|
+
jobName: {
|
|
13
|
+
type: "string";
|
|
14
|
+
};
|
|
15
|
+
type: {
|
|
16
|
+
type: import("@orion-js/schema").FieldType<"event" | "recurrent">;
|
|
17
|
+
};
|
|
18
|
+
priority: {
|
|
19
|
+
type: "number";
|
|
20
|
+
};
|
|
21
|
+
uniqueIdentifier: {
|
|
22
|
+
type: "string";
|
|
23
|
+
optional: true;
|
|
24
|
+
};
|
|
25
|
+
nextRunAt: {
|
|
26
|
+
type: "date";
|
|
27
|
+
};
|
|
28
|
+
lastRunAt: {
|
|
29
|
+
type: "date";
|
|
30
|
+
optional: true;
|
|
31
|
+
};
|
|
32
|
+
lockedUntil: {
|
|
33
|
+
type: "date";
|
|
34
|
+
optional: true;
|
|
35
|
+
};
|
|
36
|
+
tries: {
|
|
37
|
+
type: "number";
|
|
38
|
+
optional: true;
|
|
39
|
+
};
|
|
40
|
+
params: {
|
|
41
|
+
type: "blackbox";
|
|
42
|
+
optional: true;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Status of the job. Optional for backwards compatibility with existing records.
|
|
46
|
+
* Records without this field are treated as 'pending'.
|
|
47
|
+
*/
|
|
48
|
+
status: {
|
|
49
|
+
type: import("@orion-js/schema").FieldType<"maxTriesReached" | "pending">;
|
|
50
|
+
optional: true;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export type JobRecord = InferSchemaType<typeof JobRecordSchema>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Blackbox, InferSchemaType, SchemaInAnyOrionForm } from '@orion-js/schema';
|
|
2
|
+
import { ScheduleJobOptionsWithoutName, ScheduleJobsResult } from './Events';
|
|
3
|
+
import { ExecutionContext } from './Worker';
|
|
4
|
+
export interface JobRetryResultBase {
|
|
5
|
+
action: 'retry' | 'dismiss';
|
|
6
|
+
}
|
|
7
|
+
export type JobRetryResultRunIn = JobRetryResultBase & {
|
|
8
|
+
runIn: number;
|
|
9
|
+
};
|
|
10
|
+
export type JobRetryResultRunAt = JobRetryResultBase & {
|
|
11
|
+
runAt: Date;
|
|
12
|
+
};
|
|
13
|
+
export type JobRetryResult = JobRetryResultRunIn | JobRetryResultRunAt | JobRetryResultBase;
|
|
14
|
+
export interface BaseJobDefinition {
|
|
15
|
+
/**
|
|
16
|
+
* Called if the job fails.
|
|
17
|
+
*/
|
|
18
|
+
onError?: (error: Error, params: Blackbox, context: ExecutionContext) => Promise<JobRetryResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Called if the job locktime is expired. The job will be executed again.
|
|
21
|
+
*/
|
|
22
|
+
onStale?: (params: Blackbox, context: ExecutionContext) => Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Save the executions of the job time in milliseconds. Default is 1 week. Set to 0 to disable.
|
|
25
|
+
*/
|
|
26
|
+
saveExecutionsFor?: number;
|
|
27
|
+
/**
|
|
28
|
+
* The name of the job.
|
|
29
|
+
* This is set automatically when the job is passed to startWorkers.
|
|
30
|
+
*/
|
|
31
|
+
jobName?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Time in milliseconds to lock this specific job for execution.
|
|
34
|
+
* Overrides the defaultLockTime set in startWorkers config.
|
|
35
|
+
* If not set, the defaultLockTime from config will be used.
|
|
36
|
+
*/
|
|
37
|
+
lockTime?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface RecurrentJobDefinition extends BaseJobDefinition {
|
|
40
|
+
/**
|
|
41
|
+
* Type of the job.
|
|
42
|
+
*/
|
|
43
|
+
type: 'recurrent';
|
|
44
|
+
/**
|
|
45
|
+
* A function executed after each execution that returns the date of the next run.
|
|
46
|
+
*/
|
|
47
|
+
getNextRun?: () => Date;
|
|
48
|
+
/**
|
|
49
|
+
* Run every x milliseconds. This will be ignored if getNextRun is defined.
|
|
50
|
+
*/
|
|
51
|
+
runEvery?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Cron expression used to calculate the next run. Requires timezone.
|
|
54
|
+
*/
|
|
55
|
+
cron?: string;
|
|
56
|
+
/**
|
|
57
|
+
* IANA timezone used to calculate cron-based schedules.
|
|
58
|
+
*/
|
|
59
|
+
timezone?: string;
|
|
60
|
+
/**
|
|
61
|
+
* The priority of the job. Higher is more priority. Default is 100.
|
|
62
|
+
*/
|
|
63
|
+
priority?: number;
|
|
64
|
+
/**
|
|
65
|
+
* The function to execute when the job is executed.
|
|
66
|
+
*/
|
|
67
|
+
resolve: (_: any, context: ExecutionContext) => Promise<Blackbox | void>;
|
|
68
|
+
}
|
|
69
|
+
export interface EventJobDefinition<TParamsSchema extends SchemaInAnyOrionForm = any> extends BaseJobDefinition {
|
|
70
|
+
/**
|
|
71
|
+
* Type of the job.
|
|
72
|
+
*/
|
|
73
|
+
type: 'event';
|
|
74
|
+
/**
|
|
75
|
+
* Maximum number of tries for this specific event job before it is marked as 'maxTriesReached'.
|
|
76
|
+
* Overrides the global maxTries set in startWorkers config.
|
|
77
|
+
* If not set, the global maxTries from config will be used.
|
|
78
|
+
*/
|
|
79
|
+
maxTries?: number;
|
|
80
|
+
/**
|
|
81
|
+
* Schedule of the job. Supports optional runIn (milliseconds) or runAt (Date) for delayed execution.
|
|
82
|
+
*/
|
|
83
|
+
schedule: (options: ScheduleJobOptionsWithoutName<TParamsSchema>) => Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Schedule multiple jobs at once. Each job supports optional runIn or runAt for delayed execution.
|
|
86
|
+
*/
|
|
87
|
+
scheduleJobs: (jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>) => Promise<ScheduleJobsResult>;
|
|
88
|
+
/**
|
|
89
|
+
* The schema of the params of the job.
|
|
90
|
+
*/
|
|
91
|
+
params?: TParamsSchema;
|
|
92
|
+
/**
|
|
93
|
+
* Maximum number of executions of this job that can run in parallel on the same server.
|
|
94
|
+
* If not set, the job can use all available workers on the current server.
|
|
95
|
+
*/
|
|
96
|
+
maxParallelExecutionsPerServer?: number;
|
|
97
|
+
/**
|
|
98
|
+
* The function to execute when the job is executed.
|
|
99
|
+
*/
|
|
100
|
+
resolve: (params: InferSchemaType<TParamsSchema>, context: ExecutionContext) => Promise<any>;
|
|
101
|
+
}
|
|
102
|
+
export type CreateEventJobOptions<TParamsSchema extends SchemaInAnyOrionForm = any> = Omit<EventJobDefinition<TParamsSchema>, 'type' | 'schedule' | 'scheduleJobs'>;
|
|
103
|
+
type CreateRecurrentJobBaseOptions = Omit<RecurrentJobDefinition, 'type' | 'runEvery' | 'cron' | 'timezone'>;
|
|
104
|
+
export type CreateRecurrentJobRunEveryOptions = CreateRecurrentJobBaseOptions & {
|
|
105
|
+
/**
|
|
106
|
+
* Run every x milliseconds.
|
|
107
|
+
* Accepts https://github.com/jkroso/parse-duration strings.
|
|
108
|
+
*/
|
|
109
|
+
runEvery: number | string;
|
|
110
|
+
cron?: never;
|
|
111
|
+
timezone?: string;
|
|
112
|
+
};
|
|
113
|
+
export type CreateRecurrentJobCronOptions = CreateRecurrentJobBaseOptions & {
|
|
114
|
+
/**
|
|
115
|
+
* Cron expression used to calculate the next run.
|
|
116
|
+
*/
|
|
117
|
+
cron: string;
|
|
118
|
+
/**
|
|
119
|
+
* IANA timezone used to calculate cron-based schedules.
|
|
120
|
+
*/
|
|
121
|
+
timezone: string;
|
|
122
|
+
runEvery?: never;
|
|
123
|
+
};
|
|
124
|
+
export type CreateRecurrentJobOptions = CreateRecurrentJobRunEveryOptions | CreateRecurrentJobCronOptions;
|
|
125
|
+
export type CreateJobOptions<TParamsSchema extends SchemaInAnyOrionForm = any> = CreateEventJobOptions<TParamsSchema> | CreateRecurrentJobOptions;
|
|
126
|
+
export type JobDefinition<TParamsSchema extends SchemaInAnyOrionForm = any> = RecurrentJobDefinition | EventJobDefinition<TParamsSchema>;
|
|
127
|
+
export type JobDefinitionWithName<TParamsSchema extends SchemaInAnyOrionForm = any> = JobDefinition<TParamsSchema> & {
|
|
128
|
+
name: string;
|
|
129
|
+
};
|
|
130
|
+
export interface JobsDefinition {
|
|
131
|
+
[jobName: string]: JobDefinition;
|
|
132
|
+
}
|
|
133
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { JobsDefinition } from './JobsDefinition';
|
|
2
|
+
import { JobToRun } from './Worker';
|
|
3
|
+
export type LogLevels = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
4
|
+
export interface StartWorkersConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Object map of the jobs that this workers will execute
|
|
7
|
+
*/
|
|
8
|
+
jobs: JobsDefinition;
|
|
9
|
+
/**
|
|
10
|
+
* Maximum number of tries for an event job before it is marked as 'maxTriesReached'.
|
|
11
|
+
* This is a global default that can be overridden per event job definition.
|
|
12
|
+
*/
|
|
13
|
+
maxTries?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Callback invoked when an event job reaches its maximum tries limit.
|
|
16
|
+
* Use this to notify administrators (e.g., send an email alert).
|
|
17
|
+
* The job will remain in the database with status 'maxTriesReached'.
|
|
18
|
+
*/
|
|
19
|
+
onMaxTriesReached?: (job: JobToRun) => Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Time in milliseconds to wait between each look without results for a job
|
|
22
|
+
* to run at the database. Default is 3000.
|
|
23
|
+
*/
|
|
24
|
+
pollInterval?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Time in milliseconds to wait too look for a job after a job execution. Default is 100.
|
|
27
|
+
*/
|
|
28
|
+
cooldownPeriod?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Number of workers to start. Default is 1.
|
|
31
|
+
*/
|
|
32
|
+
workersCount?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Default time in milliseconds to lock a job for execution. Default is 30000 (30 seconds).
|
|
35
|
+
* If a job is locked for longer than this time, it will be considered as failed.
|
|
36
|
+
* This is to prevent a job from being executed multiple times at the same time.
|
|
37
|
+
* You can extend this time inside a job by calling extendLockTime from context.
|
|
38
|
+
* Individual jobs can override this value by setting their own lockTime.
|
|
39
|
+
*/
|
|
40
|
+
defaultLockTime?: number;
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { OrionLogger } from '@orion-js/logger';
|
|
2
|
+
import { Blackbox } from '@orion-js/schema';
|
|
3
|
+
import { JobDefinition } from './JobsDefinition';
|
|
4
|
+
export interface JobToRun {
|
|
5
|
+
jobId: string;
|
|
6
|
+
executionId: string;
|
|
7
|
+
name: string;
|
|
8
|
+
type: 'event' | 'recurrent';
|
|
9
|
+
params: Blackbox;
|
|
10
|
+
tries: number;
|
|
11
|
+
lockTime: number;
|
|
12
|
+
priority: number;
|
|
13
|
+
uniqueIdentifier?: string;
|
|
14
|
+
wasStale?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface ExecutionContext {
|
|
17
|
+
record: JobToRun;
|
|
18
|
+
definition: JobDefinition;
|
|
19
|
+
tries: number;
|
|
20
|
+
logger: OrionLogger;
|
|
21
|
+
extendLockTime: (extraTime: number) => Promise<void>;
|
|
22
|
+
clearStaleTimeout: () => void;
|
|
23
|
+
}
|
|
24
|
+
export interface WorkerInstance {
|
|
25
|
+
running: boolean;
|
|
26
|
+
workerIndex: number;
|
|
27
|
+
stop: () => Promise<void>;
|
|
28
|
+
respawn: () => Promise<void>;
|
|
29
|
+
promise?: Promise<any>;
|
|
30
|
+
}
|
|
31
|
+
export interface WorkersInstance {
|
|
32
|
+
running: boolean;
|
|
33
|
+
workersCount: number;
|
|
34
|
+
workers: WorkerInstance[];
|
|
35
|
+
runningJobsByName: Map<string, number>;
|
|
36
|
+
jobAcquisitionLock: Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Stop all workers and wait for them to finish
|
|
39
|
+
*/
|
|
40
|
+
stop: () => Promise<void>;
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-js/dogs",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -15,37 +15,36 @@
|
|
|
15
15
|
],
|
|
16
16
|
"author": "nicolaslopezj",
|
|
17
17
|
"license": "MIT",
|
|
18
|
-
"scripts": {
|
|
19
|
-
"test": "bun test",
|
|
20
|
-
"prepare": "bun run build",
|
|
21
|
-
"clean": "rm -rf ./dist",
|
|
22
|
-
"build": "tsup",
|
|
23
|
-
"dev": "tsup --watch"
|
|
24
|
-
},
|
|
25
18
|
"dependencies": {
|
|
26
19
|
"@opentelemetry/api": "^1.9.0",
|
|
27
|
-
"@orion-js/helpers": "4.
|
|
28
|
-
"@orion-js/schema": "4.
|
|
29
|
-
"@orion-js/services": "4.
|
|
30
|
-
"@orion-js/typed-model": "4.
|
|
20
|
+
"@orion-js/helpers": "4.4.0",
|
|
21
|
+
"@orion-js/schema": "4.4.0",
|
|
22
|
+
"@orion-js/services": "4.4.0",
|
|
23
|
+
"@orion-js/typed-model": "4.4.0",
|
|
31
24
|
"cron-parser": "^5.5.0",
|
|
32
25
|
"dataloader": "2.2.2",
|
|
33
26
|
"dot-object": "^2.1.5",
|
|
34
27
|
"parse-duration": "^2.1.3"
|
|
35
28
|
},
|
|
36
29
|
"peerDependencies": {
|
|
37
|
-
"@orion-js/logger": "4.
|
|
38
|
-
"@orion-js/mongodb": "4.
|
|
30
|
+
"@orion-js/logger": "4.4.0",
|
|
31
|
+
"@orion-js/mongodb": "4.4.0"
|
|
39
32
|
},
|
|
40
33
|
"devDependencies": {
|
|
41
|
-
"@orion-js/logger": "4.
|
|
42
|
-
"@orion-js/mongodb": "4.
|
|
34
|
+
"@orion-js/logger": "4.4.0",
|
|
35
|
+
"@orion-js/mongodb": "4.4.0",
|
|
43
36
|
"mongodb-memory-server": "^10.1.4",
|
|
44
37
|
"tsup": "^8.0.1",
|
|
45
|
-
"typescript": "^
|
|
38
|
+
"typescript": "^7.0.2"
|
|
46
39
|
},
|
|
47
40
|
"publishConfig": {
|
|
48
41
|
"access": "public"
|
|
49
42
|
},
|
|
50
|
-
"gitHead": "2d14bc085d49a33b2a5566bec1caf60c7d0f897e"
|
|
51
|
-
|
|
43
|
+
"gitHead": "2d14bc085d49a33b2a5566bec1caf60c7d0f897e",
|
|
44
|
+
"scripts": {
|
|
45
|
+
"test": "bun test",
|
|
46
|
+
"clean": "rm -rf ./dist",
|
|
47
|
+
"build": "tsup && bun run ../../scripts/emit-declarations.ts",
|
|
48
|
+
"dev": "tsup --watch"
|
|
49
|
+
}
|
|
50
|
+
}
|