@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 CHANGED
@@ -1,7 +1,9 @@
1
1
  ## Change Log
2
2
 
3
- #### 3.23.2
3
+ #### 3.23.4
4
4
 
5
+ - fix abstract job scheduler & job model
6
+ - remove jobId fallback and update schedule job logic
5
7
  - fix fallback jobId by id in AbstractJob
6
8
  - fix retryDelayMs
7
9
  - improve JobScheduler
@@ -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 jobId Unique id of job
20
+ * @param id Unique id of job
16
21
  */
17
- abstract removeJobById(jobId: string, tx?: ITransaction): Promise<void>;
22
+ abstract removeJobById(id: string, tx?: ITransaction): Promise<void>;
18
23
  /**
19
24
  * Remove job info by id
20
- * @param jobId Unique id of job
25
+ * @param id Unique id of job
21
26
  */
22
- abstract updateJobById(jobId: string, update: Partial<Omit<T, "id" | "jobId">>, tx?: ITransaction): Promise<void>;
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({ jobId, ...payload }: JobSchedulePayload): Promise<string>;
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(jobId: string): Promise<void>;
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 jobId The job id returned from scheduleJobAt function
33
+ * @param id The job id returned from scheduleJobAt function
34
34
  */
35
- disableJob(jobId: string, tx?: ITransaction): Promise<void>;
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({ jobId, ...payload }) {
26
- let uniqueId = jobId;
25
+ async scheduleJob({ id, ...payload }) {
26
+ let jobId = id;
27
27
  const tx = await this.db.createTransaction();
28
- if (!uniqueId) {
29
- uniqueId = await this.jobRepo.insertJob(payload, tx);
28
+ if (!jobId && !payload.cron) {
29
+ jobId = await this.jobRepo.insertJob(payload, tx);
30
30
  }
31
31
  else {
32
- const [job] = await this.jobRepo.getJobs({ _eq: { jobId: uniqueId } }, { limit: 1 });
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({ ...payload, jobId: uniqueId }, tx);
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(uniqueId, payload, tx);
44
+ await this.jobRepo.updateJobById(job.id, payload, tx);
40
45
  }
41
46
  }
42
47
  }
43
- await this._scheduleJob({ ...payload, jobId: uniqueId });
48
+ await this._scheduleJob({ ...payload, id: jobId });
44
49
  await tx.commit();
45
- return uniqueId;
50
+ return jobId;
46
51
  }
47
52
  /**
48
53
  * Remove the scheduled job and prevent if from running in the future
49
- * @param jobId The job id returned from scheduleJobAt function
54
+ * @param id The job id returned from scheduleJobAt function
50
55
  */
51
- async disableJob(jobId, tx) {
52
- await this.cancelJob(jobId);
53
- await this.jobRepo.updateJobById(jobId, { disabled: true }, tx);
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.jobId} as handler is not found`);
69
- await this.disableJob(job.jobId || job.id, tx);
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.jobId || job.id);
112
+ await this.cancelJob(job.id);
108
113
  }
109
114
  }
110
115
  }
111
116
  }
112
- await this.jobRepo.updateJobById(job.jobId || job.id, update, tx);
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.jobId}`;
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.jobId}`);
136
- await this.disableJob(job.jobId || job.id);
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.jobId || j.id)));
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.jobId}`, err));
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.jobId || jobInfo.id] = { jobCanceler: () => clearTimeout(timeout), 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.jobId}`, err));
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.jobId || jobInfo.id] = { jobCanceler: () => job.cancel(), 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
- removeJobById(jobId: string, tx?: ITransaction): Promise<void>;
12
- updateJobById(jobId: string, update: Partial<Omit<T, "id" | "jobId">>, tx?: ITransaction): Promise<void>;
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.jobId || job.id;
17
+ return job.id;
18
18
  }
19
- async removeJobById(jobId, tx) {
20
- await this.db.use(this.model, tx).deleteMany({ _or: [{ _eq: { jobId } }, { _eq: { id: jobId } }] });
19
+ async getJobById(id) {
20
+ return await this.db.use(this.model).getById(id);
21
21
  }
22
- async updateJobById(jobId, update, tx) {
23
- await this.db
24
- .use(this.model, tx)
25
- .updateOne({ _or: [{ _eq: { jobId } }, { _eq: { id: jobId } }] }, update);
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
  }
@@ -31,7 +31,7 @@ export interface JobControllerMetadata extends ObjectMetadata {
31
31
  jobs?: JobInfoMetadata[];
32
32
  }
33
33
  export interface JobSchedulePayload extends JobRetryOptions {
34
- jobId?: string;
34
+ id?: string;
35
35
  jobName: string;
36
36
  params?: any;
37
37
  at?: number;
package/dist/job/job.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { AbstractModel } from "@clairejs/core";
2
2
  import { AbstractJob } from "./interfaces";
3
3
  export declare abstract class AbstractJobModel extends AbstractModel implements AbstractJob {
4
- jobId?: string;
5
4
  jobName: string;
6
5
  at?: number;
7
6
  cron?: string;
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clairejs/server",
3
- "version": "3.23.2",
3
+ "version": "3.23.4",
4
4
  "description": "Claire server NodeJs framework written in Typescript.",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",