@clipboard-health/mongo-jobs 0.1.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.
Files changed (62) hide show
  1. package/README.md +26 -0
  2. package/package.json +41 -0
  3. package/src/index.d.ts +3 -0
  4. package/src/index.js +6 -0
  5. package/src/index.js.map +1 -0
  6. package/src/lib/backgroundJobs.d.ts +59 -0
  7. package/src/lib/backgroundJobs.js +108 -0
  8. package/src/lib/backgroundJobs.js.map +1 -0
  9. package/src/lib/handler.d.ts +6 -0
  10. package/src/lib/handler.js +3 -0
  11. package/src/lib/handler.js.map +1 -0
  12. package/src/lib/internal/cron.d.ts +29 -0
  13. package/src/lib/internal/cron.js +89 -0
  14. package/src/lib/internal/cron.js.map +1 -0
  15. package/src/lib/internal/duplicateRunningError.d.ts +2 -0
  16. package/src/lib/internal/duplicateRunningError.js +7 -0
  17. package/src/lib/internal/duplicateRunningError.js.map +1 -0
  18. package/src/lib/internal/handlerAlreadyRegisteredError.d.ts +2 -0
  19. package/src/lib/internal/handlerAlreadyRegisteredError.js +7 -0
  20. package/src/lib/internal/handlerAlreadyRegisteredError.js.map +1 -0
  21. package/src/lib/internal/jobsRepository.d.ts +51 -0
  22. package/src/lib/internal/jobsRepository.js +170 -0
  23. package/src/lib/internal/jobsRepository.js.map +1 -0
  24. package/src/lib/internal/logger.d.ts +4 -0
  25. package/src/lib/internal/logger.js +3 -0
  26. package/src/lib/internal/logger.js.map +1 -0
  27. package/src/lib/internal/metrics.d.ts +32 -0
  28. package/src/lib/internal/metrics.js +106 -0
  29. package/src/lib/internal/metrics.js.map +1 -0
  30. package/src/lib/internal/mongoDuplicate.d.ts +2 -0
  31. package/src/lib/internal/mongoDuplicate.js +9 -0
  32. package/src/lib/internal/mongoDuplicate.js.map +1 -0
  33. package/src/lib/internal/registry.d.ts +27 -0
  34. package/src/lib/internal/registry.js +78 -0
  35. package/src/lib/internal/registry.js.map +1 -0
  36. package/src/lib/internal/worker/actionableQueues.d.ts +7 -0
  37. package/src/lib/internal/worker/actionableQueues.js +32 -0
  38. package/src/lib/internal/worker/actionableQueues.js.map +1 -0
  39. package/src/lib/internal/worker/fairQueueConsumer.d.ts +24 -0
  40. package/src/lib/internal/worker/fairQueueConsumer.js +127 -0
  41. package/src/lib/internal/worker/fairQueueConsumer.js.map +1 -0
  42. package/src/lib/internal/worker/futureQueues.d.ts +5 -0
  43. package/src/lib/internal/worker/futureQueues.js +27 -0
  44. package/src/lib/internal/worker/futureQueues.js.map +1 -0
  45. package/src/lib/internal/worker/queueConsumer.d.ts +11 -0
  46. package/src/lib/internal/worker/queueConsumer.js +3 -0
  47. package/src/lib/internal/worker/queueConsumer.js.map +1 -0
  48. package/src/lib/internal/worker.d.ts +65 -0
  49. package/src/lib/internal/worker.js +342 -0
  50. package/src/lib/internal/worker.js.map +1 -0
  51. package/src/lib/job.d.ts +37 -0
  52. package/src/lib/job.js +29 -0
  53. package/src/lib/job.js.map +1 -0
  54. package/src/lib/schedule.d.ts +21 -0
  55. package/src/lib/schedule.js +16 -0
  56. package/src/lib/schedule.js.map +1 -0
  57. package/src/lib/testing.d.ts +9 -0
  58. package/src/lib/testing.js +37 -0
  59. package/src/lib/testing.js.map +1 -0
  60. package/src/lib/tracing.d.ts +8 -0
  61. package/src/lib/tracing.js +194 -0
  62. package/src/lib/tracing.js.map +1 -0
