@alanszp/queue 9.2.3 → 9.2.6

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.
@@ -0,0 +1,10 @@
1
+ import { BaseError, RenderableContext, RenderableError } from "@alanszp/errors";
2
+ import { JobState } from "bullmq";
3
+ export declare class JobCannotBePromotedError extends BaseError implements RenderableError {
4
+ jobId: string;
5
+ currentJobState: JobState | "unknown";
6
+ constructor(jobId: string, currentJobState: JobState | "unknown");
7
+ code(): string;
8
+ renderMessage(): string;
9
+ context(): RenderableContext;
10
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobCannotBePromotedError = void 0;
4
+ const errors_1 = require("@alanszp/errors");
5
+ class JobCannotBePromotedError extends errors_1.BaseError {
6
+ constructor(jobId, currentJobState) {
7
+ super("JobCannotBePromotedError");
8
+ this.jobId = jobId;
9
+ this.currentJobState = currentJobState;
10
+ }
11
+ code() {
12
+ return "job_cannot_be_promoted_error";
13
+ }
14
+ renderMessage() {
15
+ return "Job not found";
16
+ }
17
+ context() {
18
+ return {
19
+ jobId: this.jobId,
20
+ currentJobState: this.currentJobState,
21
+ };
22
+ }
23
+ }
24
+ exports.JobCannotBePromotedError = JobCannotBePromotedError;
25
+ //# sourceMappingURL=JobCannotBePromotedError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobCannotBePromotedError.js","sourceRoot":"","sources":["../../src/errors/JobCannotBePromotedError.ts"],"names":[],"mappings":";;;AAAA,4CAAgF;AAGhF,MAAa,wBACX,SAAQ,kBAAS;IAOjB,YAAY,KAAa,EAAE,eAAqC;QAC9D,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACzC,CAAC;IAED,IAAI;QACF,OAAO,8BAA8B,CAAC;IACxC,CAAC;IAED,aAAa;QACX,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO;QACL,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC;IACJ,CAAC;CACF;AA5BD,4DA4BC"}
@@ -0,0 +1,8 @@
1
+ import { BaseError, RenderableContext, RenderableError } from "@alanszp/errors";
2
+ export declare class JobNotFoundError extends BaseError implements RenderableError {
3
+ jobId: string;
4
+ constructor(jobId: string);
5
+ code(): string;
6
+ renderMessage(): string;
7
+ context(): RenderableContext;
8
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobNotFoundError = void 0;
4
+ const errors_1 = require("@alanszp/errors");
5
+ class JobNotFoundError extends errors_1.BaseError {
6
+ constructor(jobId) {
7
+ super("JobNotFoundError");
8
+ this.jobId = jobId;
9
+ }
10
+ code() {
11
+ return "job_not_found_error";
12
+ }
13
+ renderMessage() {
14
+ return "Job not found";
15
+ }
16
+ context() {
17
+ return {
18
+ jobId: this.jobId,
19
+ };
20
+ }
21
+ }
22
+ exports.JobNotFoundError = JobNotFoundError;
23
+ //# sourceMappingURL=JobNotFoundError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobNotFoundError.js","sourceRoot":"","sources":["../../src/errors/JobNotFoundError.ts"],"names":[],"mappings":";;;AAAA,4CAAgF;AAEhF,MAAa,gBAAiB,SAAQ,kBAAS;IAG7C,YAAY,KAAa;QACvB,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,IAAI;QACF,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,aAAa;QACX,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO;QACL,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;CACF;AArBD,4CAqBC"}
@@ -1,4 +1,4 @@
1
1
  import { Queue } from "./queue";
2
2
  import { JobData, QueueOptions } from "../types";
3
3
  import { SharedContext } from "@alanszp/shared-context";
4
- export declare function createQueue<JobType = JobData>(name: string, getContext: () => SharedContext, queueOptions?: QueueOptions): Queue;
4
+ export declare function createQueue<Data = JobData>(name: string, getContext: () => SharedContext, queueOptions?: QueueOptions): Queue<Data>;
@@ -1,18 +1,27 @@
1
1
  import { Job, JobsOptions } from "bullmq";
2
+ import { ListResult } from "@alanszp/core";
2
3
  import { SharedContext } from "@alanszp/shared-context";
3
- import { ConnectionOptions, JobData, QueueOptions } from "../types";
4
- export declare class Queue<JobType = JobData> {
4
+ import { ConnectionOptions, JobData, JobReturnValue, JobTypeEnum, QueueOptions } from "../types";
5
+ export declare class Queue<Data = JobData, ReturnValue = JobReturnValue> {
5
6
  private _queue;
6
7
  private name;
7
8
  private getSharedContext;
8
9
  constructor(connection: ConnectionOptions, name: string, prefix: string, getSharedContext: () => SharedContext, queueOptions?: QueueOptions);
9
10
  getName(): string;
10
- publishJob(job: JobType, opts?: JobsOptions): Promise<Job<JobType>>;
11
- publishBulkJob(jobDatas: JobType[]): Promise<Job<JobType>[]>;
11
+ publishJob(job: Data, opts?: JobsOptions): Promise<Job<Data, ReturnValue>>;
12
+ publishBulkJob(jobDatas: Data[]): Promise<Job<Data, ReturnValue>[]>;
12
13
  publishBulkJobWithOptions(jobDefinitions: {
13
- jobData: JobType;
14
+ jobData: Data;
14
15
  opts: JobsOptions;
15
- }[]): Promise<void>;
16
+ }[]): Promise<Job<Data, ReturnValue>[]>;
17
+ private pageToStartEnd;
18
+ getJobsAndCountByStatus(statuses: JobTypeEnum[], page?: number, pageSize?: number, ascending?: boolean): Promise<ListResult<Job<Data, ReturnValue>>>;
19
+ getJobCountByStatus(statuses: JobTypeEnum[], page?: number, pageSize?: number): Promise<number>;
20
+ getJobsByStatus(statuses: JobTypeEnum[], page?: number, pageSize?: number, ascending?: boolean): Promise<Job<Data, ReturnValue>[]>;
21
+ deleteJob(jobId: string): Promise<void>;
22
+ getJob(jobId: string): Promise<Job<Data, ReturnValue> | undefined>;
23
+ getJobOrFail(jobId: string): Promise<Job<Data, ReturnValue>>;
24
+ changeDelayToJob(jobId: string, delayMs: number): Promise<void>;
16
25
  close(): Promise<void>;
17
26
  private get queue();
18
27
  }
@@ -12,9 +12,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.Queue = void 0;
13
13
  const lodash_1 = require("lodash");
14
14
  const types_1 = require("../types");
15
+ const JobNotFoundError_1 = require("../errors/JobNotFoundError");
16
+ const JobCannotBePromotedError_1 = require("../errors/JobCannotBePromotedError");
15
17
  const BULL_PREFIX = "b";
16
18
  const DEFAULT_COMPLETED_JOB_MAX_AGE_IN_SECONDS = 60 * 60 * 24 * 30;
17
19
  const DEFAULT_COMPLETED_JOB_MAX_COUNT = 500;
20
+ const DEFAULT_FAILED_JOB_MAX_COUNT = 1000;
18
21
  class Queue {
19
22
  constructor(connection, name, prefix, getSharedContext, queueOptions) {
20
23
  this.name = name;
@@ -25,6 +28,9 @@ class Queue {
25
28
  age: DEFAULT_COMPLETED_JOB_MAX_AGE_IN_SECONDS,
26
29
  count: DEFAULT_COMPLETED_JOB_MAX_COUNT,
27
30
  },
31
+ removeOnFail: {
32
+ count: DEFAULT_FAILED_JOB_MAX_COUNT,
33
+ },
28
34
  attempts: 3,
29
35
  backoff: {
30
36
  type: "exponential",
@@ -58,7 +64,67 @@ class Queue {
58
64
  data,
59
65
  opts,
60
66
  }));
61
- yield this.queue.addBulk(jobs);
67
+ return this.queue.addBulk(jobs);
68
+ });
69
+ }
70
+ pageToStartEnd(pageNumber, pageSize) {
71
+ return {
72
+ start: (pageNumber - 1) * pageSize,
73
+ end: pageNumber * pageSize - 1,
74
+ };
75
+ }
76
+ getJobsAndCountByStatus(statuses, page = 1, pageSize = 50, ascending = false) {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ const { start, end } = this.pageToStartEnd(page, pageSize);
79
+ const [total, elements] = yield Promise.all([
80
+ this.queue.getJobCountByTypes(...statuses),
81
+ this.queue.getJobs(statuses, start, end, ascending),
82
+ ]);
83
+ return {
84
+ total,
85
+ elements,
86
+ page,
87
+ pageSize,
88
+ };
89
+ });
90
+ }
91
+ getJobCountByStatus(statuses, page = 1, pageSize = 50) {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ return this.queue.getJobCountByTypes(...statuses);
94
+ });
95
+ }
96
+ getJobsByStatus(statuses, page = 1, pageSize = 50, ascending = false) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ const { start, end } = this.pageToStartEnd(page, pageSize);
99
+ return this.queue.getJobs(statuses, start, end, ascending);
100
+ });
101
+ }
102
+ deleteJob(jobId) {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ this.queue.remove(jobId);
105
+ });
106
+ }
107
+ getJob(jobId) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ return this.queue.getJob(jobId);
110
+ });
111
+ }
112
+ getJobOrFail(jobId) {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ const job = yield this.queue.getJob(jobId);
115
+ if (!job)
116
+ throw new JobNotFoundError_1.JobNotFoundError(jobId);
117
+ return job;
118
+ });
119
+ }
120
+ changeDelayToJob(jobId, delayMs) {
121
+ return __awaiter(this, void 0, void 0, function* () {
122
+ const job = yield this.getJobOrFail(jobId);
123
+ const state = yield job.getState();
124
+ if (state !== types_1.JobStateEnum.DELAYED) {
125
+ throw new JobCannotBePromotedError_1.JobCannotBePromotedError(jobId, state);
126
+ }
127
+ job.changeDelay(delayMs);
62
128
  });
63
129
  }
