@clairejs/server 3.23.1 → 3.23.3
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 +3 -1
- package/dist/job/AbstractJobRepository.d.ts +9 -4
- package/dist/job/AbstractJobScheduler.d.ts +4 -4
- package/dist/job/AbstractJobScheduler.js +20 -17
- package/dist/job/AwsJobScheduler.js +4 -4
- package/dist/job/LocalJobScheduler.js +9 -5
- package/dist/job/default-job-repo.d.ts +4 -3
- package/dist/job/default-job-repo.js +12 -15
- package/dist/job/interfaces.d.ts +2 -2
- package/dist/job/job.d.ts +0 -1
- package/dist/job/job.js +0 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,14 +10,19 @@ export declare abstract class AbstractJobRepository<T extends AbstractJob = Abst
|
|
|
10
10
|
* @param jobInfo The job info to save
|
|
11
11
|
*/
|
|
12
12
|
abstract insertJob(jobInfo: Partial<T>, tx?: ITransaction): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Return the job by its unique id
|
|
15
|
+
* @param id The unique job id
|
|
16
|
+
*/
|
|
17
|
+
abstract getJobById(id: string): Promise<AbstractJob | undefined>;
|
|
13
18
|
/**
|
|
14
19
|
* Remove job info by id
|
|
15
|
-
* @param
|
|
20
|
+
* @param id Unique id of job
|
|
16
21
|
*/
|
|
17
|
-
abstract removeJobById(
|
|
22
|
+
abstract removeJobById(id: string, tx?: ITransaction): Promise<void>;
|
|
18
23
|
/**
|
|
19
24
|
* Remove job info by id
|
|
20
|
-
* @param
|
|
25
|
+
* @param id Unique id of job
|
|
21
26
|
*/
|
|
22
|
-
abstract updateJobById(
|
|
27
|
+
abstract updateJobById(id: string, update: Partial<Omit<T, "id">>, tx?: ITransaction): Promise<void>;
|
|
23
28
|
}
|
|
@@ -22,17 +22,17 @@ export declare abstract class AbstractJobScheduler {
|
|
|
22
22
|
* @param payload the necessary info to launch the job
|
|
23
23
|
*/
|
|
24
24
|
protected abstract _scheduleJob(payload: JobSchedulePayload): Promise<void>;
|
|
25
|
-
scheduleJob({
|
|
25
|
+
scheduleJob({ id, ...payload }: JobSchedulePayload): Promise<string>;
|
|
26
26
|
/**
|
|
27
27
|
* Cancel the scheduled job and prevent if from running in the future
|
|
28
28
|
* @param id The job id returned from scheduleJobAt function
|
|
29
29
|
*/
|
|
30
|
-
protected abstract cancelJob(
|
|
30
|
+
protected abstract cancelJob(id: string): Promise<void>;
|
|
31
31
|
/**
|
|
32
32
|
* Remove the scheduled job and prevent if from running in the future
|
|
33
|
-
* @param
|
|
33
|
+
* @param id The job id returned from scheduleJobAt function
|
|
34
34
|
*/
|
|
35
|
-
disableJob(
|
|
35
|
+
disableJob(id: string, tx?: ITransaction): Promise<void>;
|
|
36
36
|
/**
|
|
37
37
|
* Execute the scheduled job
|
|
38
38
|
* @param job The schedled job info to execute
|
|
@@ -22,35 +22,38 @@ export class AbstractJobScheduler {
|
|
|
22
22
|
}
|
|
23
23
|
return this._jobs;
|
|
24
24
|
}
|
|
25
|
-
async scheduleJob({
|
|
26
|
-
let
|
|
25
|
+
async scheduleJob({ id, ...payload }) {
|
|
26
|
+
let jobId = id;
|
|
27
27
|
const tx = await this.db.createTransaction();
|
|
28
|
-
if (!
|
|
29
|
-
|
|
28
|
+
if (!jobId && !payload.cron) {
|
|
29
|
+
jobId = await this.jobRepo.insertJob(payload, tx);
|
|
30
30
|
}
|
|
31
31
|
else {
|
|
32
|
-
const
|
|
32
|
+
const job = jobId
|
|
33
|
+
? await this.jobRepo.getJobById(jobId)
|
|
34
|
+
: await this.jobRepo.getJobs({ _eq: { jobName: payload.cron } }, { limit: 1 }).then((jobs) => jobs[0]);
|
|
33
35
|
if (!job) {
|
|
34
|
-
await this.jobRepo.insertJob(
|
|
36
|
+
jobId = await this.jobRepo.insertJob(payload, tx);
|
|
35
37
|
}
|
|
36
38
|
else {
|
|
39
|
+
jobId = job.id;
|
|
37
40
|
const diff = diffData(job, payload);
|
|
38
41
|
if (diff) {
|
|
39
|
-
await this.jobRepo.updateJobById(
|
|
42
|
+
await this.jobRepo.updateJobById(job.id, payload, tx);
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
|
-
await this._scheduleJob({ ...payload,
|
|
46
|
+
await this._scheduleJob({ ...payload, id: jobId });
|
|
44
47
|
await tx.commit();
|
|
45
|
-
return
|
|
48
|
+
return jobId;
|
|
46
49
|
}
|
|
47
50
|
/**
|
|
48
51
|
* Remove the scheduled job and prevent if from running in the future
|
|
49
|
-
* @param
|
|
52
|
+
* @param id The job id returned from scheduleJobAt function
|
|
50
53
|
*/
|
|
51
|
-
async disableJob(
|
|
52
|
-
await this.cancelJob(
|
|
53
|
-
await this.jobRepo.updateJobById(
|
|
54
|
+
async disableJob(id, tx) {
|
|
55
|
+
await this.cancelJob(id);
|
|
56
|
+
await this.jobRepo.updateJobById(id, { disabled: true }, tx);
|
|
54
57
|
}
|
|
55
58
|
/**
|
|
56
59
|
* Execute the scheduled job
|
|
@@ -65,8 +68,8 @@ export class AbstractJobScheduler {
|
|
|
65
68
|
const jobHandler = allHandlers.find((j) => j.jobName === job.jobName);
|
|
66
69
|
const tx = await this.db.createTransaction();
|
|
67
70
|
if (!jobHandler) {
|
|
68
|
-
this.logger.info(`Disable job with id: ${job.
|
|
69
|
-
await this.disableJob(job.
|
|
71
|
+
this.logger.info(`Disable job with id: ${job.id} as handler is not found`);
|
|
72
|
+
await this.disableJob(job.id || job.id, tx);
|
|
70
73
|
}
|
|
71
74
|
else {
|
|
72
75
|
const update = {
|
|
@@ -104,12 +107,12 @@ export class AbstractJobScheduler {
|
|
|
104
107
|
}
|
|
105
108
|
else {
|
|
106
109
|
update.disabled = true;
|
|
107
|
-
await this.cancelJob(job.
|
|
110
|
+
await this.cancelJob(job.id);
|
|
108
111
|
}
|
|
109
112
|
}
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
|
-
await this.jobRepo.updateJobById(job.
|
|
115
|
+
await this.jobRepo.updateJobById(job.id, update, tx);
|
|
113
116
|
}
|
|
114
117
|
await tx.commit();
|
|
115
118
|
}
|
|
@@ -77,7 +77,7 @@ let AwsJobScheduler = class AwsJobScheduler extends AbstractJobScheduler {
|
|
|
77
77
|
async _scheduleJob(jobInfo) {
|
|
78
78
|
this.logger.debug("Scheduling job: ", jobInfo);
|
|
79
79
|
if (jobInfo.cron || jobInfo.at) {
|
|
80
|
-
const jobId = `${this.jobNamespace}${jobInfo.
|
|
80
|
+
const jobId = `${this.jobNamespace}${jobInfo.id}`;
|
|
81
81
|
let cronExpression;
|
|
82
82
|
if (jobInfo.at) {
|
|
83
83
|
cronExpression = this.generateCronFromTimestamp(jobInfo.at);
|
|
@@ -132,8 +132,8 @@ let AwsJobScheduler = class AwsJobScheduler extends AbstractJobScheduler {
|
|
|
132
132
|
//-- remove job that no more exist
|
|
133
133
|
const nomoreExistJobs = scheduledJobs.filter((job) => !allHandlers.find((handler) => handler.jobName === job.jobName));
|
|
134
134
|
for (const job of nomoreExistJobs) {
|
|
135
|
-
this.logger.info(`Removing stale job: ${job.jobName} of id: ${job.
|
|
136
|
-
await this.disableJob(job.
|
|
135
|
+
this.logger.info(`Removing stale job: ${job.jobName} of id: ${job.id}`);
|
|
136
|
+
await this.disableJob(job.id);
|
|
137
137
|
}
|
|
138
138
|
if (nomoreExistJobs.length) {
|
|
139
139
|
this.logger.info(`Cleaned up: ${nomoreExistJobs.length} stale jobs`);
|
|
@@ -143,7 +143,7 @@ let AwsJobScheduler = class AwsJobScheduler extends AbstractJobScheduler {
|
|
|
143
143
|
const scheduledCronJobs = scheduledJobs.filter((j) => j.cron);
|
|
144
144
|
const unmatchedCronJobs = scheduledCronJobs.filter((j) => j.cron && !allHandlers.find((job) => job.jobName === j.jobName && job.cron === j.cron));
|
|
145
145
|
if (unmatchedCronJobs.length) {
|
|
146
|
-
await Promise.all(unmatchedCronJobs.map((j) => this.disableJob(j.
|
|
146
|
+
await Promise.all(unmatchedCronJobs.map((j) => this.disableJob(j.id)));
|
|
147
147
|
}
|
|
148
148
|
//-- reschedule new cron jobs and those which are not synced
|
|
149
149
|
const resyncCronJobs = allHandlers.filter((job) => job.cron &&
|
|
@@ -148,7 +148,11 @@ let LocalJobScheduler = class LocalJobScheduler extends AbstractJobScheduler {
|
|
|
148
148
|
const allJobs = await this.getCurrentJobHandlers();
|
|
149
149
|
for (const job of allJobs) {
|
|
150
150
|
if (job.cron) {
|
|
151
|
-
await this.scheduleJob(
|
|
151
|
+
await this.scheduleJob({
|
|
152
|
+
...job.retryOptions,
|
|
153
|
+
jobName: job.jobName,
|
|
154
|
+
cron: job.cron,
|
|
155
|
+
});
|
|
152
156
|
}
|
|
153
157
|
}
|
|
154
158
|
//-- re-schedule "at" jobs that are stored in repo
|
|
@@ -169,15 +173,15 @@ let LocalJobScheduler = class LocalJobScheduler extends AbstractJobScheduler {
|
|
|
169
173
|
if (jobInfo.at) {
|
|
170
174
|
//-- use the lib
|
|
171
175
|
const timeout = setTimeout(() => {
|
|
172
|
-
this.executeJob(jobInfo).catch((err) => this.logger.error(`Error execute job ${jobInfo.jobName} with id: ${jobInfo.
|
|
176
|
+
this.executeJob(jobInfo).catch((err) => this.logger.error(`Error execute job ${jobInfo.jobName} with id: ${jobInfo.id}`, err));
|
|
173
177
|
}, new Date(jobInfo.at).getTime() - Date.now());
|
|
174
|
-
this.jobHolder[jobInfo.
|
|
178
|
+
this.jobHolder[jobInfo.id] = { jobCanceler: () => clearTimeout(timeout), jobInfo };
|
|
175
179
|
}
|
|
176
180
|
else if (jobInfo.cron) {
|
|
177
181
|
const job = scheduler.scheduleJob(jobInfo.cron, () => {
|
|
178
|
-
this.executeJob(jobInfo).catch((err) => this.logger.error(`Error execute job ${jobInfo.jobName} with id: ${jobInfo.
|
|
182
|
+
this.executeJob(jobInfo).catch((err) => this.logger.error(`Error execute job ${jobInfo.jobName} with id: ${jobInfo.id}`, err));
|
|
179
183
|
});
|
|
180
|
-
this.jobHolder[jobInfo.
|
|
184
|
+
this.jobHolder[jobInfo.id] = { jobCanceler: () => job.cancel(), jobInfo };
|
|
181
185
|
}
|
|
182
186
|
else {
|
|
183
187
|
throw Errors.SYSTEM_ERROR(`Job does not have time config: ${jobInfo.jobName}`);
|
|
@@ -7,7 +7,8 @@ export declare class DefaultJobRepository<T extends AbstractJob & AbstractModel>
|
|
|
7
7
|
protected db: AbstractDbAdapter;
|
|
8
8
|
constructor(model: Constructor<T>, db: AbstractDbAdapter);
|
|
9
9
|
getJobs(query?: QueryCondition<T>, options?: GetManyOptions<T, keyof T>): Promise<T[]>;
|
|
10
|
-
insertJob(
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
insertJob(jobInfo: Partial<T>, tx?: ITransaction): Promise<string>;
|
|
11
|
+
getJobById(id: string): Promise<AbstractJob | undefined>;
|
|
12
|
+
removeJobById(id: string, tx?: ITransaction): Promise<void>;
|
|
13
|
+
updateJobById(id: string, update: Partial<Omit<T, "id">>, tx?: ITransaction): Promise<void>;
|
|
13
14
|
}
|
|
@@ -10,22 +10,19 @@ export class DefaultJobRepository extends AbstractJobRepository {
|
|
|
10
10
|
async getJobs(query, options) {
|
|
11
11
|
return await this.db.use(this.model).getRecords(query, options);
|
|
12
12
|
}
|
|
13
|
-
async insertJob(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
//-- create new
|
|
21
|
-
const job = await this.db.use(this.model, tx).createOne(jobInfo);
|
|
22
|
-
return job.jobId;
|
|
23
|
-
}
|
|
13
|
+
async insertJob(jobInfo, tx) {
|
|
14
|
+
const model = new this.model();
|
|
15
|
+
Object.assign(model, jobInfo);
|
|
16
|
+
const job = await this.db.use(this.model, tx).createOne(model);
|
|
17
|
+
return job.id;
|
|
24
18
|
}
|
|
25
|
-
async
|
|
26
|
-
await this.db.use(this.model
|
|
19
|
+
async getJobById(id) {
|
|
20
|
+
return await this.db.use(this.model).getById(id);
|
|
27
21
|
}
|
|
28
|
-
async
|
|
29
|
-
await this.db.use(this.model, tx).
|
|
22
|
+
async removeJobById(id, tx) {
|
|
23
|
+
await this.db.use(this.model, tx).deleteById(id);
|
|
24
|
+
}
|
|
25
|
+
async updateJobById(id, update, tx) {
|
|
26
|
+
await this.db.use(this.model, tx).updateById(id, update);
|
|
30
27
|
}
|
|
31
28
|
}
|
package/dist/job/interfaces.d.ts
CHANGED
|
@@ -31,14 +31,14 @@ export interface JobControllerMetadata extends ObjectMetadata {
|
|
|
31
31
|
jobs?: JobInfoMetadata[];
|
|
32
32
|
}
|
|
33
33
|
export interface JobSchedulePayload extends JobRetryOptions {
|
|
34
|
-
|
|
34
|
+
id?: string;
|
|
35
35
|
jobName: string;
|
|
36
36
|
params?: any;
|
|
37
37
|
at?: number;
|
|
38
38
|
cron?: string;
|
|
39
39
|
}
|
|
40
40
|
export interface AbstractJob extends JobSchedulePayload {
|
|
41
|
-
|
|
41
|
+
id: string;
|
|
42
42
|
disabled?: boolean;
|
|
43
43
|
execCount?: number;
|
|
44
44
|
failCount?: number;
|
package/dist/job/job.d.ts
CHANGED
package/dist/job/job.js
CHANGED
|
@@ -9,7 +9,6 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
};
|
|
10
10
|
import { AbstractModel, Column } from "@clairejs/core";
|
|
11
11
|
export class AbstractJobModel extends AbstractModel {
|
|
12
|
-
jobId;
|
|
13
12
|
jobName;
|
|
14
13
|
at;
|
|
15
14
|
cron;
|
|
@@ -25,13 +24,6 @@ export class AbstractJobModel extends AbstractModel {
|
|
|
25
24
|
lastRunAt;
|
|
26
25
|
lastSuccessAt;
|
|
27
26
|
}
|
|
28
|
-
__decorate([
|
|
29
|
-
Column({
|
|
30
|
-
description: "Unique id of the job",
|
|
31
|
-
isRequired: true,
|
|
32
|
-
}),
|
|
33
|
-
__metadata("design:type", String)
|
|
34
|
-
], AbstractJobModel.prototype, "jobId", void 0);
|
|
35
27
|
__decorate([
|
|
36
28
|
Column({
|
|
37
29
|
description: "Name of the job",
|