@@ -0,0 +1,342 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Worker = void 0;
4
+ const tracing_1 = require("../tracing");
5
+ const duplicateRunningError_1 = require("./duplicateRunningError");
6
+ const mongoDuplicate_1 = require("./mongoDuplicate");
7
+ const fairQueueConsumer_1 = require("./worker/fairQueueConsumer");
8
+ const MILLIS_IN_SECOND = 1000;
9
+ const DEFAULT_LOCK_TIMEOUT = 600 * MILLIS_IN_SECOND; // 10 minutes
10
+ const DEFAULT_MAX_CONCURRENCY = 10;
11
+ const DEFAULT_NEW_JOB_CHECK_WAIT = 10 * MILLIS_IN_SECOND; // 10 seconds
12
+ const DEFAULT_USE_CHANGE_STREAM = true;
13
+ const DEFAULT_UNLOCK_JOBS_INTERVAL = 60 * MILLIS_IN_SECOND; // 1 minute
14
+ const DEFAULT_REFRESH_QUEUES_INTERVAL = 30 * MILLIS_IN_SECOND; // 30 seconds
15
+ const DUPLICATE_RESCHEDULE_TIME = 5 * MILLIS_IN_SECOND; // 5 seconds
16
+ const DEFAULT_MAX_ATTEMPTS = 10;
17
+ const GRACEFUL_SHUTDOWN_WAIT = 30 * MILLIS_IN_SECOND; // 30 seconds
18
+ function errorMessage(error) {
19
+ if (error instanceof Error) {
20
+ return error.message;
21
+ }
22
+ if (typeof error === "string") {
23
+ return error;
24
+ }
25
+ return JSON.stringify(error);
26
+ }
27
+ function errorToString(error) {
28
+ if (error instanceof Error) {
29
+ return error.stack ?? error.message;
30
+ }
31
+ if (typeof error === "string") {
32
+ return error;
33
+ }
34
+ return JSON.stringify(error);
35
+ }
36
+ function fromNow(millis) {
37
+ return new Date(Date.now() + millis);
38
+ }
39
+ async function delay(time) {
40
+ await new Promise((resolve) => {
41
+ setTimeout(resolve, time);
42
+ });
43
+ }
44
+ function removeItemFromArray(array, item) {
45
+ const index = array.indexOf(item);
46
+ if (index > -1) {
47
+ array.splice(index, 1);
48
+ }
49
+ }
50
+ class Worker {
51
+ stopped = true;
52
+ lockTimeoutMS;
53
+ maxConcurrency;
54
+ newJobCheckWaitMS;
55
+ useChangeStream;
56
+ unlockJobsIntervalMS;
57
+ refreshQueuesIntervalMS;
58
+ jobsRepo;
59
+ runningJobs = new Map();
60
+ metrics;
61
+ registry;
62
+ cron;
63
+ logger;
64
+ queueConsumer;
65
+ unlockJobsInterval;
66
+ workerLoopInterval;
67
+ fetchingJobs = false;
68
+ newJobsWatched = false;
69
+ nextAvailableJobCheck = new Date();
70
+ constructor(options) {
71
+ this.metrics = options.metrics;
72
+ this.lockTimeoutMS = options.lockTimeoutMS ?? DEFAULT_LOCK_TIMEOUT;
73
+ this.maxConcurrency = options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY;
74
+ this.newJobCheckWaitMS = options.newJobCheckWaitMS ?? DEFAULT_NEW_JOB_CHECK_WAIT;
75
+ this.useChangeStream = options.useChangeStream ?? DEFAULT_USE_CHANGE_STREAM;
76
+ this.unlockJobsIntervalMS = options.unlockJobsIntervalMS ?? DEFAULT_UNLOCK_JOBS_INTERVAL;
77
+ this.refreshQueuesIntervalMS =
78
+ options.refreshQueuesIntervalMS ?? DEFAULT_REFRESH_QUEUES_INTERVAL;
79
+ this.jobsRepo = options.jobsRepo;
80
+ this.registry = options.registry;
81
+ this.cron = options.cron;
82
+ this.logger = options.logger;
83
+ const queues = this.registry.getQueuesForGroups(options.groups);
84
+ if (options.exclude) {
85
+ for (const excludedQueue of options.exclude) {
86
+ removeItemFromArray(queues, excludedQueue);
87
+ }
88
+ }
89
+ this.queueConsumer = new fairQueueConsumer_1.FairQueueConsumer(queues, options.jobsRepo);
90
+ }
91
+ async start() {
92
+ this.stopped = false;
93
+ this.logger?.info("Starting Background Processing");
94
+ this.unlockJobsInterval = setInterval(() => {
95
+ void this.unlockStuckJobs();
96
+ }, this.unlockJobsIntervalMS);
97
+ this.workerLoopInterval = setInterval(() => {
98
+ void this.workerLoop();
99
+ }, this.newJobCheckWaitMS);
100
+ await this.queueConsumer.start({
101
+ useChangeStream: this.useChangeStream,
102
+ refreshQueuesIntervalMS: this.refreshQueuesIntervalMS,
103
+ });
104
+ void this.unlockStuckJobs();
105
+ void this.workerLoop();
106
+ }
107
+ async acquireNextJob() {
108
+ try {
109
+ return await this.queueConsumer.acquireNextJob();
110
+ }
111
+ catch (error) {
112
+ this.logger?.error(`Error while getting job: ${errorMessage(error)}`);
113
+ return undefined;
114
+ }
115
+ }
116
+ async runJobHandler(job) {
117
+ this.reportExecutionDelay(job);
118
+ await (0, tracing_1.withConsumerTrace)(job, async () => {
119
+ const { handlerName } = job;
120
+ const { handler } = this.registry.getRegisteredHandler(handlerName);
121
+ const { data } = job;
122
+ await handler.perform(data, job);
123
+ });
124
+ }
125
+ async stop(waitTime) {
126
+ this.logger?.info("Background Jobs: Stopping");
127
+ this.stopped = true;
128
+ clearInterval(this.workerLoopInterval);
129
+ clearInterval(this.unlockJobsInterval);
130
+ // Stop metrics reporting first to prevent further database operations
131
+ this.metrics.stopReporting();
132
+ await this.queueConsumer.stop();
133
+ const shutdownWaitPromise = delay(waitTime ?? GRACEFUL_SHUTDOWN_WAIT);
134
+ const jobsWaitPromise = Promise.all(this.runningJobs.values());
135
+ await Promise.race([shutdownWaitPromise, jobsWaitPromise]);
136
+ if (this.runningJobs.size > 0) {
137
+ const runningJobsIds = [...this.runningJobs.keys()].join(", ");
138
+ this.logger?.error(`Following jobs didn't end on time during shutdown: ${runningJobsIds}`);
139
+ }
140
+ this.logger?.info("Background Jobs: Stopped");
141
+ }
142
+ async markJobCompleted(job) {
143
+ await this.jobsRepo.deleteJobs([job._id]);
144
+ }
145
+ getConsumedQueues() {
146
+ return this.queueConsumer.getConsumedQueues();
147
+ }
148
+ async updateUniqueKey(job) {
149
+ try {
150
+ const uniqueOptions = job.options?.unique;
151
+ if (!uniqueOptions) {
152
+ return;
153
+ }
154
+ if (job.uniqueKey === uniqueOptions.runningKey) {
155
+ return;
156
+ }
157
+ const operation = uniqueOptions.runningKey
158
+ ? { $set: { uniqueKey: uniqueOptions.runningKey } }
159
+ : { $unset: { uniqueKey: "" } };
160
+ await this.jobsRepo.updateOne(job._id, operation);
161
+ }
162
+ catch (error) {
163
+ throw (0, mongoDuplicate_1.isMongoDuplicateError)(error) ? new duplicateRunningError_1.DuplicateRunningError(error.message) : error;
164
+ }
165
+ }
166
+ async workerLoop() {
167
+ if (this.stopped ||
168
+ this.fetchingJobs ||
169
+ this.runningJobs.size >= this.maxConcurrency ||
170
+ new Date() < this.nextAvailableJobCheck) {
171
+ return;
172
+ }
173
+ while (this.runningJobs.size < this.maxConcurrency) {
174
+ this.fetchingJobs = true;
175
+ /* I know that fetching jobs one by one here is terrible,
176
+ but unfortunately Mongo doesn't support updateMany with limit.
177
+ So from all bad solutions this seemed the least terrible. */
178
+ // eslint-disable-next-line no-await-in-loop
179
+ const job = await this.acquireNextJob();
180
+ this.fetchingJobs = false;
181
+ if (!job) {
182
+ this.scheduleWorkerLoopAfterWait();
183
+ break;
184
+ }
185
+ void this.performJob(job);
186
+ }
187
+ }
188
+ handleNewJobEvent() {
189
+ this.newJobsWatched = false;
190
+ this.nextAvailableJobCheck = new Date();
191
+ void this.workerLoop();
192
+ }
193
+ scheduleWorkerLoopAfterWait() {
194
+ this.nextAvailableJobCheck = fromNow(this.newJobCheckWaitMS);
195
+ if (!this.newJobsWatched) {
196
+ this.newJobsWatched = true;
197
+ this.queueConsumer.addEventListener("newJob", () => {
198
+ this.handleNewJobEvent();
199
+ }, { once: true });
200
+ }
201
+ setTimeout(() => {
202
+ void this.workerLoop();
203
+ }, this.newJobCheckWaitMS);
204
+ }
205
+ async performJob(job) {
206
+ let jobPromiseResolve;
207
+ const jobPromise = new Promise((resolve) => {
208
+ jobPromiseResolve = resolve;
209
+ });
210
+ await (0, tracing_1.withInternalsTrace)("performJob", async () => {
211
+ try {
212
+ this.runningJobs.set(job._id, jobPromise);
213
+ await this.cron.maybeScheduleNextJob(job);
214
+ await this.updateUniqueKey(job);
215
+ await this.runJobHandler(job);
216
+ await this.markJobCompleted(job);
217
+ }
218
+ catch (error) {
219
+ if (error instanceof duplicateRunningError_1.DuplicateRunningError) {
220
+ void this.duplicateReschedule(job);
221
+ }
222
+ else {
223
+ this.logger?.error(`Error while performing job ${job._id.toString()}: ${errorMessage(error)}`);
224
+ void this.handleJobError(job, errorToString(error));
225
+ }
226
+ }
227
+ finally {
228
+ this.runningJobs.delete(job._id);
229
+ jobPromiseResolve();
230
+ void this.workerLoop();
231
+ }
232
+ });
233
+ }
234
+ async handleJobError(job, error) {
235
+ try {
236
+ const attemptsCount = job.attemptsCount + 1;
237
+ const maxAttempts = this.getMaxAttemptsForJob(job);
238
+ // eslint-disable-next-line unicorn/prefer-ternary
239
+ if (attemptsCount < maxAttempts) {
240
+ await this.scheduleRetry(job, attemptsCount, error);
241
+ }
242
+ else {
243
+ await this.markJobFailed(job, attemptsCount, error);
244
+ }
245
+ }
246
+ catch {
247
+ this.logger?.error(`Error while marking job as failed. Job id: ${job._id.toString()}, error: ${errorMessage(error)}`);
248
+ }
249
+ }
250
+ async duplicateReschedule(job) {
251
+ await this.jobsRepo.updateOne(job._id, {
252
+ $set: {
253
+ nextRunAt: fromNow(DUPLICATE_RESCHEDULE_TIME),
254
+ },
255
+ $unset: {
256
+ lockedAt: "",
257
+ },
258
+ });
259
+ }
260
+ async unlockStuckJobs() {
261
+ const lockedAtThreshold = fromNow(-this.lockTimeoutMS);
262
+ for (;;) {
263
+ // eslint-disable-next-line no-await-in-loop
264
+ const job = await this.jobsRepo.unlockFirstExpiredJob(lockedAtThreshold);
265
+ if (!job) {
266
+ return;
267
+ }
268
+ if (job.queue) {
269
+ this.metrics.increment(job.queue, "expired");
270
+ }
271
+ this.logger?.error("Background job expired", this.logContext(job));
272
+ }
273
+ }
274
+ reportExecutionDelay(job) {
275
+ if (!job.nextRunAt) {
276
+ return;
277
+ }
278
+ if (job.queue) {
279
+ this.metrics.timing(job.queue, "delay", job.nextRunAt);
280
+ }
281
+ }
282
+ logContext(job) {
283
+ return {
284
+ jobId: job._id.toString(),
285
+ queue: job.queue,
286
+ handlerName: job.handlerName,
287
+ attemptsCount: job.attemptsCount,
288
+ createdAt: job.createdAt,
289
+ updatedAt: job.updatedAt,
290
+ nextRunAt: job.nextRunAt,
291
+ lockedAt: job.lockedAt,
292
+ };
293
+ }
294
+ getMaxAttemptsForJob(job) {
295
+ try {
296
+ const { handlerName } = job;
297
+ const { handler } = this.registry.getRegisteredHandler(handlerName);
298
+ return handler.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
299
+ }
300
+ catch {
301
+ return DEFAULT_MAX_ATTEMPTS;
302
+ }
303
+ }
304
+ async markJobFailed(job, attemptsCount, error) {
305
+ this.logger?.error(`Background Job Failed: ${job.handlerName}`, {
306
+ ...this.logContext(job),
307
+ error,
308
+ });
309
+ await this.jobsRepo.updateOne(job._id, {
310
+ $set: {
311
+ lastError: error,
312
+ failedAt: new Date(),
313
+ attemptsCount,
314
+ originalQueue: job.queue,
315
+ },
316
+ $unset: {
317
+ queue: "",
318
+ nextRunAt: "",
319
+ uniqueKey: "",
320
+ },
321
+ });
322
+ }
323
+ async scheduleRetry(job, attemptsCount, error) {
324
+ const exponentialBackoffTime = 2 ** attemptsCount * MILLIS_IN_SECOND;
325
+ const nextRunAt = fromNow(exponentialBackoffTime);
326
+ if (job.queue) {
327
+ this.metrics.increment(job.queue, "retry");
328
+ }
329
+ await this.jobsRepo.updateOne(job._id, {
330
+ $set: {
331
+ lastError: error.toString(),
332
+ nextRunAt,
333
+ attemptsCount,
334
+ },
335
+ $unset: {
336
+ lockedAt: "",
337
+ },
338
+ });
339
+ }
340
+ }
341
+ exports.Worker = Worker;
342
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../../../../packages/mongo-jobs/src/lib/internal/worker.ts"],"names":[],"mappings":";;;AAGA,wCAAmE;AAEnE,mEAAgE;AAIhE,qDAAyD;AAEzD,kEAA+D;AAsB/D,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,oBAAoB,GAAG,GAAG,GAAG,gBAAgB,CAAC,CAAC,aAAa;AAClE,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,0BAA0B,GAAG,EAAE,GAAG,gBAAgB,CAAC,CAAC,aAAa;AACvE,MAAM,yBAAyB,GAAG,IAAI,CAAC;AACvC,MAAM,4BAA4B,GAAG,EAAE,GAAG,gBAAgB,CAAC,CAAC,WAAW;AACvE,MAAM,+BAA+B,GAAG,EAAE,GAAG,gBAAgB,CAAC,CAAC,aAAa;AAC5E,MAAM,yBAAyB,GAAG,CAAC,GAAG,gBAAgB,CAAC,CAAC,YAAY;AACpE,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAChC,MAAM,sBAAsB,GAAG,EAAE,GAAG,gBAAgB,CAAC,CAAC,aAAa;AAEnE,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC;IACtC,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,OAAO,CAAC,MAAc;IAC7B,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,IAAY;IAC/B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC5B,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAI,KAAU,EAAE,IAAO;IACjD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QACf,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED,MAAa,MAAM;IACV,OAAO,GAAG,IAAI,CAAC;IAEL,aAAa,CAAS;IACtB,cAAc,CAAS;IACvB,iBAAiB,CAAS;IAC1B,eAAe,CAAU;IAEzB,oBAAoB,CAAS;IAC7B,uBAAuB,CAAS;IAChC,QAAQ,CAAiB;IACzB,WAAW,GAAG,IAAI,GAAG,EAA6C,CAAC;IACnE,OAAO,CAAU;IACjB,QAAQ,CAAW;IACnB,IAAI,CAAO;IACX,MAAM,CAAqB;IAC3B,aAAa,CAAgB;IAEtC,kBAAkB,CAAkB;IACpC,kBAAkB,CAAkB;IACpC,YAAY,GAAG,KAAK,CAAC;IACrB,cAAc,GAAG,KAAK,CAAC;IACvB,qBAAqB,GAAG,IAAI,IAAI,EAAE,CAAC;IAE3C,YAAY,OAA2B;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,oBAAoB,CAAC;QACnE,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,uBAAuB,CAAC;QACxE,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,0BAA0B,CAAC;QACjF,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,yBAAyB,CAAC;QAC5E,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,IAAI,4BAA4B,CAAC;QACzF,IAAI,CAAC,uBAAuB;YAC1B,OAAO,CAAC,uBAAuB,IAAI,+BAA+B,CAAC;QACrE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEhE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,KAAK,MAAM,aAAa,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAC5C,mBAAmB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,IAAI,qCAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAEpD,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;YACzC,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;QAC9B,CAAC,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAE9B,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC,GAAG,EAAE;YACzC,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QACzB,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAE3B,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;YAC7B,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;SACtD,CAAC,CAAC;QAEH,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,cAAc;QACzB,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,4BAA4B,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACtE,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,GAA+B;QACxD,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAE/B,MAAM,IAAA,2BAAiB,EAAC,GAAG,EAAE,KAAK,IAAI,EAAE;YACtC,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;YAC5B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;YACpE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;YACrB,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,QAAiB;QACjC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,aAAa,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACvC,aAAa,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAEvC,sEAAsE;QACtE,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAE7B,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAEhC,MAAM,mBAAmB,GAAG,KAAK,CAAC,QAAQ,IAAI,sBAAsB,CAAC,CAAC;QACtE,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;QAE/D,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC,CAAC;QAE3D,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/D,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,sDAAsD,cAAc,EAAE,CAAC,CAAC;QAC7F,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAChD,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,GAA+B;QAC3D,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC;IAEM,iBAAiB;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC;IAChD,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,GAA+B;QAC1D,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC;YAE1C,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,SAAS,KAAK,aAAa,CAAC,UAAU,EAAE,CAAC;gBAC/C,OAAO;YACT,CAAC;YAED,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU;gBACxC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,aAAa,CAAC,UAAU,EAAE,EAAE;gBACnD,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC;YAElC,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAA,sCAAqB,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,6CAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACxF,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,IACE,IAAI,CAAC,OAAO;YACZ,IAAI,CAAC,YAAY;YACjB,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,cAAc;YAC5C,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,qBAAqB,EACvC,CAAC;YACD,OAAO;QACT,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACnD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB;;2EAE+D;YAE/D,4CAA4C;YAC5C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;YAE1B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,IAAI,CAAC,2BAA2B,EAAE,CAAC;gBACnC,MAAM;YACR,CAAC;YAED,KAAK,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,qBAAqB,GAAG,IAAI,IAAI,EAAE,CAAC;QACxC,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;IACzB,CAAC;IAEO,2BAA2B;QACjC,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAE7D,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAE3B,IAAI,CAAC,aAAa,CAAC,gBAAgB,CACjC,QAAQ,EACR,GAAG,EAAE;gBACH,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;QACJ,CAAC;QAED,UAAU,CAAC,GAAG,EAAE;YACd,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QACzB,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,GAA+B;QACtD,IAAI,iBAA4C,CAAC;QACjD,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACzC,iBAAiB,GAAG,OAAO,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,MAAM,IAAA,4BAAkB,EAAC,YAAY,EAAE,KAAK,IAAI,EAAE;YAChD,IAAI,CAAC;gBACH,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;gBAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;gBAC1C,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;gBAChC,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;gBAC9B,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,6CAAqB,EAAE,CAAC;oBAC3C,KAAK,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;gBACrC,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,EAAE,KAAK,CAChB,8BAA8B,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,YAAY,CAAC,KAAK,CAAC,EAAE,CAC3E,CAAC;oBACF,KAAK,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACjC,iBAAiB,EAAE,CAAC;gBACpB,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,GAA+B,EAAE,KAAa;QACzE,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC;YAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;YAEnD,kDAAkD;YAClD,IAAI,aAAa,GAAG,WAAW,EAAE,CAAC;gBAChC,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,MAAM,EAAE,KAAK,CAChB,8CAA8C,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,YAAY,CACtF,KAAK,CACN,EAAE,CACJ,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,GAA+B;QAC/D,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;YACrC,IAAI,EAAE;gBACJ,SAAS,EAAE,OAAO,CAAC,yBAAyB,CAAC;aAC9C;YACD,MAAM,EAAE;gBACN,QAAQ,EAAE,EAAE;aACb;SACF,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAEvD,SAAS,CAAC;YACR,4CAA4C;YAC5C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,iBAAiB,CAAC,CAAC;YAEzE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACd,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAC/C,CAAC;YAED,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,wBAAwB,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,GAA+B;QAC1D,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,GAA+B;QAChD,OAAO;YACL,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE;YACzB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,aAAa,EAAE,GAAG,CAAC,aAAa;YAChC,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;SACvB,CAAC;IACJ,CAAC;IAEO,oBAAoB,CAAC,GAA+B;QAC1D,IAAI,CAAC;YACH,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;YAC5B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;YACpE,OAAO,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,oBAAoB,CAAC;QAC9B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,GAA+B,EAC/B,aAAqB,EACrB,KAAa;QAEb,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,0BAA0B,GAAG,CAAC,WAAW,EAAE,EAAE;YAC9D,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YACvB,KAAK;SACN,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;YACrC,IAAI,EAAE;gBACJ,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,IAAI,IAAI,EAAE;gBACpB,aAAa;gBACb,aAAa,EAAE,GAAG,CAAC,KAAK;aACzB;YACD,MAAM,EAAE;gBACN,KAAK,EAAE,EAAE;gBACT,SAAS,EAAE,EAAE;gBACb,SAAS,EAAE,EAAE;aACd;SACF,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,GAA+B,EAC/B,aAAqB,EACrB,KAAa;QAEb,MAAM,sBAAsB,GAAG,CAAC,IAAI,aAAa,GAAG,gBAAgB,CAAC;QACrE,MAAM,SAAS,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAElD,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;YACrC,IAAI,EAAE;gBACJ,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE;gBAC3B,SAAS;gBACT,aAAa;aACd;YACD,MAAM,EAAE;gBACN,QAAQ,EAAE,EAAE;aACb;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAxWD,wBAwWC"}
@@ -0,0 +1,37 @@
1
+ import mongoose from "mongoose";
2
+ import type { TraceHeaders } from "./tracing";
3
+ export interface JobUniqueOptions {
4
+ enqueuedKey: string | undefined;
5
+ runningKey: string | undefined;
6
+ }
7
+ interface JobOptions {
8
+ unique?: JobUniqueOptions;
9
+ }
10
+ export interface BackgroundJobType<T> {
11
+ _id: mongoose.Types.ObjectId;
12
+ createdAt: Date;
13
+ updatedAt: Date;
14
+ queue: string | undefined;
15
+ handlerName: string;
16
+ data: T & TraceHeaders;
17
+ nextRunAt: Date | undefined;
18
+ lockedAt: Date | undefined;
19
+ failedAt: Date | undefined;
20
+ attemptsCount: number;
21
+ lastError: string | undefined;
22
+ options: JobOptions | undefined;
23
+ uniqueKey: string | undefined;
24
+ scheduleName: string | undefined;
25
+ originalQueue: string | undefined;
26
+ }
27
+ export declare const BackgroundJobSchemaName = "BackgroundJob";
28
+ declare const BackgroundJobSchema: mongoose.Schema<BackgroundJobType<unknown>, mongoose.Model<BackgroundJobType<unknown>, any, any, any, mongoose.Document<unknown, any, BackgroundJobType<unknown>, any, {}> & BackgroundJobType<unknown> & Required<{
29
+ _id: mongoose.Types.ObjectId;
30
+ }> & {
31
+ __v: number;
32
+ }, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, BackgroundJobType<unknown>, mongoose.Document<unknown, {}, mongoose.FlatRecord<BackgroundJobType<unknown>>, {}, mongoose.ResolveSchemaOptions<mongoose.DefaultSchemaOptions>> & mongoose.FlatRecord<BackgroundJobType<unknown>> & Required<{
33
+ _id: mongoose.Types.ObjectId;
34
+ }> & {
35
+ __v: number;
36
+ }>;
37
+ export { BackgroundJobSchema };
package/src/lib/job.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BackgroundJobSchema = exports.BackgroundJobSchemaName = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const mongoose_1 = tslib_1.__importDefault(require("mongoose"));
6
+ exports.BackgroundJobSchemaName = "BackgroundJob";
7
+ const BackgroundJobSchema = new mongoose_1.default.Schema({
8
+ queue: String,
9
+ handlerName: String,
10
+ data: {},
11
+ nextRunAt: Date,
12
+ lockedAt: Date,
13
+ failedAt: Date,
14
+ attemptsCount: { type: Number, default: 0 },
15
+ lastError: String,
16
+ options: {},
17
+ uniqueKey: String,
18
+ scheduleName: String,
19
+ originalQueue: String,
20
+ }, {
21
+ timestamps: true,
22
+ });
23
+ exports.BackgroundJobSchema = BackgroundJobSchema;
24
+ BackgroundJobSchema.index({ queue: 1, lockedAt: 1, nextRunAt: 1 });
25
+ BackgroundJobSchema.index({ failedAt: 1, lockedAt: 1 });
26
+ BackgroundJobSchema.index({ originalQueue: 1, failedAt: 1 });
27
+ BackgroundJobSchema.index({ uniqueKey: 1 }, { unique: true, sparse: true });
28
+ BackgroundJobSchema.index({ scheduleName: 1 });
29
+ //# sourceMappingURL=job.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job.js","sourceRoot":"","sources":["../../../../../packages/mongo-jobs/src/lib/job.ts"],"names":[],"mappings":";;;;AAAA,gEAAgC;AAoCnB,QAAA,uBAAuB,GAAG,eAAe,CAAC;AAEvD,MAAM,mBAAmB,GAAG,IAAI,kBAAQ,CAAC,MAAM,CAC7C;IACE,KAAK,EAAE,MAAM;IACb,WAAW,EAAE,MAAM;IACnB,IAAI,EAAE,EAAE;IACR,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,aAAa,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE;IAC3C,SAAS,EAAE,MAAM;IACjB,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,MAAM;IACjB,YAAY,EAAE,MAAM;IACpB,aAAa,EAAE,MAAM;CACtB,EACD;IACE,UAAU,EAAE,IAAI;CACjB,CACF,CAAC;AAQO,kDAAmB;AAN5B,mBAAmB,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;AACnE,mBAAmB,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;AACxD,mBAAmB,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;AAC7D,mBAAmB,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAC5E,mBAAmB,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import mongoose from "mongoose";
2
+ export interface ScheduleType<T> {
3
+ _id: mongoose.Types.ObjectId;
4
+ name: string;
5
+ cronExpression: string;
6
+ timeZone: string;
7
+ handlerName: string;
8
+ queue: string;
9
+ data: T;
10
+ }
11
+ export declare const ScheduleSchemaName = "BackgroundJobSchedule";
12
+ declare const ScheduleSchema: mongoose.Schema<ScheduleType<unknown>, mongoose.Model<ScheduleType<unknown>, any, any, any, mongoose.Document<unknown, any, ScheduleType<unknown>, any, {}> & ScheduleType<unknown> & Required<{
13
+ _id: mongoose.Types.ObjectId;
14
+ }> & {
15
+ __v: number;
16
+ }, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, ScheduleType<unknown>, mongoose.Document<unknown, {}, mongoose.FlatRecord<ScheduleType<unknown>>, {}, mongoose.ResolveSchemaOptions<mongoose.DefaultSchemaOptions>> & mongoose.FlatRecord<ScheduleType<unknown>> & Required<{
17
+ _id: mongoose.Types.ObjectId;
18
+ }> & {
19
+ __v: number;
20
+ }>;
21
+ export { ScheduleSchema };
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScheduleSchema = exports.ScheduleSchemaName = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const mongoose_1 = tslib_1.__importDefault(require("mongoose"));
6
+ exports.ScheduleSchemaName = "BackgroundJobSchedule";
7
+ const ScheduleSchema = new mongoose_1.default.Schema({
8
+ name: String,
9
+ cronExpression: String,
10
+ timeZone: String,
11
+ handlerName: String,
12
+ data: {},
13
+ });
14
+ exports.ScheduleSchema = ScheduleSchema;
15
+ ScheduleSchema.index({ name: 1 }, { unique: true });
16
+ //# sourceMappingURL=schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../../../../packages/mongo-jobs/src/lib/schedule.ts"],"names":[],"mappings":";;;;AAAA,gEAAgC;AAYnB,QAAA,kBAAkB,GAAG,uBAAuB,CAAC;AAE1D,MAAM,cAAc,GAAG,IAAI,kBAAQ,CAAC,MAAM,CAAwB;IAChE,IAAI,EAAE,MAAM;IACZ,cAAc,EAAE,MAAM;IACtB,QAAQ,EAAE,MAAM;IAChB,WAAW,EAAE,MAAM;IACnB,IAAI,EAAE,EAAE;CACT,CAAC,CAAC;AAIM,wCAAc;AAFvB,cAAc,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { BackgroundJobsService } from "./backgroundJobs";
2
+ import type { AnyHandlerClass } from "./internal/registry";
3
+ interface DrainOptions {
4
+ jobsScheduledUntil?: Date;
5
+ recursive?: boolean;
6
+ }
7
+ export declare function drainQueues(backgroundJobs: BackgroundJobsService, groups: string[], options?: DrainOptions): Promise<void>;
8
+ export declare function drainHandlers(backgroundJobs: BackgroundJobsService, handlers: Array<AnyHandlerClass<unknown> | string>, options?: DrainOptions): Promise<void>;
9
+ export {};
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.drainQueues = drainQueues;
4
+ exports.drainHandlers = drainHandlers;
5
+ async function executeJobs(backgroundJobs, worker, queues, options = {}) {
6
+ for (;;) {
7
+ const pendingJobs = await backgroundJobs.jobModel.find({
8
+ nextRunAt: { $lte: options.jobsScheduledUntil ?? new Date() },
9
+ queue: { $in: queues },
10
+ });
11
+ if (pendingJobs.length === 0) {
12
+ return;
13
+ }
14
+ for (const job of pendingJobs) {
15
+ await worker.updateUniqueKey(job);
16
+ await worker.runJobHandler(job);
17
+ await worker.markJobCompleted(job);
18
+ }
19
+ if (options.recursive === false) {
20
+ return;
21
+ }
22
+ }
23
+ }
24
+ // Drain jobs for all queues in given groups
25
+ async function drainQueues(backgroundJobs, groups, options = {}) {
26
+ const worker = backgroundJobs.buildWorker(groups, { useChangeStream: false });
27
+ const consumedQueues = worker.getConsumedQueues();
28
+ await executeJobs(backgroundJobs, worker, consumedQueues, options);
29
+ }
30
+ // Drain jobs for given handlers
31
+ async function drainHandlers(backgroundJobs, handlers, options = {}) {
32
+ const queues = handlers.map((handler) => backgroundJobs.registry.getRegisteredHandler(handler).queue);
33
+ const worker = backgroundJobs.buildWorker([], { useChangeStream: false });
34
+ await executeJobs(backgroundJobs, worker, queues, options);
35
+ }
36
+ /* eslint-enable no-await-in-loop */
37
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../../../../../packages/mongo-jobs/src/lib/testing.ts"],"names":[],"mappings":";;AAuCA,kCASC;AAGD,sCAWC;AApDD,KAAK,UAAU,WAAW,CACxB,cAAqC,EACrC,MAAc,EACd,MAAgB,EAChB,UAAwB,EAAE;IAE1B,SAAS,CAAC;QACR,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC;YACrD,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,kBAAkB,IAAI,IAAI,IAAI,EAAE,EAAE;YAC7D,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;SACvB,CAAC,CAAC;QAEH,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,MAAM,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAChC,MAAM,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;IACH,CAAC;AACH,CAAC;AAED,4CAA4C;AACrC,KAAK,UAAU,WAAW,CAC/B,cAAqC,EACrC,MAAgB,EAChB,UAAwB,EAAE;IAE1B,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC;IAElD,MAAM,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;AACrE,CAAC;AAED,gCAAgC;AACzB,KAAK,UAAU,aAAa,CACjC,cAAqC,EACrC,QAAkD,EAClD,UAAwB,EAAE;IAE1B,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CACzB,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,KAAK,CACzE,CAAC;IACF,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;IAE1E,MAAM,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAC7D,CAAC;AACD,oCAAoC"}
@@ -0,0 +1,8 @@
1
+ import type { HandlerInterface } from "./handler";
2
+ import type { BackgroundJobType } from "./job";
3
+ export interface TraceHeaders {
4
+ _traceHeaders?: Record<string, string>;
5
+ }
6
+ export declare function withProducerTrace<T>(handler: HandlerInterface<T>, data: T, callback: (data: T & TraceHeaders) => Promise<BackgroundJobType<T> | undefined>): Promise<BackgroundJobType<T> | undefined>;
7
+ export declare function withConsumerTrace(job: BackgroundJobType<unknown>, callback: () => Promise<void>): Promise<void>;
8
+ export declare function withInternalsTrace<T>(resource: string, callback: () => Promise<T>): Promise<T>;