@clairejs/server 3.23.2 → 3.23.4
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 +22 -17
- package/dist/job/AwsJobScheduler.js +4 -4
- package/dist/job/LocalJobScheduler.js +4 -5
- package/dist/job/default-job-repo.d.ts +3 -2
- package/dist/job/default-job-repo.js +8 -7
- package/dist/job/interfaces.d.ts +1 -1
- package/dist/job/job.d.ts +0 -1
- package/dist/job/job.js +6 -9
- 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,40 @@ 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
|
|
35
|
+
.getJobs({ _eq: { jobName: payload.jobName } }, { limit: 1 })
|
|
36
|
+
.then((jobs) => jobs[0]);
|
|
33
37
|
if (!job) {
|
|
34
|
-
await this.jobRepo.insertJob(
|
|
38
|
+
jobId = await this.jobRepo.insertJob(payload, tx);
|
|
35
39
|
}
|
|
36
40
|
else {
|
|
41
|
+
jobId = job.id;
|
|
37
42
|
const diff = diffData(job, payload);
|
|
38
43
|
if (diff) {
|
|
39
|
-
await this.jobRepo.updateJobById(
|
|
44
|
+
await this.jobRepo.updateJobById(job.id, payload, tx);
|
|
40
45
|
}
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
|
-
await this._scheduleJob({ ...payload,
|
|
48
|
+
await this._scheduleJob({ ...payload, id: jobId });
|
|
44
49
|
await tx.commit();
|
|
45
|
-
return
|
|
50
|
+
return jobId;
|
|
46
51
|
}
|
|
47
52
|
/**
|
|
48
53
|
* Remove the scheduled job and prevent if from running in the future
|
|
49
|
-
* @param
|
|
54
|
+
* @param id The job id returned from scheduleJobAt function
|
|
50
55
|
*/
|
|
51
|
-
async disableJob(
|
|
52
|
-
await this.cancelJob(
|
|
53
|
-
await this.jobRepo.updateJobById(
|
|
56
|
+
async disableJob(id, tx) {
|
|
57
|
+
await this.cancelJob(id);
|
|
58
|
+
await this.jobRepo.updateJobById(id, { disabled: true }, tx);
|
|
54
59
|
}
|
|
55
60
|
/**
|
|
56
61
|
* Execute the scheduled job
|
|
@@ -65,8 +70,8 @@ export class AbstractJobScheduler {
|
|
|
65
70
|
const jobHandler = allHandlers.find((j) => j.jobName === job.jobName);
|
|
66
71
|
const tx = await this.db.createTransaction();
|
|
67
72
|
if (!jobHandler) {
|
|
68
|
-
this.logger.info(`Disable job with id: ${job.
|
|
69
|
-
await this.disableJob(job.
|
|
73
|
+
this.logger.info(`Disable job with id: ${job.id} as handler is not found`);
|
|
74
|
+
await this.disableJob(job.id || job.id, tx);
|
|
70
75
|
}
|
|
71
76
|
else {
|
|
72
77
|
const update = {
|
|
@@ -104,12 +109,12 @@ export class AbstractJobScheduler {
|
|
|
104
109
|
}
|
|
105
110
|
else {
|
|
106
111
|
update.disabled = true;
|
|
107
|
-
await this.cancelJob(job.
|
|
112
|
+
await this.cancelJob(job.id);
|
|
108
113
|
}
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
|
-
await this.jobRepo.updateJobById(job.
|
|
117
|
+
await this.jobRepo.updateJobById(job.id, update, tx);
|
|
113
118
|
}
|
|
114
119
|
await tx.commit();
|
|
115
120
|
}
|
|
@@ -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 &&
|
|
@@ -152,7 +152,6 @@ let LocalJobScheduler = class LocalJobScheduler extends AbstractJobScheduler {
|
|
|
152
152
|
...job.retryOptions,
|
|
153
153
|
jobName: job.jobName,
|
|
154
154
|
cron: job.cron,
|
|
155
|
-
jobId: job.jobName,
|
|
156
155
|
});
|
|
157
156
|
}
|
|
158
157
|
}
|
|
@@ -174,15 +173,15 @@ let LocalJobScheduler = class LocalJobScheduler extends AbstractJobScheduler {
|
|
|
174
173
|
if (jobInfo.at) {
|
|
175
174
|
//-- use the lib
|
|
176
175
|
const timeout = setTimeout(() => {
|
|
177
|
-
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));
|
|
178
177
|
}, new Date(jobInfo.at).getTime() - Date.now());
|
|
179
|
-
this.jobHolder[jobInfo.
|
|
178
|
+
this.jobHolder[jobInfo.id] = { jobCanceler: () => clearTimeout(timeout), jobInfo };
|
|
180
179
|
}
|
|
181
180
|
else if (jobInfo.cron) {
|
|
182
181
|
const job = scheduler.scheduleJob(jobInfo.cron, () => {
|
|
183
|
-
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));
|
|
184
183
|
});
|
|
185
|
-
this.jobHolder[jobInfo.
|
|
184
|
+
this.jobHolder[jobInfo.id] = { jobCanceler: () => job.cancel(), jobInfo };
|
|
186
185
|
}
|
|
187
186
|
else {
|
|
188
187
|
throw Errors.SYSTEM_ERROR(`Job does not have time config: ${jobInfo.jobName}`);
|
|
@@ -8,6 +8,7 @@ export declare class DefaultJobRepository<T extends AbstractJob & AbstractModel>
|
|
|
8
8
|
constructor(model: Constructor<T>, db: AbstractDbAdapter);
|
|
9
9
|
getJobs(query?: QueryCondition<T>, options?: GetManyOptions<T, keyof T>): Promise<T[]>;
|
|
10
10
|
insertJob(jobInfo: Partial<T>, tx?: ITransaction): Promise<string>;
|
|
11
|
-
|
|
12
|
-
|
|
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
|
}
|
|
@@ -14,14 +14,15 @@ export class DefaultJobRepository extends AbstractJobRepository {
|
|
|
14
14
|
const model = new this.model();
|
|
15
15
|
Object.assign(model, jobInfo);
|
|
16
16
|
const job = await this.db.use(this.model, tx).createOne(model);
|
|
17
|
-
return job.
|
|
17
|
+
return job.id;
|
|
18
18
|
}
|
|
19
|
-
async
|
|
20
|
-
await this.db.use(this.model
|
|
19
|
+
async getJobById(id) {
|
|
20
|
+
return await this.db.use(this.model).getById(id);
|
|
21
21
|
}
|
|
22
|
-
async
|
|
23
|
-
await this.db
|
|
24
|
-
|
|
25
|
-
|
|
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);
|
|
26
27
|
}
|
|
27
28
|
}
|
package/dist/job/interfaces.d.ts
CHANGED
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,12 +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
|
-
}),
|
|
32
|
-
__metadata("design:type", String)
|
|
33
|
-
], AbstractJobModel.prototype, "jobId", void 0);
|
|
34
27
|
__decorate([
|
|
35
28
|
Column({
|
|
36
29
|
description: "Name of the job",
|
|
@@ -90,10 +83,14 @@ __decorate([
|
|
|
90
83
|
__metadata("design:type", String)
|
|
91
84
|
], AbstractJobModel.prototype, "lastError", void 0);
|
|
92
85
|
__decorate([
|
|
93
|
-
Column({
|
|
86
|
+
Column({
|
|
87
|
+
isTimestamp: true,
|
|
88
|
+
}),
|
|
94
89
|
__metadata("design:type", Number)
|
|
95
90
|
], AbstractJobModel.prototype, "lastRunAt", void 0);
|
|
96
91
|
__decorate([
|
|
97
|
-
Column({
|
|
92
|
+
Column({
|
|
93
|
+
isTimestamp: true,
|
|
94
|
+
}),
|
|
98
95
|
__metadata("design:type", Number)
|
|
99
96
|
], AbstractJobModel.prototype, "lastSuccessAt", void 0);
|