64
130
  close() {
@@ -1 +1 @@
1
- {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/queue/queue.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mCAA+B;AAG/B,oCAA8E;AAE9E,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,MAAM,wCAAwC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACnE,MAAM,+BAA+B,GAAG,GAAG,CAAC;AAE5C,MAAa,KAAK;IAOhB,YACE,UAA6B,EAC7B,IAAY,EACZ,MAAc,EACd,gBAAqC,EACrC,YAA2B;QAE3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QAEzC,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAQ,CAAU,IAAI,kCACnC,IAAA,cAAK,EACN;YACE,iBAAiB,EAAE;gBACjB,gBAAgB,EAAE;oBAChB,GAAG,EAAE,wCAAwC;oBAC7C,KAAK,EAAE,+BAA+B;iBACvC;gBACD,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE;oBACP,IAAI,EAAE,aAAa;oBACnB,KAAK,EAAE,IAAI;iBACZ;aACF;YACD,UAAU;SACX,EACD,YAAY,IAAI,EAAE,CACnB,GACE,EAAE,MAAM,EAAE,IAAI,MAAM,KAAK,WAAW,EAAE,EAAE,EAC3C,CAAC;IACL,CAAC;IAEM,OAAO;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAEK,UAAU,CAAC,GAAY,EAAE,IAAkB;;YAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxC,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,kCAAO,GAAG,KAAE,GAAG,EAAE,GAAG,KAAI,IAAI,CAAC,CAAC;QAC/D,CAAC;KAAA;IAEK,cAAc,CAAC,QAAmB;;YACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACjE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;KAAA;IAEK,yBAAyB,CAC7B,cAAyD;;YAEzD,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC5D,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI;gBACJ,IAAI;aACL,CAAC,CAAC,CAAC;YACJ,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;KAAA;IAEK,KAAK;;YACT,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC3B,CAAC;KAAA;IAED,IAAY,KAAK;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AA1ED,sBA0EC"}
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../src/queue/queue.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,2 +1,22 @@
1
- export { ConnectionOptions, RedisOptions, Job, Worker as RawWorker, WorkerOptions, Queue as RawQueue, QueueOptions, JobsOptions, } from "bullmq";
2
- export declare type JobData = any;
1
+ export { ConnectionOptions, RedisOptions, Job, Worker as RawWorker, WorkerOptions, Queue as RawQueue, QueueOptions, JobState, JobType, JobsOptions, } from "bullmq";
2
+ export declare type JobData = unknown;
3
+ export declare type JobReturnValue = unknown;
4
+ export declare enum JobStateEnum {
5
+ ACTIVE = "active",
6
+ DELAYED = "delayed",
7
+ WAITING = "waiting",
8
+ COMPLETED = "completed",
9
+ FAILED = "failed",
10
+ WAITING_CHILDREN = "waiting-children"
11
+ }
12
+ export declare enum JobTypeEnum {
13
+ ACTIVE = "active",
14
+ DELAYED = "delayed",
15
+ WAITING = "waiting",
16
+ COMPLETED = "completed",
17
+ FAILED = "failed",
18
+ WAITING_CHILDREN = "waiting-children",
19
+ PAUSED = "paused",
20
+ REPEAT = "repeat",
21
+ WAIT = "wait"
22
+ }
package/dist/types.js CHANGED
@@ -1,9 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RawQueue = exports.RawWorker = exports.Job = void 0;
3
+ exports.JobTypeEnum = exports.JobStateEnum = exports.RawQueue = exports.RawWorker = exports.Job = void 0;
4
4
  // decoupling from bullmq
5
5
  var bullmq_1 = require("bullmq");
6
6
  Object.defineProperty(exports, "Job", { enumerable: true, get: function () { return bullmq_1.Job; } });
7
7
  Object.defineProperty(exports, "RawWorker", { enumerable: true, get: function () { return bullmq_1.Worker; } });
8
8
  Object.defineProperty(exports, "RawQueue", { enumerable: true, get: function () { return bullmq_1.Queue; } });
9
+ var JobStateEnum;
10
+ (function (JobStateEnum) {
11
+ JobStateEnum["ACTIVE"] = "active";
12
+ JobStateEnum["DELAYED"] = "delayed";
13
+ JobStateEnum["WAITING"] = "waiting";
14
+ JobStateEnum["COMPLETED"] = "completed";
15
+ JobStateEnum["FAILED"] = "failed";
16
+ JobStateEnum["WAITING_CHILDREN"] = "waiting-children";
17
+ })(JobStateEnum = exports.JobStateEnum || (exports.JobStateEnum = {}));
18
+ var JobTypeEnum;
19
+ (function (JobTypeEnum) {
20
+ JobTypeEnum["ACTIVE"] = "active";
21
+ JobTypeEnum["DELAYED"] = "delayed";
22
+ JobTypeEnum["WAITING"] = "waiting";
23
+ JobTypeEnum["COMPLETED"] = "completed";
24
+ JobTypeEnum["FAILED"] = "failed";
25
+ JobTypeEnum["WAITING_CHILDREN"] = "waiting-children";
26
+ JobTypeEnum["PAUSED"] = "paused";
27
+ JobTypeEnum["REPEAT"] = "repeat";
28
+ JobTypeEnum["WAIT"] = "wait";
29
+ })(JobTypeEnum = exports.JobTypeEnum || (exports.JobTypeEnum = {}));
9
30
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AACzB,iCASgB;AANd,6FAAA,GAAG,OAAA;AACH,mGAAA,MAAM,OAAa;AAEnB,kGAAA,KAAK,OAAY"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AACzB,iCAWgB;AARd,6FAAA,GAAG,OAAA;AACH,mGAAA,MAAM,OAAa;AAEnB,kGAAA,KAAK,OAAY;AAWnB,IAAY,YAOX;AAPD,WAAY,YAAY;IACtB,iCAAiB,CAAA;IACjB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,uCAAuB,CAAA;IACvB,iCAAiB,CAAA;IACjB,qDAAqC,CAAA;AACvC,CAAC,EAPW,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAOvB;AAED,IAAY,WAUX;AAVD,WAAY,WAAW;IACrB,gCAAiB,CAAA;IACjB,kCAAmB,CAAA;IACnB,kCAAmB,CAAA;IACnB,sCAAuB,CAAA;IACvB,gCAAiB,CAAA;IACjB,oDAAqC,CAAA;IACrC,gCAAiB,CAAA;IACjB,gCAAiB,CAAA;IACjB,4BAAa,CAAA;AACf,CAAC,EAVW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAUtB"}
@@ -1,5 +1,5 @@
1
1
  import { ILogger } from "@alanszp/logger";
2
- import { JobData, Job, RawWorker, WorkerOptions } from "../types";
2
+ import { JobData, Job, RawWorker, WorkerOptions, JobReturnValue } from "../types";
3
3
  import { SharedContext } from "@alanszp/shared-context";
4
4
  import { Audit } from "@alanszp/audit";
5
5
  export interface WorkerStatus {
@@ -15,25 +15,25 @@ export interface WorkerContext {
15
15
  baseLogger: ILogger;
16
16
  audit: Audit;
17
17
  }
18
- interface Worker<T = JobData> {
19
- handleJobFailed?(job: Job<T>, error: Error): Promise<void> | void;
20
- handleJobCompleted?(job: Job<T>): Promise<void> | void;
18
+ interface Worker<Data = JobData, ReturnValue = JobReturnValue> {
19
+ handleJobFailed?(job: Job<Data, ReturnValue>, error: Error): Promise<void> | void;
20
+ handleJobCompleted?(job: Job<Data, ReturnValue>): Promise<void> | void;
21
21
  handleJobError?(error: Error): Promise<void> | void;
22
22
  }
23
- declare abstract class Worker<T = JobData> {
23
+ declare abstract class Worker<Data = JobData, ReturnValue = unknown> {
24
24
  private _worker;
25
25
  private _queue;
26
26
  private getLogger;
27
27
  constructor();
28
- abstract process(job: Job<T>): Promise<void>;
28
+ abstract process(job: Job<Data, ReturnValue>): Promise<ReturnValue>;
29
29
  abstract setup(): WorkerSetup;
30
30
  abstract getContext(): WorkerContext;
31
31
  close(): Promise<void>;
32
32
  get status(): WorkerStatus;
33
33
  get id(): RawWorker["id"];
34
34
  private processJob;
35
- processFailed(job: Job<T>, error: Error): Promise<void>;
36
- processCompleted(job: Job<T>): Promise<void>;
35
+ processFailed(job: Job<Data, ReturnValue>, error: Error): Promise<void>;
36
+ processCompleted(job: Job<Data, ReturnValue>, returnValue: ReturnValue): Promise<void>;
37
37
  processError(error: Error): Promise<void>;
38
38
  run(): Promise<void>;
39
39
  protected registerHooks(): void;
@@ -40,7 +40,7 @@ class Worker {
40
40
  queue: this.queueFullName,
41
41
  job,
42
42
  });
43
- yield this.process(job);
43
+ return this.process(job);
44
44
  }));
45
45
  }
46
46
  processFailed(job, error) {
@@ -55,11 +55,12 @@ class Worker {
55
55
  }
56
56
  });
57
57
  }
58
- processCompleted(job) {
58
+ processCompleted(job, returnValue) {
59
59
  return __awaiter(this, void 0, void 0, function* () {
60
60
  this.getLogger().info("worker.job.completed", {
61
61
  queue: this.queueFullName,
62
62
  job,
63
+ returnValue,
63
64
  });
64
65
  if (this.handleJobCompleted) {
65
66
  yield this.handleJobCompleted(job);
@@ -101,7 +102,7 @@ class Worker {
101
102
  // on error: handle unhandled exceptions
102
103
  this.worker.on("error", (error) => this.processError(error));
103
104
  // on completed: allow to do something else after a job is completed
104
- this.worker.on("completed", (job) => this.processCompleted(job));
105
+ this.worker.on("completed", (job, result) => this.processCompleted(job, result));
105
106
  // on failed: when the process fails with an exception it is possible to listen for the "failed" event
106
107
  this.worker.on("failed", (job, error) => this.processFailed(job, error));
107
108
  }
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/worker/worker.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,4DAAyD;AACzD,oCAAkE;AAGlE,yDAAsD;AA4BtD,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,MAAe,MAAM;IAOnB;QACE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAExD,MAAM,iBAAiB,GAAG,qCAAiB,CAAC,WAAW,EAAE,CAAC;QAC1D,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;QAE7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,cAAc,EAAE,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;QACvD,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAS,CAAI,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,kBACrD,OAAO,EAAE,KAAK,EACd,UAAU,EAAE,iBAAiB,CAAC,aAAa,EAAE,EAC7C,MAAM,EAAE,IAAI,MAAM,KAAK,WAAW,EAAE,IACjC,aAAa,EAChB,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QAErE,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IASM,KAAK;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,IAAW,MAAM;QACf,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC9E,CAAC;IAED,IAAW,EAAE;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACxB,CAAC;IAEO,UAAU;QAChB,OAAO,IAAA,yBAAW,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAO,GAAG,EAAE,EAAE;YAClD,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,6BAA6B,EAAE;gBACnD,KAAK,EAAE,IAAI,CAAC,aAAa;gBACzB,GAAG;aACJ,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC,CAAA,CAAC,CAAC;IACL,CAAC;IAEK,aAAa,CAAC,GAAW,EAAE,KAAY;;YAC3C,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE;gBACzC,KAAK,EAAE,IAAI,CAAC,aAAa;gBACzB,GAAG;gBACH,KAAK;aACN,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,eAAe,EAAE;gBACxB,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;aACxC;QACH,CAAC;KAAA;IAEK,gBAAgB,CAAC,GAAW;;YAChC,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE;gBAC5C,KAAK,EAAE,IAAI,CAAC,aAAa;gBACzB,GAAG;aACJ,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,kBAAkB,EAAE;gBAC3B,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;aACpC;QACH,CAAC;KAAA;IAEK,YAAY,CAAC,KAAY;;YAC7B,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,gCAAgC,EAAE;gBACvD,KAAK,EAAE,IAAI,CAAC,aAAa;gBACzB,KAAK;aACN,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,cAAc,EAAE;gBACvB,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;aAClC;QACH,CAAC;KAAA;IAEK,GAAG;;YACP,IAAI;gBACF,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE;oBAC3C,KAAK,EAAE,IAAI,CAAC,aAAa;iBAC1B,CAAC,CAAC;gBAEH,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACxB,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE;oBAC1C,KAAK,EAAE,IAAI,CAAC,aAAa;iBAC1B,CAAC,CAAC;aACJ;YAAC,OAAO,KAAc,EAAE;gBACvB,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE;oBACzC,KAAK,EAAE,IAAI,CAAC,aAAa;oBACzB,KAAK;iBACN,CAAC,CAAC;gBACH,MAAM,KAAK,CAAC;aACb;QACH,CAAC;KAAA;IAES,aAAa;QACrB,wCAAwC;QACxC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,oEAAoE;QACpE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;QACzE,sGAAsG;QACtG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAW,EAAE,KAAY,EAAE,EAAE,CACrD,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAC/B,CAAC;IACJ,CAAC;IAED,IAAc,MAAM;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAI,aAAa;QACf,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAChD,OAAO,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;CACF;AAGQ,wBAAM"}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/worker/worker.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,4DAAyD;AACzD,oCAMkB;AAGlB,yDAAsD;AA+BtD,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,MAAe,MAAM;IAOnB;QACE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAExD,MAAM,iBAAiB,GAAG,qCAAiB,CAAC,WAAW,EAAE,CAAC;QAC1D,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;QAE7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,cAAc,EAAE,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;QACvD,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAS,CAAoB,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,kBACrE,OAAO,EAAE,KAAK,EACd,UAAU,EAAE,iBAAiB,CAAC,aAAa,EAAE,EAC7C,MAAM,EAAE,IAAI,MAAM,KAAK,WAAW,EAAE,IACjC,aAAa,EAChB,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QAErE,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IASM,KAAK;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,IAAW,MAAM;QACf,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC9E,CAAC;IAED,IAAW,EAAE;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACxB,CAAC;IAEO,UAAU;QAChB,OAAO,IAAA,yBAAW,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAO,GAAG,EAAE,EAAE;YAClD,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,6BAA6B,EAAE;gBACnD,KAAK,EAAE,IAAI,CAAC,aAAa;gBACzB,GAAG;aACJ,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC,CAAA,CAAC,CAAC;IACL,CAAC;IAEK,aAAa,CACjB,GAA2B,EAC3B,KAAY;;YAEZ,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,mBAAmB,EAAE;gBACzC,KAAK,EAAE,IAAI,CAAC,aAAa;gBACzB,GAAG;gBACH,KAAK;aACN,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,eAAe,EAAE;gBACxB,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;aACxC;QACH,CAAC;KAAA;IAEK,gBAAgB,CACpB,GAA2B,EAC3B,WAAwB;;YAExB,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE;gBAC5C,KAAK,EAAE,IAAI,CAAC,aAAa;gBACzB,GAAG;gBACH,WAAW;aACZ,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,kBAAkB,EAAE;gBAC3B,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;aACpC;QACH,CAAC;KAAA;IAEK,YAAY,CAAC,KAAY;;YAC7B,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,gCAAgC,EAAE;gBACvD,KAAK,EAAE,IAAI,CAAC,aAAa;gBACzB,KAAK;aACN,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,cAAc,EAAE;gBACvB,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;aAClC;QACH,CAAC;KAAA;IAEK,GAAG;;YACP,IAAI;gBACF,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE;oBAC3C,KAAK,EAAE,IAAI,CAAC,aAAa;iBAC1B,CAAC,CAAC;gBAEH,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACxB,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE;oBAC1C,KAAK,EAAE,IAAI,CAAC,aAAa;iBAC1B,CAAC,CAAC;aACJ;YAAC,OAAO,KAAc,EAAE;gBACvB,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE;oBACzC,KAAK,EAAE,IAAI,CAAC,aAAa;oBACzB,KAAK;iBACN,CAAC,CAAC;gBACH,MAAM,KAAK,CAAC;aACb;QACH,CAAC;KAAA;IAES,aAAa;QACrB,wCAAwC;QACxC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,oEAAoE;QACpE,IAAI,CAAC,MAAM,CAAC,EAAE,CACZ,WAAW,EACX,CAAC,GAA2B,EAAE,MAAmB,EAAE,EAAE,CACnD,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CACrC,CAAC;QACF,sGAAsG;QACtG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAA2B,EAAE,KAAY,EAAE,EAAE,CACrE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAC/B,CAAC;IACJ,CAAC;IAED,IAAc,MAAM;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAI,aAAa;QACf,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAChD,OAAO,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;CACF;AAGQ,wBAAM"}
@@ -1,3 +1,4 @@
1
1
  import { Job, JobData } from "bullmq";
2
2
  import { WorkerContext } from "../worker/worker";
3
- export declare function withContext<T = JobData>(workerContext: WorkerContext, executor: (job: Job<T>) => Promise<void>): (job: Job<T>) => Promise<void>;
3
+ import { JobReturnValue } from "../types";
4
+ export declare function withContext<T = JobData, ReturnValue = JobReturnValue>(workerContext: WorkerContext, executor: (job: Job<T>) => Promise<ReturnValue>): (job: Job<T>) => Promise<ReturnValue>;
@@ -1 +1 @@
1
- {"version":3,"file":"withContext.js","sourceRoot":"","sources":["../../src/wrappers/withContext.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gDAAwB;AACxB,4DAAyD;AAIzD,SAAgB,WAAW,CACzB,aAA4B,EAC5B,QAAwC;IAExC,OAAO,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,IAAsC,CAAC;QAChE,OAAO,aAAa,CAAC,aAAa,CAAC,GAAG,CACpC,GAAS,EAAE;YACT,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC,CAAA,EACD;YACE,MAAM,EAAE,aAAa,CAAC,UAAU;YAChC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE;YACtC,WAAW,EAAE,GAAG,IAAI,IAAA,cAAI,GAAE;YAC1B,cAAc,EAAE,GAAG,IAAI,IAAA,6BAAa,GAAE;YACtC,SAAS,EAAE,IAAA,cAAI,GAAE;SAClB,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAnBD,kCAmBC"}
1
+ {"version":3,"file":"withContext.js","sourceRoot":"","sources":["../../src/wrappers/withContext.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,gDAAwB;AACxB,4DAAyD;AAKzD,SAAgB,WAAW,CACzB,aAA4B,EAC5B,QAA+C;IAE/C,OAAO,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,IAAsC,CAAC;QAChE,OAAO,aAAa,CAAC,aAAa,CAAC,GAAG,CACpC,GAAS,EAAE;YACT,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC,CAAA,EACD;YACE,MAAM,EAAE,aAAa,CAAC,UAAU;YAChC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE;YACtC,WAAW,EAAE,GAAG,IAAI,IAAA,cAAI,GAAE;YAC1B,cAAc,EAAE,GAAG,IAAI,IAAA,6BAAa,GAAE;YACtC,SAAS,EAAE,IAAA,cAAI,GAAE;SAClB,CACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAnBD,kCAmBC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alanszp/queue",
3
- "version": "9.2.3",
3
+ "version": "9.2.6",
4
4
  "description": "Workers and queues",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -26,11 +26,12 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@alanszp/audit": "^9.0.0",
29
+ "@alanszp/core": "^9.2.2",
29
30
  "@alanszp/logger": "^9.0.0",
30
31
  "@alanszp/shared-context": "^9.0.0",
31
32
  "bullmq": "^2.1.2",
32
33
  "ioredis": "^5.2.3",
33
34
  "lodash": "^4.17.21"
34
35
  },
35
- "gitHead": "dcb2a6f5d6489dbcb67197d26b8da716ea3c9c97"
36
+ "gitHead": "a5e4b5c25d8acdbfdf1cfa07791c620cc0d2fff5"
36
37
  }
@@ -0,0 +1,32 @@
1
+ import { BaseError, RenderableContext, RenderableError } from "@alanszp/errors";
2
+ import { JobState } from "bullmq";
3
+
4
+ export class JobCannotBePromotedError
5
+ extends BaseError
6
+ implements RenderableError
7
+ {
8
+ public jobId: string;
9
+
10
+ public currentJobState: JobState | "unknown";
11
+
12
+ constructor(jobId: string, currentJobState: JobState | "unknown") {
13
+ super("JobCannotBePromotedError");
14
+ this.jobId = jobId;
15
+ this.currentJobState = currentJobState;
16
+ }
17
+
18
+ code(): string {
19
+ return "job_cannot_be_promoted_error";
20
+ }
21
+
22
+ renderMessage(): string {
23
+ return "Job not found";
24
+ }
25
+
26
+ context(): RenderableContext {
27
+ return {
28
+ jobId: this.jobId,
29
+ currentJobState: this.currentJobState,
30
+ };
31
+ }
32
+ }
@@ -0,0 +1,24 @@
1
+ import { BaseError, RenderableContext, RenderableError } from "@alanszp/errors";
2
+
3
+ export class JobNotFoundError extends BaseError implements RenderableError {
4
+ public jobId: string;
5
+
6
+ constructor(jobId: string) {
7
+ super("JobNotFoundError");
8
+ this.jobId = jobId;
9
+ }
10
+
11
+ code(): string {
12
+ return "job_not_found_error";
13
+ }
14
+
15
+ renderMessage(): string {
16
+ return "Job not found";
17
+ }
18
+
19
+ context(): RenderableContext {
20
+ return {
21
+ jobId: this.jobId,
22
+ };
23
+ }
24
+ }
@@ -4,13 +4,13 @@ import { ConnectionManager } from "../connectionManager";
4
4
  import { JobData, QueueOptions } from "../types";
5
5
  import { SharedContext } from "@alanszp/shared-context";
6
6
 
7
- export function createQueue<JobType = JobData>(
7
+ export function createQueue<Data = JobData>(
8
8
  name: string,
9
9
  getContext: () => SharedContext,
10
10
  queueOptions?: QueueOptions
11
- ): Queue {
11
+ ): Queue<Data> {
12
12
  const connection = ConnectionManager.getInstance().getConnection();
13
- const queue = new Queue<JobType>(
13
+ const queue = new Queue<Data>(
14
14
  connection,
15
15
  name,
16
16
  ConnectionManager.getInstance().getServiceName(),
@@ -1,14 +1,27 @@
1
- import { merge } from "lodash";
1
+ import { capitalize, merge } from "lodash";
2
2
  import { Job, JobsOptions } from "bullmq";
3
+ import { ListResult } from "@alanszp/core";
3
4
  import { SharedContext } from "@alanszp/shared-context";
4
- import { ConnectionOptions, JobData, QueueOptions, RawQueue } from "../types";
5
+ import {
6
+ ConnectionOptions,
7
+ JobData,
8
+ JobReturnValue,
9
+ JobStateEnum,
10
+ JobTypeEnum,
11
+ QueueOptions,
12
+ RawQueue,
13
+ } from "../types";
14
+ import { JobNotFoundError } from "../errors/JobNotFoundError";
15
+ import { JobCannotBePromotedError } from "../errors/JobCannotBePromotedError";
16
+ import { ResultTypes } from "ioredis/built/utils/RedisCommander";
5
17
 
6
18
  const BULL_PREFIX = "b";
7
19
 
8
20
  const DEFAULT_COMPLETED_JOB_MAX_AGE_IN_SECONDS = 60 * 60 * 24 * 30;
9
21
  const DEFAULT_COMPLETED_JOB_MAX_COUNT = 500;
22
+ const DEFAULT_FAILED_JOB_MAX_COUNT = 1000;
10
23
 
11
- export class Queue<JobType = JobData> {
24
+ export class Queue<Data = JobData, ReturnValue = JobReturnValue> {
12
25
  private _queue: RawQueue;
13
26
 
14
27
  private name: string;
@@ -26,7 +39,7 @@ export class Queue<JobType = JobData> {
26
39
 
27
40
  this.getSharedContext = getSharedContext;
28
41
 
29
- this._queue = new RawQueue<JobType>(name, {
42
+ this._queue = new RawQueue<Data>(name, {
30
43
  ...merge(
31
44
  {
32
45
  defaultJobOptions: {
@@ -34,6 +47,9 @@ export class Queue<JobType = JobData> {
34
47
  age: DEFAULT_COMPLETED_JOB_MAX_AGE_IN_SECONDS,
35
48
  count: DEFAULT_COMPLETED_JOB_MAX_COUNT,
36
49
  },
50
+ removeOnFail: {
51
+ count: DEFAULT_FAILED_JOB_MAX_COUNT,
52
+ },
37
53
  attempts: 3,
38
54
  backoff: {
39
55
  type: "exponential",
@@ -52,34 +68,109 @@ export class Queue<JobType = JobData> {
52
68
  return this.name;
53
69
  }
54
70
 
55
- async publishJob(job: JobType, opts?: JobsOptions): Promise<Job<JobType>> {
71
+ async publishJob(
72
+ job: Data,
73
+ opts?: JobsOptions
74
+ ): Promise<Job<Data, ReturnValue>> {
56
75
  const context = this.getSharedContext();
57
76
  const lid = context.getLifecycleId();
58
77
  const lch = context.getLifecycleChain();
59
78
  return this.queue.add(this.name, { ...job, lid, lch }, opts);
60
79
  }
61
80
 
62
- async publishBulkJob(jobDatas: JobType[]): Promise<Job<JobType>[]> {
81
+ async publishBulkJob(jobDatas: Data[]): Promise<Job<Data, ReturnValue>[]> {
63
82
  const jobs = jobDatas.map((data) => ({ name: this.name, data }));
64
83
  return this.queue.addBulk(jobs);
65
84
  }
66
85
 
67
86
  async publishBulkJobWithOptions(
68
- jobDefinitions: { jobData: JobType; opts: JobsOptions }[]
69
- ): Promise<void> {
87
+ jobDefinitions: { jobData: Data; opts: JobsOptions }[]
88
+ ): Promise<Job<Data, ReturnValue>[]> {
70
89
  const jobs = jobDefinitions.map(({ jobData: data, opts }) => ({
71
90
  name: this.name,
72
91
  data,
73
92
  opts,
74
93
  }));
75
- await this.queue.addBulk(jobs);
94
+ return this.queue.addBulk(jobs);
95
+ }
96
+
97
+ private pageToStartEnd(pageNumber: number, pageSize: number) {
98
+ return {
99
+ start: (pageNumber - 1) * pageSize,
100
+ end: pageNumber * pageSize - 1,
101
+ };
102
+ }
103
+
104
+ public async getJobsAndCountByStatus(
105
+ statuses: JobTypeEnum[],
106
+ page: number = 1,
107
+ pageSize: number = 50,
108
+ ascending: boolean = false
109
+ ): Promise<ListResult<Job<Data, ReturnValue>>> {
110
+ const { start, end } = this.pageToStartEnd(page, pageSize);
111
+ const [total, elements] = await Promise.all([
112
+ this.queue.getJobCountByTypes(...statuses),
113
+ this.queue.getJobs(statuses, start, end, ascending),
114
+ ]);
115
+
116
+ return {
117
+ total,
118
+ elements,
119
+ page,
120
+ pageSize,
121
+ };
122
+ }
123
+
124
+ public async getJobCountByStatus(
125
+ statuses: JobTypeEnum[],
126
+ page: number = 1,
127
+ pageSize: number = 50
128
+ ): Promise<number> {
129
+ return this.queue.getJobCountByTypes(...statuses);
130
+ }
131
+
132
+ public async getJobsByStatus(
133
+ statuses: JobTypeEnum[],
134
+ page: number = 1,
135
+ pageSize: number = 50,
136
+ ascending: boolean = false
137
+ ): Promise<Job<Data, ReturnValue>[]> {
138
+ const { start, end } = this.pageToStartEnd(page, pageSize);
139
+ return this.queue.getJobs(statuses, start, end, ascending);
140
+ }
141
+
142
+ public async deleteJob(jobId: string) {
143
+ this.queue.remove(jobId);
144
+ }
145
+
146
+ public async getJob(
147
+ jobId: string
148
+ ): Promise<Job<Data, ReturnValue> | undefined> {
149
+ return this.queue.getJob(jobId);
150
+ }
151
+
152
+ public async getJobOrFail(jobId: string): Promise<Job<Data, ReturnValue>> {
153
+ const job = await this.queue.getJob(jobId);
154
+ if (!job) throw new JobNotFoundError(jobId);
155
+ return job;
156
+ }
157
+
158
+ public async changeDelayToJob(jobId: string, delayMs: number) {
159
+ const job = await this.getJobOrFail(jobId);
160
+
161
+ const state = await job.getState();
162
+ if (state !== JobStateEnum.DELAYED) {
163
+ throw new JobCannotBePromotedError(jobId, state);
164
+ }
165
+
166
+ job.changeDelay(delayMs);
76
167
  }
77
168
 
78
169
  async close(): Promise<void> {
79
170
  await this.queue.close();
80
171
  }
81
172
 
82
- private get queue(): RawQueue<JobType> {
173
+ private get queue(): RawQueue<Data, ReturnValue> {
83
174
  return this._queue;
84
175
  }
85
176
  }
package/src/types.ts CHANGED
@@ -7,9 +7,32 @@ export {
7
7
  WorkerOptions,
8
8
  Queue as RawQueue,
9
9
  QueueOptions,
10
+ JobState,
11
+ JobType,
10
12
  JobsOptions,
11
13
  } from "bullmq";
12
14
 
13
- // This may seems odd but actual Job data type from bullmq is any 🤷‍♂️
14
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
- export type JobData = any;
15
+ export type JobData = unknown;
16
+
17
+ export type JobReturnValue = unknown;
18
+
19
+ export enum JobStateEnum {
20
+ ACTIVE = "active",
21
+ DELAYED = "delayed",
22
+ WAITING = "waiting",
23
+ COMPLETED = "completed",
24
+ FAILED = "failed",
25
+ WAITING_CHILDREN = "waiting-children",
26
+ }
27
+
28
+ export enum JobTypeEnum {
29
+ ACTIVE = "active",
30
+ DELAYED = "delayed",
31
+ WAITING = "waiting",
32
+ COMPLETED = "completed",
33
+ FAILED = "failed",
34
+ WAITING_CHILDREN = "waiting-children",
35
+ PAUSED = "paused",
36
+ REPEAT = "repeat",
37
+ WAIT = "wait",
38
+ }
@@ -1,6 +1,12 @@
1
1
  import { ILogger } from "@alanszp/logger";
2
2
  import { ConnectionManager } from "../connectionManager";
3
- import { JobData, Job, RawWorker, WorkerOptions } from "../types";
3
+ import {
4
+ JobData,
5
+ Job,
6
+ RawWorker,
7
+ WorkerOptions,
8
+ JobReturnValue,
9
+ } from "../types";
4
10
  import { SharedContext } from "@alanszp/shared-context";
5
11
  import { Audit } from "@alanszp/audit";
6
12
  import { withContext } from "../wrappers/withContext";
@@ -23,9 +29,12 @@ export interface WorkerContext {
23
29
 
24
30
  // optional methods
25
31
 
26
- interface Worker<T = JobData> {
27
- handleJobFailed?(job: Job<T>, error: Error): Promise<void> | void;
28
- handleJobCompleted?(job: Job<T>): Promise<void> | void;
32
+ interface Worker<Data = JobData, ReturnValue = JobReturnValue> {
33
+ handleJobFailed?(
34
+ job: Job<Data, ReturnValue>,
35
+ error: Error
36
+ ): Promise<void> | void;
37
+ handleJobCompleted?(job: Job<Data, ReturnValue>): Promise<void> | void;
29
38
  handleJobError?(error: Error): Promise<void> | void;
30
39
  }
31
40
 
@@ -33,7 +42,7 @@ type QueueName = { name: string; prefix: string; namespace: string };
33
42
 
34
43
  const BULL_PREFIX = "b";
35
44
 
36
- abstract class Worker<T = JobData> {
45
+ abstract class Worker<Data = JobData, ReturnValue = unknown> {
37
46
  private _worker: RawWorker;
38
47
 
39
48
  private _queue: QueueName;
@@ -48,7 +57,7 @@ abstract class Worker<T = JobData> {
48
57
 
49
58
  const prefix = connectionManager.getServiceName();
50
59
  this._queue = { name, prefix, namespace: BULL_PREFIX };
51
- this._worker = new RawWorker<T>(name, this.processJob(), {
60
+ this._worker = new RawWorker<Data, ReturnValue>(name, this.processJob(), {
52
61
  autorun: false,
53
62
  connection: connectionManager.getConnection(),
54
63
  prefix: `{${prefix}}:${BULL_PREFIX}`,
@@ -60,7 +69,7 @@ abstract class Worker<T = JobData> {
60
69
  }
61
70
 
62
71
  // Handle job
63
- abstract process(job: Job<T>): Promise<void>;
72
+ abstract process(job: Job<Data, ReturnValue>): Promise<ReturnValue>;
64
73
 
65
74
  abstract setup(): WorkerSetup;
66
75
 
@@ -78,17 +87,20 @@ abstract class Worker<T = JobData> {
78
87
  return this.worker.id;
79
88
  }
80
89
 
81
- private processJob(): (job: Job<T>) => Promise<void> {
90
+ private processJob(): (job: Job<Data, ReturnValue>) => Promise<ReturnValue> {
82
91
  return withContext(this.getContext(), async (job) => {
83
92
  this.getLogger().info(`worker.process.job_received`, {
84
93
  queue: this.queueFullName,
85
94
  job,
86
95
  });
87
- await this.process(job);
96
+ return this.process(job);
88
97
  });
89
98
  }
90
99
 
91
- async processFailed(job: Job<T>, error: Error): Promise<void> {
100
+ async processFailed(
101
+ job: Job<Data, ReturnValue>,
102
+ error: Error
103
+ ): Promise<void> {
92
104
  this.getLogger().warn("worker.job.failed", {
93
105
  queue: this.queueFullName,
94
106
  job,
@@ -99,10 +111,14 @@ abstract class Worker<T = JobData> {
99
111
  }
100
112
  }
101
113
 
102
- async processCompleted(job: Job<T>): Promise<void> {
114
+ async processCompleted(
115
+ job: Job<Data, ReturnValue>,
116
+ returnValue: ReturnValue
117
+ ): Promise<void> {
103
118
  this.getLogger().info("worker.job.completed", {
104
119
  queue: this.queueFullName,
105
120
  job,
121
+ returnValue,
106
122
  });
107
123
  if (this.handleJobCompleted) {
108
124
  await this.handleJobCompleted(job);
@@ -142,9 +158,13 @@ abstract class Worker<T = JobData> {
142
158
  // on error: handle unhandled exceptions
143
159
  this.worker.on("error", (error: Error) => this.processError(error));
144
160
  // on completed: allow to do something else after a job is completed
145
- this.worker.on("completed", (job: Job<T>) => this.processCompleted(job));
161
+ this.worker.on(
162
+ "completed",
163
+ (job: Job<Data, ReturnValue>, result: ReturnValue) =>
164
+ this.processCompleted(job, result)
165
+ );
146
166
  // on failed: when the process fails with an exception it is possible to listen for the "failed" event
147
- this.worker.on("failed", (job: Job<T>, error: Error) =>
167
+ this.worker.on("failed", (job: Job<Data, ReturnValue>, error: Error) =>
148
168
  this.processFailed(job, error)
149
169
  );
150
170
  }
@@ -2,11 +2,12 @@ import cuid from "cuid";
2
2
  import { appIdentifier } from "../helpers/appIdentifier";
3
3
  import { Job, JobData } from "bullmq";
4
4
  import { WorkerContext } from "../worker/worker";
5
+ import { JobReturnValue } from "../types";
5
6
 
6
- export function withContext<T = JobData>(
7
+ export function withContext<T = JobData, ReturnValue = JobReturnValue>(
7
8
  workerContext: WorkerContext,
8
- executor: (job: Job<T>) => Promise<void>
9
- ): (job: Job<T>) => Promise<void> {
9
+ executor: (job: Job<T>) => Promise<ReturnValue>
10
+ ): (job: Job<T>) => Promise<ReturnValue> {
10
11
  return (job) => {
11
12
  const { lid, lch } = job.data as { lid?: string; lch?: string };
12
13
  return workerContext.sharedContext.run(