@orion-js/dogs 4.2.10 → 4.3.1
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/dist/index.cjs +64 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +62 -46
- package/dist/index.js.map +1 -1
- package/package.json +21 -21
- package/LICENSE +0 -21
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
7
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
8
8
|
var __typeError = (msg) => {
|
|
9
9
|
throw TypeError(msg);
|
|
10
10
|
};
|
|
@@ -101,7 +101,6 @@ var import_services = require("@orion-js/services");
|
|
|
101
101
|
var import_helpers = require("@orion-js/helpers");
|
|
102
102
|
var import_logger = require("@orion-js/logger");
|
|
103
103
|
var import_mongodb = require("@orion-js/mongodb");
|
|
104
|
-
var import_mongodb2 = require("@orion-js/mongodb");
|
|
105
104
|
|
|
106
105
|
// src/types/JobRecord.ts
|
|
107
106
|
var import_schema = require("@orion-js/schema");
|
|
@@ -126,7 +125,7 @@ var JobRecordSchema = (0, import_schema.schemaWithName)("JobRecord", {
|
|
|
126
125
|
|
|
127
126
|
// src/repos/JobsRepo.ts
|
|
128
127
|
var _jobs_dec, _JobsRepo_decorators, _init;
|
|
129
|
-
_JobsRepo_decorators = [(0,
|
|
128
|
+
_JobsRepo_decorators = [(0, import_mongodb.Repository)()], _jobs_dec = [(0, import_mongodb.MongoCollection)({
|
|
130
129
|
idGeneration: "uuid",
|
|
131
130
|
name: "orionjs.jobs_dogs_records",
|
|
132
131
|
schema: JobRecordSchema,
|
|
@@ -188,9 +187,10 @@ var JobsRepo = class {
|
|
|
188
187
|
);
|
|
189
188
|
if (!job) return;
|
|
190
189
|
let tries = job.tries || 1;
|
|
191
|
-
|
|
190
|
+
const wasStale = Boolean(job.lockedUntil);
|
|
191
|
+
if (wasStale) {
|
|
192
192
|
import_logger.logger.info(`Running job "${job.jobName}" that was staled`);
|
|
193
|
-
this.jobs.updateOne(job._id, { $inc: { tries: 1 } });
|
|
193
|
+
await this.jobs.updateOne(job._id, { $inc: { tries: 1 } });
|
|
194
194
|
tries++;
|
|
195
195
|
}
|
|
196
196
|
return {
|
|
@@ -202,7 +202,8 @@ var JobsRepo = class {
|
|
|
202
202
|
tries,
|
|
203
203
|
lockTime,
|
|
204
204
|
priority: job.priority,
|
|
205
|
-
uniqueIdentifier: job.uniqueIdentifier
|
|
205
|
+
uniqueIdentifier: job.uniqueIdentifier,
|
|
206
|
+
wasStale
|
|
206
207
|
};
|
|
207
208
|
}
|
|
208
209
|
async setJobRecordPriority(jobId, priority) {
|
|
@@ -415,25 +416,25 @@ var import_logger3 = require("@orion-js/logger");
|
|
|
415
416
|
var import_services2 = require("@orion-js/services");
|
|
416
417
|
|
|
417
418
|
// src/repos/JobsHistoryRepo.ts
|
|
418
|
-
var
|
|
419
|
+
var import_mongodb2 = require("@orion-js/mongodb");
|
|
419
420
|
|
|
420
|
-
// ../../node_modules/.
|
|
421
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js
|
|
421
422
|
function _isInteger(n) {
|
|
422
423
|
return n << 0 === n;
|
|
423
424
|
}
|
|
424
425
|
var isInteger = Number.isInteger || _isInteger;
|
|
425
426
|
|
|
426
|
-
// ../../node_modules/.
|
|
427
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js
|
|
427
428
|
function createPath(path, delimiter = ".") {
|
|
428
429
|
return typeof path === "string" ? path.split(delimiter).map((x) => isInteger(x) ? Number(x) : x) : path;
|
|
429
430
|
}
|
|
430
431
|
|
|
431
|
-
// ../../node_modules/.
|
|
432
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js
|
|
432
433
|
function compare(a, b) {
|
|
433
434
|
return String(a) === String(b);
|
|
434
435
|
}
|
|
435
436
|
|
|
436
|
-
// ../../node_modules/.
|
|
437
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js
|
|
437
438
|
function includes(a, list) {
|
|
438
439
|
let index = -1;
|
|
439
440
|
const { length } = list;
|
|
@@ -443,7 +444,7 @@ function includes(a, list) {
|
|
|
443
444
|
return false;
|
|
444
445
|
}
|
|
445
446
|
|
|
446
|
-
// ../../node_modules/.
|
|
447
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/omit.js
|
|
447
448
|
function omit(propsToOmit, obj) {
|
|
448
449
|
if (arguments.length === 1) return (_obj) => omit(propsToOmit, _obj);
|
|
449
450
|
if (obj === null || obj === void 0)
|
|
@@ -479,7 +480,7 @@ var HistoryRecordSchema = (0, import_schema2.schemaWithName)("HistoryRecord", {
|
|
|
479
480
|
|
|
480
481
|
// src/repos/JobsHistoryRepo.ts
|
|
481
482
|
var _history_dec, _JobsHistoryRepo_decorators, _init3;
|
|
482
|
-
_JobsHistoryRepo_decorators = [(0,
|
|
483
|
+
_JobsHistoryRepo_decorators = [(0, import_mongodb2.Repository)()], _history_dec = [(0, import_mongodb2.MongoCollection)({
|
|
483
484
|
name: "orionjs.jobs_dogs_history",
|
|
484
485
|
idGeneration: "uuid",
|
|
485
486
|
schema: HistoryRecordSchema,
|
|
@@ -597,15 +598,19 @@ var Executor = class {
|
|
|
597
598
|
* Handles when a job has reached its maximum retry attempts.
|
|
598
599
|
* Marks the job in the database and invokes the onMaxTriesReached callback.
|
|
599
600
|
*/
|
|
600
|
-
async handleMaxTriesReached(jobToRun,
|
|
601
|
-
|
|
601
|
+
async handleMaxTriesReached(jobToRun, onMaxTriesReached) {
|
|
602
|
+
const jobLogger = import_logger3.logger.addMetadata({
|
|
603
|
+
jobName: jobToRun.name,
|
|
604
|
+
jobId: jobToRun.jobId
|
|
605
|
+
});
|
|
606
|
+
jobLogger.warn(
|
|
602
607
|
`Job "${jobToRun.name}" has reached max tries (${jobToRun.tries}). Marking as maxTriesReached.`
|
|
603
608
|
);
|
|
604
609
|
await this.jobsRepo.markJobAsMaxTriesReached(jobToRun.jobId);
|
|
605
610
|
try {
|
|
606
611
|
await onMaxTriesReached(jobToRun);
|
|
607
612
|
} catch (callbackError) {
|
|
608
|
-
|
|
613
|
+
jobLogger.error(`Error in onMaxTriesReached callback for job "${jobToRun.name}"`, {
|
|
609
614
|
error: callbackError
|
|
610
615
|
});
|
|
611
616
|
}
|
|
@@ -624,7 +629,7 @@ var Executor = class {
|
|
|
624
629
|
};
|
|
625
630
|
const handleRetry = async (nextRunAt) => {
|
|
626
631
|
if (jobToRun.tries >= effectiveMaxTries) {
|
|
627
|
-
await this.handleMaxTriesReached(jobToRun,
|
|
632
|
+
await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached);
|
|
628
633
|
return;
|
|
629
634
|
}
|
|
630
635
|
await this.jobsRepo.scheduleNextRun({
|
|
@@ -637,7 +642,7 @@ var Executor = class {
|
|
|
637
642
|
if (!job.onError) {
|
|
638
643
|
context.logger.error(`Error executing job "${jobToRun.name}"`, { error });
|
|
639
644
|
if (jobToRun.tries >= effectiveMaxTries) {
|
|
640
|
-
await this.handleMaxTriesReached(jobToRun,
|
|
645
|
+
await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached);
|
|
641
646
|
return;
|
|
642
647
|
}
|
|
643
648
|
await scheduleRecurrent();
|
|
@@ -700,6 +705,11 @@ var Executor = class {
|
|
|
700
705
|
async executeJob(config, jobToRun, respawnWorker) {
|
|
701
706
|
const job = this.getJobDefinition(jobToRun, config.jobs);
|
|
702
707
|
if (!job) return;
|
|
708
|
+
const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries);
|
|
709
|
+
if (jobToRun.wasStale && jobToRun.tries >= effectiveMaxTries) {
|
|
710
|
+
await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached);
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
703
713
|
const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun);
|
|
704
714
|
if (effectiveLockTime !== jobToRun.lockTime) {
|
|
705
715
|
await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime);
|
|
@@ -983,53 +993,58 @@ var defineJob = (options) => {
|
|
|
983
993
|
// src/service/index.ts
|
|
984
994
|
var serviceMetadata = /* @__PURE__ */ new WeakMap();
|
|
985
995
|
var jobsMetadata = /* @__PURE__ */ new Map();
|
|
996
|
+
var jobEntriesByClass = /* @__PURE__ */ new Map();
|
|
997
|
+
var pendingJobEntries = {};
|
|
986
998
|
function Jobs() {
|
|
987
999
|
return (target, context) => {
|
|
988
1000
|
(0, import_services4.Service)()(target, context);
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1001
|
+
serviceMetadata.set(target, { _serviceType: "jobs" });
|
|
1002
|
+
if (Object.keys(pendingJobEntries).length > 0) {
|
|
1003
|
+
jobEntriesByClass.set(target, pendingJobEntries);
|
|
1004
|
+
pendingJobEntries = {};
|
|
1005
|
+
}
|
|
992
1006
|
};
|
|
993
1007
|
}
|
|
994
1008
|
function RecurrentJob(options = {}) {
|
|
995
1009
|
return (method, context) => {
|
|
996
1010
|
const propertyKey = String(context.name);
|
|
997
|
-
context.
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
jobs[propertyKey] = this[propertyKey];
|
|
1008
|
-
}
|
|
1009
|
-
jobsMetadata.set(this, jobs);
|
|
1010
|
-
});
|
|
1011
|
+
if (context.kind === "method") {
|
|
1012
|
+
pendingJobEntries[propertyKey] = (instance) => defineJob({
|
|
1013
|
+
...options,
|
|
1014
|
+
type: "recurrent",
|
|
1015
|
+
resolve: instance[propertyKey].bind(instance)
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
if (context.kind === "field") {
|
|
1019
|
+
pendingJobEntries[propertyKey] = (instance) => instance[propertyKey];
|
|
1020
|
+
}
|
|
1011
1021
|
return method;
|
|
1012
1022
|
};
|
|
1013
1023
|
}
|
|
1014
1024
|
function EventJob(options = {}) {
|
|
1015
1025
|
return (method, context) => {
|
|
1016
1026
|
const propertyKey = String(context.name);
|
|
1017
|
-
context.
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
jobs[propertyKey] = this[propertyKey];
|
|
1027
|
-
}
|
|
1028
|
-
jobsMetadata.set(this, jobs);
|
|
1029
|
-
});
|
|
1027
|
+
if (context.kind === "method") {
|
|
1028
|
+
pendingJobEntries[propertyKey] = (instance) => createEventJob({
|
|
1029
|
+
...options,
|
|
1030
|
+
resolve: instance[propertyKey].bind(instance)
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
if (context.kind === "field") {
|
|
1034
|
+
pendingJobEntries[propertyKey] = (instance) => instance[propertyKey];
|
|
1035
|
+
}
|
|
1030
1036
|
return method;
|
|
1031
1037
|
};
|
|
1032
1038
|
}
|
|
1039
|
+
function initializeJobsIfNeeded(instance) {
|
|
1040
|
+
if (jobsMetadata.has(instance)) return;
|
|
1041
|
+
const entries = jobEntriesByClass.get(instance.constructor) || {};
|
|
1042
|
+
const jobs = {};
|
|
1043
|
+
for (const [key, setup] of Object.entries(entries)) {
|
|
1044
|
+
jobs[key] = setup(instance);
|
|
1045
|
+
}
|
|
1046
|
+
jobsMetadata.set(instance, jobs);
|
|
1047
|
+
}
|
|
1033
1048
|
function getServiceJobs(target) {
|
|
1034
1049
|
const instance = (0, import_services4.getInstance)(target);
|
|
1035
1050
|
if (!serviceMetadata.has(instance.constructor)) {
|
|
@@ -1039,6 +1054,7 @@ function getServiceJobs(target) {
|
|
|
1039
1054
|
if (instanceMetadata._serviceType !== "jobs") {
|
|
1040
1055
|
throw new Error("You must pass a class decorated with @Jobs to getServiceJobs");
|
|
1041
1056
|
}
|
|
1057
|
+
initializeJobsIfNeeded(instance);
|
|
1042
1058
|
const jobsMap = jobsMetadata.get(instance) || {};
|
|
1043
1059
|
return jobsMap;
|
|
1044
1060
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/services/EventsService.ts","../src/repos/JobsRepo.ts","../src/types/JobRecord.ts","../src/services/getNextRunDate.ts","../src/services/WorkerService.ts","../src/services/Executor.ts","../src/repos/JobsHistoryRepo.ts","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/omit.js","../src/types/HistoryRecord.ts","../src/service/index.ts","../src/defineJob/index.ts"],"sourcesContent":["import {getInstance} from '@orion-js/services'\nimport {EventsService} from './services/EventsService'\nimport {WorkerService} from './services/WorkerService'\nimport {StartWorkersConfig} from './types/StartConfig'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from './types/Events'\nimport {JobsHistoryRepo} from './repos/JobsHistoryRepo'\nimport {JobsRepo} from './repos/JobsRepo'\nimport {SchemaInAnyOrionForm} from '@orion-js/schema'\n\nexport * from './types'\nexport * from './service'\nexport * from './defineJob'\n\nconst workerService = getInstance(WorkerService)\nconst eventsService = getInstance(EventsService)\nconst jobsHistoryRepo = getInstance(JobsHistoryRepo)\nconst jobsRepo = getInstance(JobsRepo)\n\nconst startWorkers = (config: StartWorkersConfig) => {\n return workerService.startWorkers(config)\n}\n\n/**\n * @deprecated Use the event job definition.schedule method instead.\n */\nconst scheduleJob = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n options: ScheduleJobOptions<TParamsSchema>,\n) => {\n return eventsService.scheduleJob(options)\n}\n\n/**\n * Schedule multiple jobs at once for better performance.\n * @deprecated Use the event job definition.scheduleJobs method instead.\n */\nconst scheduleJobs = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n jobs: ScheduleJobsOptions<TParamsSchema>,\n): Promise<ScheduleJobsResult> => {\n return eventsService.scheduleJobs(jobs)\n}\n\nexport {startWorkers, scheduleJob, scheduleJobs, jobsHistoryRepo, jobsRepo}\n","import {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from '../types/Events'\nimport {getNextRunDate} from './getNextRunDate'\n\n@Service()\nexport class EventsService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n async scheduleJob(options: ScheduleJobOptions) {\n logger.debug('Scheduling job...', options)\n\n await this.jobsRepo.scheduleJob({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n })\n }\n\n async scheduleJobs(jobs: ScheduleJobsOptions): Promise<ScheduleJobsResult> {\n logger.debug(`Scheduling ${jobs.length} jobs...`)\n\n const jobRecords = jobs.map(options => ({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n }))\n\n return await this.jobsRepo.scheduleJobs(jobRecords)\n }\n}\n","import {generateId} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Collection, MongoDB, MongoCollection} from '@orion-js/mongodb'\nimport {ScheduleJobRecordOptions, ScheduleJobsResult} from '../types/Events'\nimport {JobRecord} from '../types/JobRecord'\nimport {JobDefinitionWithName, RecurrentJobDefinition} from '../types/JobsDefinition'\nimport {JobToRun} from '../types/Worker'\nimport {Repository} from '@orion-js/mongodb'\nimport {JobRecordSchema} from '../types/JobRecord'\n\n@Repository()\nexport class JobsRepo {\n @MongoCollection({\n idGeneration: 'uuid',\n name: 'orionjs.jobs_dogs_records',\n schema: JobRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n priority: -1,\n nextRunAt: 1,\n },\n },\n {\n keys: {\n jobName: 1,\n },\n options: {\n unique: true,\n partialFilterExpression: {type: 'recurrent'},\n },\n },\n {\n keys: {\n uniqueIdentifier: 1,\n },\n options: {\n unique: true,\n sparse: true,\n },\n },\n ],\n })\n jobs: Collection<JobRecord>\n\n async getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun> {\n const lockedUntil = new Date(Date.now() + lockTime)\n\n const job = await this.jobs.findOneAndUpdate(\n {\n jobName: {$in: jobNames},\n nextRunAt: {$lte: new Date()},\n $or: [{lockedUntil: {$exists: false}}, {lockedUntil: {$lte: new Date()}}],\n // Exclude jobs that have reached max tries. Using $ne handles backwards compatibility\n // since records without the status field will still match (undefined !== 'maxTriesReached')\n status: {$ne: 'maxTriesReached'},\n },\n {\n $set: {lockedUntil, lastRunAt: new Date()},\n },\n {\n mongoOptions: {\n sort: {\n priority: -1,\n nextRunAt: 1,\n },\n returnDocument: 'before',\n },\n },\n )\n\n if (!job) return\n\n let tries = job.tries || 1\n\n if (job.lockedUntil) {\n logger.info(`Running job \"${job.jobName}\" that was staled`)\n this.jobs.updateOne(job._id, {$inc: {tries: 1}})\n tries++\n }\n\n return {\n jobId: job._id,\n executionId: generateId(),\n name: job.jobName,\n params: job.params,\n type: job.type,\n tries,\n lockTime,\n priority: job.priority,\n uniqueIdentifier: job.uniqueIdentifier,\n }\n }\n\n async setJobRecordPriority(jobId: string, priority: number) {\n await this.jobs.updateOne(jobId, {$set: {priority}})\n }\n\n async scheduleNextRun(options: {\n jobId: string\n nextRunAt: Date\n addTries: boolean\n priority: number\n }) {\n const updator: MongoDB.UpdateFilter<JobRecord> = {\n $set: {\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n ...(options.addTries ? {} : {tries: 0}),\n },\n $unset: {lockedUntil: ''},\n ...(options.addTries ? {$inc: {tries: 1}} : {}),\n }\n\n await this.jobs.updateOne(options.jobId, updator)\n }\n\n async deleteEventJob(jobId: string) {\n await this.jobs.deleteOne({_id: jobId, type: 'event'})\n }\n\n /**\n * Marks a job as having reached its maximum tries limit.\n * The job will remain in the database but won't be picked up for execution.\n */\n async markJobAsMaxTriesReached(jobId: string) {\n await this.jobs.updateOne(\n {_id: jobId},\n {\n $set: {status: 'maxTriesReached'},\n $unset: {lockedUntil: ''},\n },\n )\n }\n\n async extendLockTime(jobId: string, extraTime: number) {\n await this.updateLockTime(jobId, extraTime)\n }\n\n /**\n * Updates the lock time for a job to the specified duration from now.\n * Can be used to both extend or shorten the lock time.\n */\n async updateLockTime(jobId: string, lockDuration: number) {\n const lockedUntil = new Date(Date.now() + lockDuration)\n await this.jobs.updateOne(\n {\n _id: jobId,\n },\n {\n $set: {lockedUntil},\n },\n )\n }\n\n async unlockAllJobs(): Promise<number> {\n const result = await this.jobs.updateMany(\n {\n lockedUntil: {$exists: true},\n },\n {\n $unset: {lockedUntil: ''},\n },\n )\n\n return result.modifiedCount\n }\n\n async ensureJobRecord(job: JobDefinitionWithName) {\n const result = await this.jobs.upsert(\n {\n jobName: job.name,\n },\n {\n $set: {\n type: job.type,\n priority: (job as RecurrentJobDefinition).priority,\n },\n $setOnInsert: {\n nextRunAt: new Date(),\n },\n },\n )\n\n if (result.upsertedId) {\n logger.debug(`Created job record for \"${job.name}\"`)\n } else {\n logger.debug(`Record for job \"${job.name}\" already exists`)\n }\n }\n\n async scheduleJob(options: ScheduleJobRecordOptions) {\n try {\n await this.jobs.insertOne({\n jobName: options.name,\n uniqueIdentifier: options.uniqueIdentifier,\n params: options.params,\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n type: 'event',\n })\n } catch (error) {\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n options.uniqueIdentifier\n ) {\n logger.info(\n `Job \"${options.name}\" with identifier \"${options.uniqueIdentifier}\" already exists`,\n )\n } else {\n throw error\n }\n }\n }\n\n async scheduleJobs(jobs: ScheduleJobRecordOptions[]): Promise<ScheduleJobsResult> {\n if (jobs.length === 0) {\n return {scheduledCount: 0, skippedCount: 0, errors: []}\n }\n\n // Process each job individually to handle errors properly\n let scheduledCount = 0\n let skippedCount = 0\n const errors: Array<{index: number; error: Error; job: ScheduleJobRecordOptions}> = []\n\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i]\n try {\n // Insert directly to get better error handling than the single scheduleJob method\n await this.jobs.insertOne({\n jobName: job.name,\n uniqueIdentifier: job.uniqueIdentifier,\n params: job.params,\n nextRunAt: job.nextRunAt,\n priority: job.priority,\n type: 'event',\n })\n scheduledCount++\n } catch (error) {\n // Check if it's a validation error with uniqueIdentifier constraint\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n job.uniqueIdentifier\n ) {\n logger.info(`Job \"${job.name}\" with identifier \"${job.uniqueIdentifier}\" already exists`)\n skippedCount++\n } else {\n errors.push({\n index: i,\n error: error instanceof Error ? error : new Error(String(error)),\n job,\n })\n }\n }\n }\n\n logger.debug(\n `Scheduled ${scheduledCount} jobs successfully, skipped ${skippedCount}, errors: ${errors.length}`,\n )\n\n return {\n scheduledCount,\n skippedCount,\n errors,\n }\n }\n}\n","import {createEnum, InferSchemaType, schemaWithName} from '@orion-js/schema'\n\n/**\n * Enum representing the status of a job record.\n * - 'pending': Job is active and can be executed (default for existing records)\n * - 'maxTriesReached': Job has exhausted all retry attempts and won't be executed\n */\nexport const JobStatusEnum = createEnum('JobStatus', ['pending', 'maxTriesReached'])\n\nexport const JobRecordSchema = schemaWithName('JobRecord', {\n _id: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: createEnum('JobType', ['recurrent', 'event'])},\n priority: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n nextRunAt: {type: 'date'},\n lastRunAt: {type: 'date', optional: true},\n lockedUntil: {type: 'date', optional: true},\n tries: {type: 'number', optional: true},\n params: {type: 'blackbox', optional: true},\n /**\n * Status of the job. Optional for backwards compatibility with existing records.\n * Records without this field are treated as 'pending'.\n */\n status: {type: JobStatusEnum, optional: true},\n})\n\nexport type JobRecord = InferSchemaType<typeof JobRecordSchema>\n","export type Options = {\n getNextRun?: () => Date\n runIn?: number\n runEvery?: number\n runAt?: Date\n} & {[key: string]: any}\n\nexport const getNextRunDate = (options: Options) => {\n if (options.runIn) {\n return new Date(Date.now() + options.runIn)\n }\n\n if (options.runEvery) {\n return new Date(Date.now() + options.runEvery)\n }\n\n if (options.runAt) {\n return options.runAt\n }\n\n if (options.getNextRun) {\n return options.getNextRun()\n }\n\n return new Date()\n}\n","import {sleep} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinitionWithName, JobsDefinition} from '../types/JobsDefinition'\nimport {StartWorkersConfig} from '../types/StartConfig'\nimport {WorkerInstance, WorkersInstance} from '../types/Worker'\nimport {ExecuteJobConfig, Executor} from './Executor'\n\n@Service()\nexport class WorkerService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n @Inject(() => Executor)\n private executor: Executor\n\n getJobNames(jobs: JobsDefinition) {\n return Object.keys(jobs)\n }\n\n getJobs(jobs: JobsDefinition): JobDefinitionWithName[] {\n return Object.keys(jobs).map(name => {\n return {\n name,\n ...jobs[name],\n }\n })\n }\n\n async runWorkerLoop(\n config: StartWorkersConfig,\n workerInstance: WorkerInstance,\n jobNames: string[],\n executeConfig: ExecuteJobConfig,\n ) {\n const jobToRun = await this.jobsRepo.getJobAndLock(jobNames, config.defaultLockTime)\n if (!jobToRun) {\n logger.debug('No job to run')\n return false\n }\n\n logger.debug(`Got job [w${workerInstance.workerIndex}] to run:`, jobToRun)\n\n await this.executor.executeJob(executeConfig, jobToRun, workerInstance.respawn)\n\n return true\n }\n\n async startWorker(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n const names = this.getJobNames(config.jobs)\n logger.debug(\n `Running worker loop [w${workerInstance.workerIndex}] for jobs \"${names.join(', ')}\"...`,\n )\n const executeConfig: ExecuteJobConfig = {\n jobs: config.jobs,\n maxTries: config.maxTries,\n onMaxTriesReached: config.onMaxTriesReached,\n }\n\n while (true) {\n if (!workerInstance.running) {\n logger.info(`Got signal to stop. Stopping worker [w${workerInstance.workerIndex}]...`)\n return\n }\n\n try {\n const didRun = await this.runWorkerLoop(config, workerInstance, names, executeConfig)\n if (!didRun) await sleep(config.pollInterval)\n if (didRun) await sleep(config.cooldownPeriod)\n } catch (error) {\n logger.error('Error in job runner.', {error})\n await sleep(config.pollInterval)\n }\n }\n }\n\n createWorkersInstanceDefinition(config: StartWorkersConfig): WorkersInstance {\n const workersInstance: WorkersInstance = {\n running: true,\n workersCount: config.workersCount,\n workers: [],\n stop: async () => {\n logger.info('Stopping workers...')\n workersInstance.running = false\n const stopingPromises = workersInstance.workers.map(worker => worker.stop())\n await Promise.all(stopingPromises)\n },\n }\n\n return workersInstance\n }\n\n async ensureRecords(config: StartWorkersConfig) {\n const jobs = this.getJobs(config.jobs)\n\n await Promise.all(\n jobs\n .filter(job => job.type === 'recurrent')\n .map(async job => {\n logger.debug(`Ensuring records for job \"${job.name}\"...`)\n await this.jobsRepo.ensureJobRecord(job)\n }),\n )\n }\n\n async startANewWorker(\n config: StartWorkersConfig,\n workersInstance: WorkersInstance,\n workerIndex = workersInstance.workers.length,\n ) {\n if (!workersInstance.running) {\n return\n }\n\n const workerInstance: WorkerInstance = {\n running: true,\n workerIndex,\n stop: async () => {\n logger.info(`Stopping worker [w${workerIndex}]...`)\n workerInstance.running = false\n await workerInstance.promise\n },\n respawn: async () => {\n logger.info(`Respawning worker [w${workerIndex}]...`)\n workerInstance.running = false\n await this.startANewWorker(config, workersInstance, workerIndex)\n },\n }\n\n const workerPromise = this.startWorker(config, workerInstance)\n\n workerInstance.promise = workerPromise\n workersInstance.workers[workerIndex] = workerInstance\n }\n\n async runWorkers(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n logger.debug('Will ensure records for recurrent jobs')\n await this.ensureRecords(config)\n\n const workersCount = config.workersCount\n const workerWord = workersCount === 1 ? 'worker' : 'workers'\n logger.info(`Starting ${workersCount} ${workerWord}`)\n\n for (let workerIndex = 0; workerIndex < workersCount; workerIndex++) {\n this.startANewWorker(config, workersInstance, workerIndex)\n }\n }\n\n /**\n * Starts the job workers with the provided configuration.\n * @param userConfig - Configuration for the workers. Required fields: jobs, maxTries, onMaxTriesReached\n */\n startWorkers(userConfig: StartWorkersConfig): WorkersInstance {\n // Apply defaults for optional fields\n const config: StartWorkersConfig = {\n cooldownPeriod: 100,\n pollInterval: 3000,\n workersCount: 4,\n defaultLockTime: 30 * 1000,\n ...userConfig,\n }\n\n setNameToJobs(config.jobs)\n\n const workersInstance = this.createWorkersInstanceDefinition(config)\n logger.debug('Starting workers', config)\n\n this.runWorkers(config, workersInstance)\n\n return workersInstance\n }\n}\n\nfunction setNameToJobs(jobs: JobsDefinition) {\n for (const name of Object.keys(jobs)) {\n jobs[name].jobName = name\n }\n}\n","import {SpanStatusCode, trace} from '@opentelemetry/api'\nimport {logger, runWithOrionAsyncContext, updateOrionAsyncContext} from '@orion-js/logger'\nimport {Blackbox} from '@orion-js/schema'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsHistoryRepo} from '../repos/JobsHistoryRepo'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinition, JobsDefinition} from '../types/JobsDefinition'\nimport {ExecutionContext, JobToRun} from '../types/Worker'\nimport {getNextRunDate} from './getNextRunDate'\n\n/**\n * Configuration for job execution including max tries settings.\n */\nexport interface ExecuteJobConfig {\n jobs: JobsDefinition\n maxTries: number\n onMaxTriesReached: (job: JobToRun) => Promise<void>\n}\n\n@Service()\nexport class Executor {\n @Inject(() => JobsRepo)\n private readonly jobsRepo: JobsRepo\n\n @Inject(() => JobsHistoryRepo)\n private readonly jobsHistoryRepo: JobsHistoryRepo\n\n /**\n * Determines the effective lock time for a job execution.\n * Job-specific lockTime takes precedence over the default lockTime from config.\n */\n getEffectiveLockTime(job: JobDefinition, jobToRun: JobToRun): number {\n return job.lockTime ?? jobToRun.lockTime\n }\n\n getContext(job: JobDefinition, jobToRun: JobToRun, onStale: Function): ExecutionContext {\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n let staleTimeout = setTimeout(() => onStale(), effectiveLockTime)\n staleTimeout.unref?.()\n return {\n definition: job,\n record: jobToRun,\n tries: jobToRun.tries || 0,\n clearStaleTimeout: () => clearTimeout(staleTimeout),\n extendLockTime: async (extraTime: number) => {\n clearTimeout(staleTimeout)\n staleTimeout = setTimeout(() => onStale(), extraTime)\n staleTimeout.unref?.()\n await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime)\n },\n logger: logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n }),\n }\n }\n\n getJobDefinition(jobToRun: JobToRun, jobs: JobsDefinition) {\n const job = jobs[jobToRun.name]\n\n if (jobToRun.type !== job.type) {\n logger.warn(\n `Job record \"${jobToRun.name}\" is \"${jobToRun.type}\" but definition is \"${job.type}\"`,\n )\n return\n }\n\n return job\n }\n\n /**\n * Determines the effective max tries for a job.\n * Job-specific maxTries takes precedence over the global maxTries from config.\n */\n getEffectiveMaxTries(job: JobDefinition, globalMaxTries: number): number {\n return job.maxTries ?? globalMaxTries\n }\n\n /**\n * Handles when a job has reached its maximum retry attempts.\n * Marks the job in the database and invokes the onMaxTriesReached callback.\n */\n async handleMaxTriesReached(\n jobToRun: JobToRun,\n context: ExecutionContext,\n onMaxTriesReached: (job: JobToRun) => Promise<void>,\n ) {\n context.logger.warn(\n `Job \"${jobToRun.name}\" has reached max tries (${jobToRun.tries}). Marking as maxTriesReached.`,\n )\n await this.jobsRepo.markJobAsMaxTriesReached(jobToRun.jobId)\n\n // Invoke the callback to notify administrators\n try {\n await onMaxTriesReached(jobToRun)\n } catch (callbackError) {\n context.logger.error(`Error in onMaxTriesReached callback for job \"${jobToRun.name}\"`, {\n error: callbackError,\n })\n }\n }\n\n async onError(\n error: unknown,\n job: JobDefinition,\n jobToRun: JobToRun,\n context: ExecutionContext,\n config: ExecuteJobConfig,\n ) {\n const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries)\n\n // Helper to schedule next run for recurrent jobs (used when dismissing)\n const scheduleRecurrent = async () => {\n if (job.type === 'recurrent') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n }\n\n // Helper to handle retry with max tries check\n const handleRetry = async (nextRunAt: Date) => {\n // Check if we've reached max tries before scheduling another retry\n if (jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, context, config.onMaxTriesReached)\n return\n }\n\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt,\n addTries: true,\n priority: job.type === 'recurrent' ? job.priority : jobToRun.priority,\n })\n }\n\n // If no custom error handler, check max tries and schedule recurrent if applicable\n if (!job.onError) {\n context.logger.error(`Error executing job \"${jobToRun.name}\"`, {error})\n\n // For jobs without onError, check if max tries reached\n if (jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, context, config.onMaxTriesReached)\n return\n }\n\n await scheduleRecurrent()\n return\n }\n\n context.logger.info(`Error executing job \"${jobToRun.name}\"`, {error})\n const result = await job.onError(\n error instanceof Error ? error : new Error(String(error)),\n jobToRun.params,\n context,\n )\n\n if (result.action === 'dismiss') {\n await scheduleRecurrent()\n return\n }\n\n if (result.action === 'retry') {\n await handleRetry(getNextRunDate(result))\n }\n }\n\n async saveExecution(options: {\n startedAt: Date\n status: 'stale' | 'error' | 'success'\n errorMessage?: string\n result?: Blackbox\n job: JobDefinition\n jobToRun: JobToRun\n }) {\n const {startedAt, status, errorMessage, result, job, jobToRun} = options\n const endedAt = new Date()\n\n if (job.saveExecutionsFor !== 0) {\n const oneWeek = 1000 * 60 * 60 * 24 * 7\n const saveExecutionsFor = job.saveExecutionsFor || oneWeek\n await this.jobsHistoryRepo.saveExecution({\n jobId: jobToRun.jobId,\n executionId: jobToRun.executionId,\n jobName: jobToRun.name,\n type: jobToRun.type,\n priority: jobToRun.priority,\n tries: jobToRun.tries,\n uniqueIdentifier: jobToRun.uniqueIdentifier,\n startedAt,\n endedAt,\n duration: endedAt.getTime() - startedAt.getTime(),\n expiresAt: new Date(Date.now() + saveExecutionsFor),\n status,\n errorMessage,\n params: jobToRun.params,\n result,\n })\n }\n }\n\n async afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n if (job.type === 'recurrent') {\n context.logger.debug(`Scheduling next run for recurrent job \"${jobToRun.name}\"`)\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n if (job.type === 'event') {\n context.logger.debug(`Removing event job after success \"${jobToRun.name}\"`)\n await this.jobsRepo.deleteEventJob(jobToRun.jobId)\n }\n }\n\n async executeJob(config: ExecuteJobConfig, jobToRun: JobToRun, respawnWorker: () => void) {\n const job = this.getJobDefinition(jobToRun, config.jobs)\n if (!job) return\n\n // If job has a custom lockTime different from the default, update the database lock\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n if (effectiveLockTime !== jobToRun.lockTime) {\n await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime)\n }\n\n const tracer = trace.getTracer('orionjs.dogs', '1.0')\n\n await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async span => {\n try {\n const startedAt = new Date()\n\n const onStale = async () => {\n if (job.onStale) {\n context.logger.info(`Job \"${jobToRun.name}\" is stale`)\n job.onStale(jobToRun.params, context)\n } else {\n context.logger.error(`Job \"${jobToRun.name}\" is stale`)\n }\n\n await this.jobsRepo.setJobRecordPriority(jobToRun.jobId, 0)\n\n void respawnWorker()\n\n void this.saveExecution({\n startedAt,\n status: 'stale',\n result: null,\n errorMessage: null,\n job,\n jobToRun,\n }).catch(error => {\n context.logger.error('Error saving stale execution history', {error})\n })\n }\n\n const context = this.getContext(job, jobToRun, onStale)\n\n const extraContext = {\n controllerType: 'job' as const,\n jobName: jobToRun.name,\n params: jobToRun.params,\n }\n\n await runWithOrionAsyncContext(extraContext, async () => {\n try {\n // Inject async context update\n updateOrionAsyncContext({\n jobName: jobToRun.name,\n params: jobToRun.params,\n })\n const result = await job.resolve(jobToRun.params, context)\n context.clearStaleTimeout()\n\n void this.saveExecution({\n startedAt,\n status: 'success',\n result: result || null,\n errorMessage: null,\n job,\n jobToRun,\n }).catch(error => {\n context.logger.error('Error saving successful execution history', {error})\n })\n\n await this.afterExecutionSuccess(job, jobToRun, context)\n } catch (error) {\n context.clearStaleTimeout()\n void this.saveExecution({\n startedAt,\n status: 'error',\n result: null,\n errorMessage: (error as Error).message,\n job,\n jobToRun,\n }).catch(saveError => {\n context.logger.error('Error saving failed execution history', {error: saveError})\n })\n\n await this.onError(error, job, jobToRun, context, config)\n }\n })\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: (error as Error).message,\n })\n throw error\n } finally {\n span.end()\n }\n })\n }\n}\n","import {Collection, MongoCollection, Repository, MongoDB} from '@orion-js/mongodb'\nimport {omit} from 'rambdax'\nimport {HistoryRecord, HistoryRecordSchema} from '../types/HistoryRecord'\n\n@Repository()\nexport class JobsHistoryRepo {\n @MongoCollection({\n name: 'orionjs.jobs_dogs_history',\n idGeneration: 'uuid',\n schema: HistoryRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n startedAt: 1,\n },\n },\n {\n keys: {\n executionId: 1,\n },\n },\n {\n keys: {\n expiresAt: 1,\n },\n options: {\n expireAfterSeconds: 0,\n },\n },\n ],\n })\n history: Collection<HistoryRecord>\n\n async saveExecution(record: MongoDB.WithoutId<HistoryRecord>) {\n await this.history.upsert(\n {executionId: record.executionId},\n {\n $setOnInsert: {\n status: record.status,\n },\n $set: {\n ...omit(['status'], record),\n },\n },\n )\n }\n\n async getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]> {\n const cursor = this.history.find({jobName}).sort({startedAt: -1})\n\n if (skip) {\n cursor.skip(skip)\n }\n\n if (limit) {\n cursor.limit(limit)\n }\n\n return await cursor.toArray()\n }\n}\n","function _isInteger(n){\n return n << 0 === n\n}\n\nexport const isInteger = Number.isInteger || _isInteger\n\n/**\n * Check if `index` is integer even if it is a string.\n */\nexport const isIndexInteger = index => Number.isInteger(Number(index))\n","import { isInteger } from './isInteger.js'\n\nexport function createPath(path, delimiter = '.'){\n return typeof path === 'string' ?\n path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) :\n path\n}\n","export function compare(a, b){\n return String(a) === String(b)\n}\n","import { compare } from './compare.js'\n\nexport function includes(a, list){\n let index = -1\n const { length } = list\n\n while (++index < length)\n if (compare(list[ index ], a))\n return true\n\n return false\n}\n","import { createPath } from './_internals/createPath.js'\nimport { includes } from './_internals/includes.js'\n\nexport function omit(propsToOmit, obj){\n if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)\n\n if (obj === null || obj === undefined)\n return undefined\n\n const propsToOmitValue = createPath(propsToOmit, ',')\n const willReturn = {}\n\n for (const key in obj)\n if (!includes(key, propsToOmitValue))\n willReturn[ key ] = obj[ key ]\n\n return willReturn\n}\n","import {InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const HistoryRecordSchema = schemaWithName('HistoryRecord', {\n _id: {type: 'string'},\n jobId: {type: 'string'},\n executionId: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: 'string'},\n priority: {type: 'number'},\n tries: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n startedAt: {type: 'date'},\n endedAt: {type: 'date'},\n duration: {type: 'number'},\n expiresAt: {type: 'date', optional: true},\n status: {type: 'string', enum: ['success', 'error', 'stale']},\n errorMessage: {type: 'string', optional: true},\n params: {type: 'blackbox', optional: true},\n result: {type: 'any', optional: true},\n})\n\nexport type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>\n","import {getInstance, Service} from '@orion-js/services'\nimport {createEventJob, defineJob} from '../defineJob'\nimport type {CreateEventJobOptions, JobDefinition, RecurrentJobDefinition} from '../types'\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst jobsMetadata = new Map<any, Record<string, any>>()\n\nexport function Jobs() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n Service()(target, context)\n\n context.addInitializer(function (this) {\n serviceMetadata.set(this, {_serviceType: 'jobs'})\n })\n }\n}\n\nexport function RecurrentJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function RecurrentJob(\n options: Omit<RecurrentJobDefinition, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function RecurrentJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = defineJob({\n ...options,\n type: 'recurrent',\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function EventJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EventJob(\n options: Omit<CreateEventJobOptions<any>, 'resolve'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EventJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = createEventJob({\n ...options,\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function getServiceJobs(target: any): {\n [key: string]: JobDefinition\n} {\n const instance = getInstance(target)\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'jobs') {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const jobsMap = jobsMetadata.get(instance) || {}\n\n return jobsMap\n}\n\n/**\n * Logs\n * after event job {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n}\nbefore recurrent job Map(1) {\n ExampleJobsService {} => {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n }\n}\nbefore recurrent job undefined\nafter recurrent job {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n}\n{\n serviceJobs: {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n }\n}\n */\n","import {\n CreateEventJobOptions,\n CreateJobOptions,\n CreateRecurrentJobOptions,\n EventJobDefinition,\n JobDefinition,\n RecurrentJobDefinition,\n} from '../types/JobsDefinition'\nimport {scheduleJob, ScheduleJobsResult, scheduleJobs} from '..'\nimport {ScheduleJobOptionsWithoutName} from '../types/Events'\nimport {cleanAndValidate, SchemaInAnyOrionForm} from '@orion-js/schema'\nimport parse from 'parse-duration'\n\nexport function createEventJob<TParamsSchema extends SchemaInAnyOrionForm>(\n options: CreateEventJobOptions<TParamsSchema>,\n): EventJobDefinition<TParamsSchema> {\n const jobDefinition: EventJobDefinition<TParamsSchema> = {\n ...options,\n type: 'event',\n schedule: null,\n scheduleJobs: null,\n }\n\n jobDefinition.schedule = async (scheduleOptions: ScheduleJobOptionsWithoutName<TParamsSchema>) => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return await scheduleJob({\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n })\n }\n\n jobDefinition.scheduleJobs = async (\n jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>,\n ): Promise<ScheduleJobsResult> => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n // Process all job parameters if schema validation is needed\n const processedJobs = await Promise.all(\n jobs.map(async scheduleOptions => {\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return {\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n }\n }),\n )\n\n return await scheduleJobs(processedJobs)\n }\n\n return jobDefinition\n}\n\nexport function createRecurrentJob(options: CreateRecurrentJobOptions): RecurrentJobDefinition {\n const jobDefinition: RecurrentJobDefinition = {\n ...options,\n priority: options.priority ?? 100,\n type: 'recurrent',\n runEvery: typeof options.runEvery === 'string' ? parse(options.runEvery) : options.runEvery,\n }\n\n return jobDefinition\n}\n\n/**\n * @deprecated Use `createEventJob` or `createRecurrentJob` instead.\n */\nexport const defineJob = (\n options: CreateJobOptions & {type: 'event' | 'recurrent'},\n): JobDefinition => {\n return options.type === 'event'\n ? createEventJob(options as any)\n : createRecurrentJob(options as any)\n}\n"],"mappings":"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","names":["import_services","import_logger","import_mongodb","_init","import_helpers","import_logger","import_services","import_logger","import_services","import_mongodb","import_schema","_init","_jobsRepo_dec","_init","_a","_jobsRepo_dec","_init","import_services","import_schema","parse"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/services/EventsService.ts","../src/repos/JobsRepo.ts","../src/types/JobRecord.ts","../src/services/getNextRunDate.ts","../src/services/WorkerService.ts","../src/services/Executor.ts","../src/repos/JobsHistoryRepo.ts","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/omit.js","../src/types/HistoryRecord.ts","../src/service/index.ts","../src/defineJob/index.ts"],"sourcesContent":["import {getInstance} from '@orion-js/services'\nimport {EventsService} from './services/EventsService'\nimport {WorkerService} from './services/WorkerService'\nimport {StartWorkersConfig} from './types/StartConfig'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from './types/Events'\nimport {JobsHistoryRepo} from './repos/JobsHistoryRepo'\nimport {JobsRepo} from './repos/JobsRepo'\nimport {SchemaInAnyOrionForm} from '@orion-js/schema'\n\nexport * from './types'\nexport * from './service'\nexport * from './defineJob'\n\nconst workerService = getInstance(WorkerService)\nconst eventsService = getInstance(EventsService)\nconst jobsHistoryRepo = getInstance(JobsHistoryRepo)\nconst jobsRepo = getInstance(JobsRepo)\n\nconst startWorkers = (config: StartWorkersConfig) => {\n return workerService.startWorkers(config)\n}\n\n/**\n * @deprecated Use the event job definition.schedule method instead.\n */\nconst scheduleJob = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n options: ScheduleJobOptions<TParamsSchema>,\n) => {\n return eventsService.scheduleJob(options)\n}\n\n/**\n * Schedule multiple jobs at once for better performance.\n * @deprecated Use the event job definition.scheduleJobs method instead.\n */\nconst scheduleJobs = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n jobs: ScheduleJobsOptions<TParamsSchema>,\n): Promise<ScheduleJobsResult> => {\n return eventsService.scheduleJobs(jobs)\n}\n\nexport {startWorkers, scheduleJob, scheduleJobs, jobsHistoryRepo, jobsRepo}\n","import {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from '../types/Events'\nimport {getNextRunDate} from './getNextRunDate'\n\n@Service()\nexport class EventsService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n async scheduleJob(options: ScheduleJobOptions) {\n logger.debug('Scheduling job...', options)\n\n await this.jobsRepo.scheduleJob({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n })\n }\n\n async scheduleJobs(jobs: ScheduleJobsOptions): Promise<ScheduleJobsResult> {\n logger.debug(`Scheduling ${jobs.length} jobs...`)\n\n const jobRecords = jobs.map(options => ({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n }))\n\n return await this.jobsRepo.scheduleJobs(jobRecords)\n }\n}\n","import {generateId} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Collection, MongoCollection, MongoDB, Repository} from '@orion-js/mongodb'\nimport {ScheduleJobRecordOptions, ScheduleJobsResult} from '../types/Events'\nimport {JobRecord, JobRecordSchema} from '../types/JobRecord'\nimport {JobDefinitionWithName, RecurrentJobDefinition} from '../types/JobsDefinition'\nimport {JobToRun} from '../types/Worker'\n\n@Repository()\nexport class JobsRepo {\n @MongoCollection({\n idGeneration: 'uuid',\n name: 'orionjs.jobs_dogs_records',\n schema: JobRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n priority: -1,\n nextRunAt: 1,\n },\n },\n {\n keys: {\n jobName: 1,\n },\n options: {\n unique: true,\n partialFilterExpression: {type: 'recurrent'},\n },\n },\n {\n keys: {\n uniqueIdentifier: 1,\n },\n options: {\n unique: true,\n sparse: true,\n },\n },\n ],\n })\n jobs: Collection<JobRecord>\n\n async getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun> {\n const lockedUntil = new Date(Date.now() + lockTime)\n\n const job = await this.jobs.findOneAndUpdate(\n {\n jobName: {$in: jobNames},\n nextRunAt: {$lte: new Date()},\n $or: [{lockedUntil: {$exists: false}}, {lockedUntil: {$lte: new Date()}}],\n // Exclude jobs that have reached max tries. Using $ne handles backwards compatibility\n // since records without the status field will still match (undefined !== 'maxTriesReached')\n status: {$ne: 'maxTriesReached'},\n },\n {\n $set: {lockedUntil, lastRunAt: new Date()},\n },\n {\n mongoOptions: {\n sort: {\n priority: -1,\n nextRunAt: 1,\n },\n returnDocument: 'before',\n },\n },\n )\n\n if (!job) return\n\n let tries = job.tries || 1\n const wasStale = Boolean(job.lockedUntil)\n\n if (wasStale) {\n logger.info(`Running job \"${job.jobName}\" that was staled`)\n await this.jobs.updateOne(job._id, {$inc: {tries: 1}})\n tries++\n }\n\n return {\n jobId: job._id,\n executionId: generateId(),\n name: job.jobName,\n params: job.params,\n type: job.type,\n tries,\n lockTime,\n priority: job.priority,\n uniqueIdentifier: job.uniqueIdentifier,\n wasStale,\n }\n }\n\n async setJobRecordPriority(jobId: string, priority: number) {\n await this.jobs.updateOne(jobId, {$set: {priority}})\n }\n\n async scheduleNextRun(options: {\n jobId: string\n nextRunAt: Date\n addTries: boolean\n priority: number\n }) {\n const updator: MongoDB.UpdateFilter<JobRecord> = {\n $set: {\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n ...(options.addTries ? {} : {tries: 0}),\n },\n $unset: {lockedUntil: ''},\n ...(options.addTries ? {$inc: {tries: 1}} : {}),\n }\n\n await this.jobs.updateOne(options.jobId, updator)\n }\n\n async deleteEventJob(jobId: string) {\n await this.jobs.deleteOne({_id: jobId, type: 'event'})\n }\n\n /**\n * Marks a job as having reached its maximum tries limit.\n * The job will remain in the database but won't be picked up for execution.\n */\n async markJobAsMaxTriesReached(jobId: string) {\n await this.jobs.updateOne(\n {_id: jobId},\n {\n $set: {status: 'maxTriesReached'},\n $unset: {lockedUntil: ''},\n },\n )\n }\n\n async extendLockTime(jobId: string, extraTime: number) {\n await this.updateLockTime(jobId, extraTime)\n }\n\n /**\n * Updates the lock time for a job to the specified duration from now.\n * Can be used to both extend or shorten the lock time.\n */\n async updateLockTime(jobId: string, lockDuration: number) {\n const lockedUntil = new Date(Date.now() + lockDuration)\n await this.jobs.updateOne(\n {\n _id: jobId,\n },\n {\n $set: {lockedUntil},\n },\n )\n }\n\n async unlockAllJobs(): Promise<number> {\n const result = await this.jobs.updateMany(\n {\n lockedUntil: {$exists: true},\n },\n {\n $unset: {lockedUntil: ''},\n },\n )\n\n return result.modifiedCount\n }\n\n async ensureJobRecord(job: JobDefinitionWithName) {\n const result = await this.jobs.upsert(\n {\n jobName: job.name,\n },\n {\n $set: {\n type: job.type,\n priority: (job as RecurrentJobDefinition).priority,\n },\n $setOnInsert: {\n nextRunAt: new Date(),\n },\n },\n )\n\n if (result.upsertedId) {\n logger.debug(`Created job record for \"${job.name}\"`)\n } else {\n logger.debug(`Record for job \"${job.name}\" already exists`)\n }\n }\n\n async scheduleJob(options: ScheduleJobRecordOptions) {\n try {\n await this.jobs.insertOne({\n jobName: options.name,\n uniqueIdentifier: options.uniqueIdentifier,\n params: options.params,\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n type: 'event',\n })\n } catch (error) {\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n options.uniqueIdentifier\n ) {\n logger.info(\n `Job \"${options.name}\" with identifier \"${options.uniqueIdentifier}\" already exists`,\n )\n } else {\n throw error\n }\n }\n }\n\n async scheduleJobs(jobs: ScheduleJobRecordOptions[]): Promise<ScheduleJobsResult> {\n if (jobs.length === 0) {\n return {scheduledCount: 0, skippedCount: 0, errors: []}\n }\n\n // Process each job individually to handle errors properly\n let scheduledCount = 0\n let skippedCount = 0\n const errors: Array<{index: number; error: Error; job: ScheduleJobRecordOptions}> = []\n\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i]\n try {\n // Insert directly to get better error handling than the single scheduleJob method\n await this.jobs.insertOne({\n jobName: job.name,\n uniqueIdentifier: job.uniqueIdentifier,\n params: job.params,\n nextRunAt: job.nextRunAt,\n priority: job.priority,\n type: 'event',\n })\n scheduledCount++\n } catch (error) {\n // Check if it's a validation error with uniqueIdentifier constraint\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n job.uniqueIdentifier\n ) {\n logger.info(`Job \"${job.name}\" with identifier \"${job.uniqueIdentifier}\" already exists`)\n skippedCount++\n } else {\n errors.push({\n index: i,\n error: error instanceof Error ? error : new Error(String(error)),\n job,\n })\n }\n }\n }\n\n logger.debug(\n `Scheduled ${scheduledCount} jobs successfully, skipped ${skippedCount}, errors: ${errors.length}`,\n )\n\n return {\n scheduledCount,\n skippedCount,\n errors,\n }\n }\n}\n","import {createEnum, InferSchemaType, schemaWithName} from '@orion-js/schema'\n\n/**\n * Enum representing the status of a job record.\n * - 'pending': Job is active and can be executed (default for existing records)\n * - 'maxTriesReached': Job has exhausted all retry attempts and won't be executed\n */\nexport const JobStatusEnum = createEnum('JobStatus', ['pending', 'maxTriesReached'])\n\nexport const JobRecordSchema = schemaWithName('JobRecord', {\n _id: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: createEnum('JobType', ['recurrent', 'event'])},\n priority: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n nextRunAt: {type: 'date'},\n lastRunAt: {type: 'date', optional: true},\n lockedUntil: {type: 'date', optional: true},\n tries: {type: 'number', optional: true},\n params: {type: 'blackbox', optional: true},\n /**\n * Status of the job. Optional for backwards compatibility with existing records.\n * Records without this field are treated as 'pending'.\n */\n status: {type: JobStatusEnum, optional: true},\n})\n\nexport type JobRecord = InferSchemaType<typeof JobRecordSchema>\n","export type Options = {\n getNextRun?: () => Date\n runIn?: number\n runEvery?: number\n runAt?: Date\n} & {[key: string]: any}\n\nexport const getNextRunDate = (options: Options) => {\n if (options.runIn) {\n return new Date(Date.now() + options.runIn)\n }\n\n if (options.runEvery) {\n return new Date(Date.now() + options.runEvery)\n }\n\n if (options.runAt) {\n return options.runAt\n }\n\n if (options.getNextRun) {\n return options.getNextRun()\n }\n\n return new Date()\n}\n","import {sleep} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinitionWithName, JobsDefinition} from '../types/JobsDefinition'\nimport {StartWorkersConfig} from '../types/StartConfig'\nimport {WorkerInstance, WorkersInstance} from '../types/Worker'\nimport {ExecuteJobConfig, Executor} from './Executor'\n\n@Service()\nexport class WorkerService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n @Inject(() => Executor)\n private executor: Executor\n\n getJobNames(jobs: JobsDefinition) {\n return Object.keys(jobs)\n }\n\n getJobs(jobs: JobsDefinition): JobDefinitionWithName[] {\n return Object.keys(jobs).map(name => {\n return {\n name,\n ...jobs[name],\n }\n })\n }\n\n async runWorkerLoop(\n config: StartWorkersConfig,\n workerInstance: WorkerInstance,\n jobNames: string[],\n executeConfig: ExecuteJobConfig,\n ) {\n const jobToRun = await this.jobsRepo.getJobAndLock(jobNames, config.defaultLockTime)\n if (!jobToRun) {\n logger.debug('No job to run')\n return false\n }\n\n logger.debug(`Got job [w${workerInstance.workerIndex}] to run:`, jobToRun)\n\n await this.executor.executeJob(executeConfig, jobToRun, workerInstance.respawn)\n\n return true\n }\n\n async startWorker(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n const names = this.getJobNames(config.jobs)\n logger.debug(\n `Running worker loop [w${workerInstance.workerIndex}] for jobs \"${names.join(', ')}\"...`,\n )\n const executeConfig: ExecuteJobConfig = {\n jobs: config.jobs,\n maxTries: config.maxTries,\n onMaxTriesReached: config.onMaxTriesReached,\n }\n\n while (true) {\n if (!workerInstance.running) {\n logger.info(`Got signal to stop. Stopping worker [w${workerInstance.workerIndex}]...`)\n return\n }\n\n try {\n const didRun = await this.runWorkerLoop(config, workerInstance, names, executeConfig)\n if (!didRun) await sleep(config.pollInterval)\n if (didRun) await sleep(config.cooldownPeriod)\n } catch (error) {\n logger.error('Error in job runner.', {error})\n await sleep(config.pollInterval)\n }\n }\n }\n\n createWorkersInstanceDefinition(config: StartWorkersConfig): WorkersInstance {\n const workersInstance: WorkersInstance = {\n running: true,\n workersCount: config.workersCount,\n workers: [],\n stop: async () => {\n logger.info('Stopping workers...')\n workersInstance.running = false\n const stopingPromises = workersInstance.workers.map(worker => worker.stop())\n await Promise.all(stopingPromises)\n },\n }\n\n return workersInstance\n }\n\n async ensureRecords(config: StartWorkersConfig) {\n const jobs = this.getJobs(config.jobs)\n\n await Promise.all(\n jobs\n .filter(job => job.type === 'recurrent')\n .map(async job => {\n logger.debug(`Ensuring records for job \"${job.name}\"...`)\n await this.jobsRepo.ensureJobRecord(job)\n }),\n )\n }\n\n async startANewWorker(\n config: StartWorkersConfig,\n workersInstance: WorkersInstance,\n workerIndex = workersInstance.workers.length,\n ) {\n if (!workersInstance.running) {\n return\n }\n\n const workerInstance: WorkerInstance = {\n running: true,\n workerIndex,\n stop: async () => {\n logger.info(`Stopping worker [w${workerIndex}]...`)\n workerInstance.running = false\n await workerInstance.promise\n },\n respawn: async () => {\n logger.info(`Respawning worker [w${workerIndex}]...`)\n workerInstance.running = false\n await this.startANewWorker(config, workersInstance, workerIndex)\n },\n }\n\n const workerPromise = this.startWorker(config, workerInstance)\n\n workerInstance.promise = workerPromise\n workersInstance.workers[workerIndex] = workerInstance\n }\n\n async runWorkers(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n logger.debug('Will ensure records for recurrent jobs')\n await this.ensureRecords(config)\n\n const workersCount = config.workersCount\n const workerWord = workersCount === 1 ? 'worker' : 'workers'\n logger.info(`Starting ${workersCount} ${workerWord}`)\n\n for (let workerIndex = 0; workerIndex < workersCount; workerIndex++) {\n this.startANewWorker(config, workersInstance, workerIndex)\n }\n }\n\n /**\n * Starts the job workers with the provided configuration.\n * @param userConfig - Configuration for the workers. Required fields: jobs, maxTries, onMaxTriesReached\n */\n startWorkers(userConfig: StartWorkersConfig): WorkersInstance {\n // Apply defaults for optional fields\n const config: StartWorkersConfig = {\n cooldownPeriod: 100,\n pollInterval: 3000,\n workersCount: 4,\n defaultLockTime: 30 * 1000,\n ...userConfig,\n }\n\n setNameToJobs(config.jobs)\n\n const workersInstance = this.createWorkersInstanceDefinition(config)\n logger.debug('Starting workers', config)\n\n this.runWorkers(config, workersInstance)\n\n return workersInstance\n }\n}\n\nfunction setNameToJobs(jobs: JobsDefinition) {\n for (const name of Object.keys(jobs)) {\n jobs[name].jobName = name\n }\n}\n","import {SpanStatusCode, trace} from '@opentelemetry/api'\nimport {logger, runWithOrionAsyncContext, updateOrionAsyncContext} from '@orion-js/logger'\nimport {Blackbox} from '@orion-js/schema'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsHistoryRepo} from '../repos/JobsHistoryRepo'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinition, JobsDefinition} from '../types/JobsDefinition'\nimport {ExecutionContext, JobToRun} from '../types/Worker'\nimport {getNextRunDate} from './getNextRunDate'\n\n/**\n * Configuration for job execution including max tries settings.\n */\nexport interface ExecuteJobConfig {\n jobs: JobsDefinition\n maxTries: number\n onMaxTriesReached: (job: JobToRun) => Promise<void>\n}\n\n@Service()\nexport class Executor {\n @Inject(() => JobsRepo)\n private readonly jobsRepo: JobsRepo\n\n @Inject(() => JobsHistoryRepo)\n private readonly jobsHistoryRepo: JobsHistoryRepo\n\n /**\n * Determines the effective lock time for a job execution.\n * Job-specific lockTime takes precedence over the default lockTime from config.\n */\n getEffectiveLockTime(job: JobDefinition, jobToRun: JobToRun): number {\n return job.lockTime ?? jobToRun.lockTime\n }\n\n getContext(job: JobDefinition, jobToRun: JobToRun, onStale: Function): ExecutionContext {\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n let staleTimeout = setTimeout(() => onStale(), effectiveLockTime)\n staleTimeout.unref?.()\n return {\n definition: job,\n record: jobToRun,\n tries: jobToRun.tries || 0,\n clearStaleTimeout: () => clearTimeout(staleTimeout),\n extendLockTime: async (extraTime: number) => {\n clearTimeout(staleTimeout)\n staleTimeout = setTimeout(() => onStale(), extraTime)\n staleTimeout.unref?.()\n await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime)\n },\n logger: logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n }),\n }\n }\n\n getJobDefinition(jobToRun: JobToRun, jobs: JobsDefinition) {\n const job = jobs[jobToRun.name]\n\n if (jobToRun.type !== job.type) {\n logger.warn(\n `Job record \"${jobToRun.name}\" is \"${jobToRun.type}\" but definition is \"${job.type}\"`,\n )\n return\n }\n\n return job\n }\n\n /**\n * Determines the effective max tries for a job.\n * Job-specific maxTries takes precedence over the global maxTries from config.\n */\n getEffectiveMaxTries(job: JobDefinition, globalMaxTries: number): number {\n return job.maxTries ?? globalMaxTries\n }\n\n /**\n * Handles when a job has reached its maximum retry attempts.\n * Marks the job in the database and invokes the onMaxTriesReached callback.\n */\n async handleMaxTriesReached(\n jobToRun: JobToRun,\n onMaxTriesReached: (job: JobToRun) => Promise<void>,\n ) {\n const jobLogger = logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n })\n\n jobLogger.warn(\n `Job \"${jobToRun.name}\" has reached max tries (${jobToRun.tries}). Marking as maxTriesReached.`,\n )\n await this.jobsRepo.markJobAsMaxTriesReached(jobToRun.jobId)\n\n // Invoke the callback to notify administrators\n try {\n await onMaxTriesReached(jobToRun)\n } catch (callbackError) {\n jobLogger.error(`Error in onMaxTriesReached callback for job \"${jobToRun.name}\"`, {\n error: callbackError,\n })\n }\n }\n\n async onError(\n error: unknown,\n job: JobDefinition,\n jobToRun: JobToRun,\n context: ExecutionContext,\n config: ExecuteJobConfig,\n ) {\n const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries)\n\n // Helper to schedule next run for recurrent jobs (used when dismissing)\n const scheduleRecurrent = async () => {\n if (job.type === 'recurrent') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n }\n\n // Helper to handle retry with max tries check\n const handleRetry = async (nextRunAt: Date) => {\n // Check if we've reached max tries before scheduling another retry\n if (jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached)\n return\n }\n\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt,\n addTries: true,\n priority: job.type === 'recurrent' ? job.priority : jobToRun.priority,\n })\n }\n\n // If no custom error handler, check max tries and schedule recurrent if applicable\n if (!job.onError) {\n context.logger.error(`Error executing job \"${jobToRun.name}\"`, {error})\n\n // For jobs without onError, check if max tries reached\n if (jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached)\n return\n }\n\n await scheduleRecurrent()\n return\n }\n\n context.logger.info(`Error executing job \"${jobToRun.name}\"`, {error})\n const result = await job.onError(\n error instanceof Error ? error : new Error(String(error)),\n jobToRun.params,\n context,\n )\n\n if (result.action === 'dismiss') {\n await scheduleRecurrent()\n return\n }\n\n if (result.action === 'retry') {\n await handleRetry(getNextRunDate(result))\n }\n }\n\n async saveExecution(options: {\n startedAt: Date\n status: 'stale' | 'error' | 'success'\n errorMessage?: string\n result?: Blackbox\n job: JobDefinition\n jobToRun: JobToRun\n }) {\n const {startedAt, status, errorMessage, result, job, jobToRun} = options\n const endedAt = new Date()\n\n if (job.saveExecutionsFor !== 0) {\n const oneWeek = 1000 * 60 * 60 * 24 * 7\n const saveExecutionsFor = job.saveExecutionsFor || oneWeek\n await this.jobsHistoryRepo.saveExecution({\n jobId: jobToRun.jobId,\n executionId: jobToRun.executionId,\n jobName: jobToRun.name,\n type: jobToRun.type,\n priority: jobToRun.priority,\n tries: jobToRun.tries,\n uniqueIdentifier: jobToRun.uniqueIdentifier,\n startedAt,\n endedAt,\n duration: endedAt.getTime() - startedAt.getTime(),\n expiresAt: new Date(Date.now() + saveExecutionsFor),\n status,\n errorMessage,\n params: jobToRun.params,\n result,\n })\n }\n }\n\n async afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n if (job.type === 'recurrent') {\n context.logger.debug(`Scheduling next run for recurrent job \"${jobToRun.name}\"`)\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n if (job.type === 'event') {\n context.logger.debug(`Removing event job after success \"${jobToRun.name}\"`)\n await this.jobsRepo.deleteEventJob(jobToRun.jobId)\n }\n }\n\n async executeJob(config: ExecuteJobConfig, jobToRun: JobToRun, respawnWorker: () => void) {\n const job = this.getJobDefinition(jobToRun, config.jobs)\n if (!job) return\n\n const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries)\n if (jobToRun.wasStale && jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached)\n return\n }\n\n // If job has a custom lockTime different from the default, update the database lock\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n if (effectiveLockTime !== jobToRun.lockTime) {\n await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime)\n }\n\n const tracer = trace.getTracer('orionjs.dogs', '1.0')\n\n await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async span => {\n try {\n const startedAt = new Date()\n\n const onStale = async () => {\n if (job.onStale) {\n context.logger.info(`Job \"${jobToRun.name}\" is stale`)\n job.onStale(jobToRun.params, context)\n } else {\n context.logger.error(`Job \"${jobToRun.name}\" is stale`)\n }\n\n await this.jobsRepo.setJobRecordPriority(jobToRun.jobId, 0)\n\n void respawnWorker()\n\n void this.saveExecution({\n startedAt,\n status: 'stale',\n result: null,\n errorMessage: null,\n job,\n jobToRun,\n }).catch(error => {\n context.logger.error('Error saving stale execution history', {error})\n })\n }\n\n const context = this.getContext(job, jobToRun, onStale)\n\n const extraContext = {\n controllerType: 'job' as const,\n jobName: jobToRun.name,\n params: jobToRun.params,\n }\n\n await runWithOrionAsyncContext(extraContext, async () => {\n try {\n // Inject async context update\n updateOrionAsyncContext({\n jobName: jobToRun.name,\n params: jobToRun.params,\n })\n const result = await job.resolve(jobToRun.params, context)\n context.clearStaleTimeout()\n\n void this.saveExecution({\n startedAt,\n status: 'success',\n result: result || null,\n errorMessage: null,\n job,\n jobToRun,\n }).catch(error => {\n context.logger.error('Error saving successful execution history', {error})\n })\n\n await this.afterExecutionSuccess(job, jobToRun, context)\n } catch (error) {\n context.clearStaleTimeout()\n void this.saveExecution({\n startedAt,\n status: 'error',\n result: null,\n errorMessage: (error as Error).message,\n job,\n jobToRun,\n }).catch(saveError => {\n context.logger.error('Error saving failed execution history', {error: saveError})\n })\n\n await this.onError(error, job, jobToRun, context, config)\n }\n })\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: (error as Error).message,\n })\n throw error\n } finally {\n span.end()\n }\n })\n }\n}\n","import {Collection, MongoCollection, Repository, MongoDB} from '@orion-js/mongodb'\nimport {omit} from 'rambdax'\nimport {HistoryRecord, HistoryRecordSchema} from '../types/HistoryRecord'\n\n@Repository()\nexport class JobsHistoryRepo {\n @MongoCollection({\n name: 'orionjs.jobs_dogs_history',\n idGeneration: 'uuid',\n schema: HistoryRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n startedAt: 1,\n },\n },\n {\n keys: {\n executionId: 1,\n },\n },\n {\n keys: {\n expiresAt: 1,\n },\n options: {\n expireAfterSeconds: 0,\n },\n },\n ],\n })\n history: Collection<HistoryRecord>\n\n async saveExecution(record: MongoDB.WithoutId<HistoryRecord>) {\n await this.history.upsert(\n {executionId: record.executionId},\n {\n $setOnInsert: {\n status: record.status,\n },\n $set: {\n ...omit(['status'], record),\n },\n },\n )\n }\n\n async getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]> {\n const cursor = this.history.find({jobName}).sort({startedAt: -1})\n\n if (skip) {\n cursor.skip(skip)\n }\n\n if (limit) {\n cursor.limit(limit)\n }\n\n return await cursor.toArray()\n }\n}\n","function _isInteger(n){\n return n << 0 === n\n}\n\nexport const isInteger = Number.isInteger || _isInteger\n\n/**\n * Check if `index` is integer even if it is a string.\n */\nexport const isIndexInteger = index => Number.isInteger(Number(index))\n","import { isInteger } from './isInteger.js'\n\nexport function createPath(path, delimiter = '.'){\n return typeof path === 'string' ?\n path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) :\n path\n}\n","export function compare(a, b){\n return String(a) === String(b)\n}\n","import { compare } from './compare.js'\n\nexport function includes(a, list){\n let index = -1\n const { length } = list\n\n while (++index < length)\n if (compare(list[ index ], a))\n return true\n\n return false\n}\n","import { createPath } from './_internals/createPath.js'\nimport { includes } from './_internals/includes.js'\n\nexport function omit(propsToOmit, obj){\n if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)\n\n if (obj === null || obj === undefined)\n return undefined\n\n const propsToOmitValue = createPath(propsToOmit, ',')\n const willReturn = {}\n\n for (const key in obj)\n if (!includes(key, propsToOmitValue))\n willReturn[ key ] = obj[ key ]\n\n return willReturn\n}\n","import {InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const HistoryRecordSchema = schemaWithName('HistoryRecord', {\n _id: {type: 'string'},\n jobId: {type: 'string'},\n executionId: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: 'string'},\n priority: {type: 'number'},\n tries: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n startedAt: {type: 'date'},\n endedAt: {type: 'date'},\n duration: {type: 'number'},\n expiresAt: {type: 'date', optional: true},\n status: {type: 'string', enum: ['success', 'error', 'stale']},\n errorMessage: {type: 'string', optional: true},\n params: {type: 'blackbox', optional: true},\n result: {type: 'any', optional: true},\n})\n\nexport type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>\n","import {getInstance, Service} from '@orion-js/services'\nimport {createEventJob, defineJob} from '../defineJob'\nimport type {CreateEventJobOptions, JobDefinition, RecurrentJobDefinition} from '../types'\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst jobsMetadata = new Map<any, Record<string, any>>()\nconst jobEntriesByClass = new Map<Function, Record<string, (instance: any) => any>>()\nlet pendingJobEntries: Record<string, (instance: any) => any> = {}\n\nexport function Jobs() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n Service()(target, context)\n serviceMetadata.set(target, {_serviceType: 'jobs'})\n\n if (Object.keys(pendingJobEntries).length > 0) {\n jobEntriesByClass.set(target, pendingJobEntries)\n pendingJobEntries = {}\n }\n }\n}\n\nexport function RecurrentJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function RecurrentJob(\n options: Omit<RecurrentJobDefinition, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function RecurrentJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingJobEntries[propertyKey] = (instance: any) =>\n defineJob({\n ...options,\n type: 'recurrent',\n resolve: instance[propertyKey].bind(instance),\n })\n }\n\n if (context.kind === 'field') {\n pendingJobEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nexport function EventJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EventJob(\n options: Omit<CreateEventJobOptions<any>, 'resolve'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EventJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingJobEntries[propertyKey] = (instance: any) =>\n createEventJob({\n ...options,\n resolve: instance[propertyKey].bind(instance),\n })\n }\n\n if (context.kind === 'field') {\n pendingJobEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nfunction initializeJobsIfNeeded(instance: any) {\n if (jobsMetadata.has(instance)) return\n const entries = jobEntriesByClass.get(instance.constructor) || {}\n const jobs: Record<string, any> = {}\n for (const [key, setup] of Object.entries(entries)) {\n jobs[key] = setup(instance)\n }\n jobsMetadata.set(instance, jobs)\n}\n\nexport function getServiceJobs(target: any): {\n [key: string]: JobDefinition\n} {\n const instance = getInstance(target)\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'jobs') {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n initializeJobsIfNeeded(instance)\n\n const jobsMap = jobsMetadata.get(instance) || {}\n\n return jobsMap\n}\n","import {\n CreateEventJobOptions,\n CreateJobOptions,\n CreateRecurrentJobOptions,\n EventJobDefinition,\n JobDefinition,\n RecurrentJobDefinition,\n} from '../types/JobsDefinition'\nimport {scheduleJob, ScheduleJobsResult, scheduleJobs} from '..'\nimport {ScheduleJobOptionsWithoutName} from '../types/Events'\nimport {cleanAndValidate, SchemaInAnyOrionForm} from '@orion-js/schema'\nimport parse from 'parse-duration'\n\nexport function createEventJob<TParamsSchema extends SchemaInAnyOrionForm>(\n options: CreateEventJobOptions<TParamsSchema>,\n): EventJobDefinition<TParamsSchema> {\n const jobDefinition: EventJobDefinition<TParamsSchema> = {\n ...options,\n type: 'event',\n schedule: null,\n scheduleJobs: null,\n }\n\n jobDefinition.schedule = async (scheduleOptions: ScheduleJobOptionsWithoutName<TParamsSchema>) => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return await scheduleJob({\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n })\n }\n\n jobDefinition.scheduleJobs = async (\n jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>,\n ): Promise<ScheduleJobsResult> => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n // Process all job parameters if schema validation is needed\n const processedJobs = await Promise.all(\n jobs.map(async scheduleOptions => {\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return {\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n }\n }),\n )\n\n return await scheduleJobs(processedJobs)\n }\n\n return jobDefinition\n}\n\nexport function createRecurrentJob(options: CreateRecurrentJobOptions): RecurrentJobDefinition {\n const jobDefinition: RecurrentJobDefinition = {\n ...options,\n priority: options.priority ?? 100,\n type: 'recurrent',\n runEvery: typeof options.runEvery === 'string' ? parse(options.runEvery) : options.runEvery,\n }\n\n return jobDefinition\n}\n\n/**\n * @deprecated Use `createEventJob` or `createRecurrentJob` instead.\n */\nexport const defineJob = (\n options: CreateJobOptions & {type: 'event' | 'recurrent'},\n): JobDefinition => {\n return options.type === 'event'\n ? createEventJob(options as any)\n : createRecurrentJob(options as any)\n}\n"],"mappings":"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","names":["import_services","import_logger","_init","import_helpers","import_logger","import_services","import_logger","import_services","import_mongodb","import_schema","_init","_jobsRepo_dec","_init","_a","_jobsRepo_dec","_init","import_services","import_schema","parse"]}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __create = Object.create;
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
4
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
5
5
|
var __typeError = (msg) => {
|
|
6
6
|
throw TypeError(msg);
|
|
7
7
|
};
|
|
@@ -57,8 +57,7 @@ import { Inject, Service } from "@orion-js/services";
|
|
|
57
57
|
// src/repos/JobsRepo.ts
|
|
58
58
|
import { generateId } from "@orion-js/helpers";
|
|
59
59
|
import { logger } from "@orion-js/logger";
|
|
60
|
-
import { MongoCollection } from "@orion-js/mongodb";
|
|
61
|
-
import { Repository } from "@orion-js/mongodb";
|
|
60
|
+
import { MongoCollection, Repository } from "@orion-js/mongodb";
|
|
62
61
|
|
|
63
62
|
// src/types/JobRecord.ts
|
|
64
63
|
import { createEnum, schemaWithName } from "@orion-js/schema";
|
|
@@ -145,9 +144,10 @@ var JobsRepo = class {
|
|
|
145
144
|
);
|
|
146
145
|
if (!job) return;
|
|
147
146
|
let tries = job.tries || 1;
|
|
148
|
-
|
|
147
|
+
const wasStale = Boolean(job.lockedUntil);
|
|
148
|
+
if (wasStale) {
|
|
149
149
|
logger.info(`Running job "${job.jobName}" that was staled`);
|
|
150
|
-
this.jobs.updateOne(job._id, { $inc: { tries: 1 } });
|
|
150
|
+
await this.jobs.updateOne(job._id, { $inc: { tries: 1 } });
|
|
151
151
|
tries++;
|
|
152
152
|
}
|
|
153
153
|
return {
|
|
@@ -159,7 +159,8 @@ var JobsRepo = class {
|
|
|
159
159
|
tries,
|
|
160
160
|
lockTime,
|
|
161
161
|
priority: job.priority,
|
|
162
|
-
uniqueIdentifier: job.uniqueIdentifier
|
|
162
|
+
uniqueIdentifier: job.uniqueIdentifier,
|
|
163
|
+
wasStale
|
|
163
164
|
};
|
|
164
165
|
}
|
|
165
166
|
async setJobRecordPriority(jobId, priority) {
|
|
@@ -374,23 +375,23 @@ import { Inject as Inject2, Service as Service2 } from "@orion-js/services";
|
|
|
374
375
|
// src/repos/JobsHistoryRepo.ts
|
|
375
376
|
import { MongoCollection as MongoCollection2, Repository as Repository2 } from "@orion-js/mongodb";
|
|
376
377
|
|
|
377
|
-
// ../../node_modules/.
|
|
378
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js
|
|
378
379
|
function _isInteger(n) {
|
|
379
380
|
return n << 0 === n;
|
|
380
381
|
}
|
|
381
382
|
var isInteger = Number.isInteger || _isInteger;
|
|
382
383
|
|
|
383
|
-
// ../../node_modules/.
|
|
384
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js
|
|
384
385
|
function createPath(path, delimiter = ".") {
|
|
385
386
|
return typeof path === "string" ? path.split(delimiter).map((x) => isInteger(x) ? Number(x) : x) : path;
|
|
386
387
|
}
|
|
387
388
|
|
|
388
|
-
// ../../node_modules/.
|
|
389
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js
|
|
389
390
|
function compare(a, b) {
|
|
390
391
|
return String(a) === String(b);
|
|
391
392
|
}
|
|
392
393
|
|
|
393
|
-
// ../../node_modules/.
|
|
394
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js
|
|
394
395
|
function includes(a, list) {
|
|
395
396
|
let index = -1;
|
|
396
397
|
const { length } = list;
|
|
@@ -400,7 +401,7 @@ function includes(a, list) {
|
|
|
400
401
|
return false;
|
|
401
402
|
}
|
|
402
403
|
|
|
403
|
-
// ../../node_modules/.
|
|
404
|
+
// ../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/omit.js
|
|
404
405
|
function omit(propsToOmit, obj) {
|
|
405
406
|
if (arguments.length === 1) return (_obj) => omit(propsToOmit, _obj);
|
|
406
407
|
if (obj === null || obj === void 0)
|
|
@@ -554,15 +555,19 @@ var Executor = class {
|
|
|
554
555
|
* Handles when a job has reached its maximum retry attempts.
|
|
555
556
|
* Marks the job in the database and invokes the onMaxTriesReached callback.
|
|
556
557
|
*/
|
|
557
|
-
async handleMaxTriesReached(jobToRun,
|
|
558
|
-
|
|
558
|
+
async handleMaxTriesReached(jobToRun, onMaxTriesReached) {
|
|
559
|
+
const jobLogger = logger3.addMetadata({
|
|
560
|
+
jobName: jobToRun.name,
|
|
561
|
+
jobId: jobToRun.jobId
|
|
562
|
+
});
|
|
563
|
+
jobLogger.warn(
|
|
559
564
|
`Job "${jobToRun.name}" has reached max tries (${jobToRun.tries}). Marking as maxTriesReached.`
|
|
560
565
|
);
|
|
561
566
|
await this.jobsRepo.markJobAsMaxTriesReached(jobToRun.jobId);
|
|
562
567
|
try {
|
|
563
568
|
await onMaxTriesReached(jobToRun);
|
|
564
569
|
} catch (callbackError) {
|
|
565
|
-
|
|
570
|
+
jobLogger.error(`Error in onMaxTriesReached callback for job "${jobToRun.name}"`, {
|
|
566
571
|
error: callbackError
|
|
567
572
|
});
|
|
568
573
|
}
|
|
@@ -581,7 +586,7 @@ var Executor = class {
|
|
|
581
586
|
};
|
|
582
587
|
const handleRetry = async (nextRunAt) => {
|
|
583
588
|
if (jobToRun.tries >= effectiveMaxTries) {
|
|
584
|
-
await this.handleMaxTriesReached(jobToRun,
|
|
589
|
+
await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached);
|
|
585
590
|
return;
|
|
586
591
|
}
|
|
587
592
|
await this.jobsRepo.scheduleNextRun({
|
|
@@ -594,7 +599,7 @@ var Executor = class {
|
|
|
594
599
|
if (!job.onError) {
|
|
595
600
|
context.logger.error(`Error executing job "${jobToRun.name}"`, { error });
|
|
596
601
|
if (jobToRun.tries >= effectiveMaxTries) {
|
|
597
|
-
await this.handleMaxTriesReached(jobToRun,
|
|
602
|
+
await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached);
|
|
598
603
|
return;
|
|
599
604
|
}
|
|
600
605
|
await scheduleRecurrent();
|
|
@@ -657,6 +662,11 @@ var Executor = class {
|
|
|
657
662
|
async executeJob(config, jobToRun, respawnWorker) {
|
|
658
663
|
const job = this.getJobDefinition(jobToRun, config.jobs);
|
|
659
664
|
if (!job) return;
|
|
665
|
+
const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries);
|
|
666
|
+
if (jobToRun.wasStale && jobToRun.tries >= effectiveMaxTries) {
|
|
667
|
+
await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached);
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
660
670
|
const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun);
|
|
661
671
|
if (effectiveLockTime !== jobToRun.lockTime) {
|
|
662
672
|
await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime);
|
|
@@ -940,53 +950,58 @@ var defineJob = (options) => {
|
|
|
940
950
|
// src/service/index.ts
|
|
941
951
|
var serviceMetadata = /* @__PURE__ */ new WeakMap();
|
|
942
952
|
var jobsMetadata = /* @__PURE__ */ new Map();
|
|
953
|
+
var jobEntriesByClass = /* @__PURE__ */ new Map();
|
|
954
|
+
var pendingJobEntries = {};
|
|
943
955
|
function Jobs() {
|
|
944
956
|
return (target, context) => {
|
|
945
957
|
Service4()(target, context);
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
958
|
+
serviceMetadata.set(target, { _serviceType: "jobs" });
|
|
959
|
+
if (Object.keys(pendingJobEntries).length > 0) {
|
|
960
|
+
jobEntriesByClass.set(target, pendingJobEntries);
|
|
961
|
+
pendingJobEntries = {};
|
|
962
|
+
}
|
|
949
963
|
};
|
|
950
964
|
}
|
|
951
965
|
function RecurrentJob(options = {}) {
|
|
952
966
|
return (method, context) => {
|
|
953
967
|
const propertyKey = String(context.name);
|
|
954
|
-
context.
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
jobs[propertyKey] = this[propertyKey];
|
|
965
|
-
}
|
|
966
|
-
jobsMetadata.set(this, jobs);
|
|
967
|
-
});
|
|
968
|
+
if (context.kind === "method") {
|
|
969
|
+
pendingJobEntries[propertyKey] = (instance) => defineJob({
|
|
970
|
+
...options,
|
|
971
|
+
type: "recurrent",
|
|
972
|
+
resolve: instance[propertyKey].bind(instance)
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
if (context.kind === "field") {
|
|
976
|
+
pendingJobEntries[propertyKey] = (instance) => instance[propertyKey];
|
|
977
|
+
}
|
|
968
978
|
return method;
|
|
969
979
|
};
|
|
970
980
|
}
|
|
971
981
|
function EventJob(options = {}) {
|
|
972
982
|
return (method, context) => {
|
|
973
983
|
const propertyKey = String(context.name);
|
|
974
|
-
context.
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
jobs[propertyKey] = this[propertyKey];
|
|
984
|
-
}
|
|
985
|
-
jobsMetadata.set(this, jobs);
|
|
986
|
-
});
|
|
984
|
+
if (context.kind === "method") {
|
|
985
|
+
pendingJobEntries[propertyKey] = (instance) => createEventJob({
|
|
986
|
+
...options,
|
|
987
|
+
resolve: instance[propertyKey].bind(instance)
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
if (context.kind === "field") {
|
|
991
|
+
pendingJobEntries[propertyKey] = (instance) => instance[propertyKey];
|
|
992
|
+
}
|
|
987
993
|
return method;
|
|
988
994
|
};
|
|
989
995
|
}
|
|
996
|
+
function initializeJobsIfNeeded(instance) {
|
|
997
|
+
if (jobsMetadata.has(instance)) return;
|
|
998
|
+
const entries = jobEntriesByClass.get(instance.constructor) || {};
|
|
999
|
+
const jobs = {};
|
|
1000
|
+
for (const [key, setup] of Object.entries(entries)) {
|
|
1001
|
+
jobs[key] = setup(instance);
|
|
1002
|
+
}
|
|
1003
|
+
jobsMetadata.set(instance, jobs);
|
|
1004
|
+
}
|
|
990
1005
|
function getServiceJobs(target) {
|
|
991
1006
|
const instance = getInstance(target);
|
|
992
1007
|
if (!serviceMetadata.has(instance.constructor)) {
|
|
@@ -996,6 +1011,7 @@ function getServiceJobs(target) {
|
|
|
996
1011
|
if (instanceMetadata._serviceType !== "jobs") {
|
|
997
1012
|
throw new Error("You must pass a class decorated with @Jobs to getServiceJobs");
|
|
998
1013
|
}
|
|
1014
|
+
initializeJobsIfNeeded(instance);
|
|
999
1015
|
const jobsMap = jobsMetadata.get(instance) || {};
|
|
1000
1016
|
return jobsMap;
|
|
1001
1017
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/services/EventsService.ts","../src/repos/JobsRepo.ts","../src/types/JobRecord.ts","../src/services/getNextRunDate.ts","../src/services/WorkerService.ts","../src/services/Executor.ts","../src/repos/JobsHistoryRepo.ts","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js","../../../node_modules/.pnpm/rambdax@11.3.1/node_modules/rambdax/src/omit.js","../src/types/HistoryRecord.ts","../src/service/index.ts","../src/defineJob/index.ts"],"sourcesContent":["import {getInstance} from '@orion-js/services'\nimport {EventsService} from './services/EventsService'\nimport {WorkerService} from './services/WorkerService'\nimport {StartWorkersConfig} from './types/StartConfig'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from './types/Events'\nimport {JobsHistoryRepo} from './repos/JobsHistoryRepo'\nimport {JobsRepo} from './repos/JobsRepo'\nimport {SchemaInAnyOrionForm} from '@orion-js/schema'\n\nexport * from './types'\nexport * from './service'\nexport * from './defineJob'\n\nconst workerService = getInstance(WorkerService)\nconst eventsService = getInstance(EventsService)\nconst jobsHistoryRepo = getInstance(JobsHistoryRepo)\nconst jobsRepo = getInstance(JobsRepo)\n\nconst startWorkers = (config: StartWorkersConfig) => {\n return workerService.startWorkers(config)\n}\n\n/**\n * @deprecated Use the event job definition.schedule method instead.\n */\nconst scheduleJob = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n options: ScheduleJobOptions<TParamsSchema>,\n) => {\n return eventsService.scheduleJob(options)\n}\n\n/**\n * Schedule multiple jobs at once for better performance.\n * @deprecated Use the event job definition.scheduleJobs method instead.\n */\nconst scheduleJobs = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n jobs: ScheduleJobsOptions<TParamsSchema>,\n): Promise<ScheduleJobsResult> => {\n return eventsService.scheduleJobs(jobs)\n}\n\nexport {startWorkers, scheduleJob, scheduleJobs, jobsHistoryRepo, jobsRepo}\n","import {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from '../types/Events'\nimport {getNextRunDate} from './getNextRunDate'\n\n@Service()\nexport class EventsService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n async scheduleJob(options: ScheduleJobOptions) {\n logger.debug('Scheduling job...', options)\n\n await this.jobsRepo.scheduleJob({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n })\n }\n\n async scheduleJobs(jobs: ScheduleJobsOptions): Promise<ScheduleJobsResult> {\n logger.debug(`Scheduling ${jobs.length} jobs...`)\n\n const jobRecords = jobs.map(options => ({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n }))\n\n return await this.jobsRepo.scheduleJobs(jobRecords)\n }\n}\n","import {generateId} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Collection, MongoDB, MongoCollection} from '@orion-js/mongodb'\nimport {ScheduleJobRecordOptions, ScheduleJobsResult} from '../types/Events'\nimport {JobRecord} from '../types/JobRecord'\nimport {JobDefinitionWithName, RecurrentJobDefinition} from '../types/JobsDefinition'\nimport {JobToRun} from '../types/Worker'\nimport {Repository} from '@orion-js/mongodb'\nimport {JobRecordSchema} from '../types/JobRecord'\n\n@Repository()\nexport class JobsRepo {\n @MongoCollection({\n idGeneration: 'uuid',\n name: 'orionjs.jobs_dogs_records',\n schema: JobRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n priority: -1,\n nextRunAt: 1,\n },\n },\n {\n keys: {\n jobName: 1,\n },\n options: {\n unique: true,\n partialFilterExpression: {type: 'recurrent'},\n },\n },\n {\n keys: {\n uniqueIdentifier: 1,\n },\n options: {\n unique: true,\n sparse: true,\n },\n },\n ],\n })\n jobs: Collection<JobRecord>\n\n async getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun> {\n const lockedUntil = new Date(Date.now() + lockTime)\n\n const job = await this.jobs.findOneAndUpdate(\n {\n jobName: {$in: jobNames},\n nextRunAt: {$lte: new Date()},\n $or: [{lockedUntil: {$exists: false}}, {lockedUntil: {$lte: new Date()}}],\n // Exclude jobs that have reached max tries. Using $ne handles backwards compatibility\n // since records without the status field will still match (undefined !== 'maxTriesReached')\n status: {$ne: 'maxTriesReached'},\n },\n {\n $set: {lockedUntil, lastRunAt: new Date()},\n },\n {\n mongoOptions: {\n sort: {\n priority: -1,\n nextRunAt: 1,\n },\n returnDocument: 'before',\n },\n },\n )\n\n if (!job) return\n\n let tries = job.tries || 1\n\n if (job.lockedUntil) {\n logger.info(`Running job \"${job.jobName}\" that was staled`)\n this.jobs.updateOne(job._id, {$inc: {tries: 1}})\n tries++\n }\n\n return {\n jobId: job._id,\n executionId: generateId(),\n name: job.jobName,\n params: job.params,\n type: job.type,\n tries,\n lockTime,\n priority: job.priority,\n uniqueIdentifier: job.uniqueIdentifier,\n }\n }\n\n async setJobRecordPriority(jobId: string, priority: number) {\n await this.jobs.updateOne(jobId, {$set: {priority}})\n }\n\n async scheduleNextRun(options: {\n jobId: string\n nextRunAt: Date\n addTries: boolean\n priority: number\n }) {\n const updator: MongoDB.UpdateFilter<JobRecord> = {\n $set: {\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n ...(options.addTries ? {} : {tries: 0}),\n },\n $unset: {lockedUntil: ''},\n ...(options.addTries ? {$inc: {tries: 1}} : {}),\n }\n\n await this.jobs.updateOne(options.jobId, updator)\n }\n\n async deleteEventJob(jobId: string) {\n await this.jobs.deleteOne({_id: jobId, type: 'event'})\n }\n\n /**\n * Marks a job as having reached its maximum tries limit.\n * The job will remain in the database but won't be picked up for execution.\n */\n async markJobAsMaxTriesReached(jobId: string) {\n await this.jobs.updateOne(\n {_id: jobId},\n {\n $set: {status: 'maxTriesReached'},\n $unset: {lockedUntil: ''},\n },\n )\n }\n\n async extendLockTime(jobId: string, extraTime: number) {\n await this.updateLockTime(jobId, extraTime)\n }\n\n /**\n * Updates the lock time for a job to the specified duration from now.\n * Can be used to both extend or shorten the lock time.\n */\n async updateLockTime(jobId: string, lockDuration: number) {\n const lockedUntil = new Date(Date.now() + lockDuration)\n await this.jobs.updateOne(\n {\n _id: jobId,\n },\n {\n $set: {lockedUntil},\n },\n )\n }\n\n async unlockAllJobs(): Promise<number> {\n const result = await this.jobs.updateMany(\n {\n lockedUntil: {$exists: true},\n },\n {\n $unset: {lockedUntil: ''},\n },\n )\n\n return result.modifiedCount\n }\n\n async ensureJobRecord(job: JobDefinitionWithName) {\n const result = await this.jobs.upsert(\n {\n jobName: job.name,\n },\n {\n $set: {\n type: job.type,\n priority: (job as RecurrentJobDefinition).priority,\n },\n $setOnInsert: {\n nextRunAt: new Date(),\n },\n },\n )\n\n if (result.upsertedId) {\n logger.debug(`Created job record for \"${job.name}\"`)\n } else {\n logger.debug(`Record for job \"${job.name}\" already exists`)\n }\n }\n\n async scheduleJob(options: ScheduleJobRecordOptions) {\n try {\n await this.jobs.insertOne({\n jobName: options.name,\n uniqueIdentifier: options.uniqueIdentifier,\n params: options.params,\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n type: 'event',\n })\n } catch (error) {\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n options.uniqueIdentifier\n ) {\n logger.info(\n `Job \"${options.name}\" with identifier \"${options.uniqueIdentifier}\" already exists`,\n )\n } else {\n throw error\n }\n }\n }\n\n async scheduleJobs(jobs: ScheduleJobRecordOptions[]): Promise<ScheduleJobsResult> {\n if (jobs.length === 0) {\n return {scheduledCount: 0, skippedCount: 0, errors: []}\n }\n\n // Process each job individually to handle errors properly\n let scheduledCount = 0\n let skippedCount = 0\n const errors: Array<{index: number; error: Error; job: ScheduleJobRecordOptions}> = []\n\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i]\n try {\n // Insert directly to get better error handling than the single scheduleJob method\n await this.jobs.insertOne({\n jobName: job.name,\n uniqueIdentifier: job.uniqueIdentifier,\n params: job.params,\n nextRunAt: job.nextRunAt,\n priority: job.priority,\n type: 'event',\n })\n scheduledCount++\n } catch (error) {\n // Check if it's a validation error with uniqueIdentifier constraint\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n job.uniqueIdentifier\n ) {\n logger.info(`Job \"${job.name}\" with identifier \"${job.uniqueIdentifier}\" already exists`)\n skippedCount++\n } else {\n errors.push({\n index: i,\n error: error instanceof Error ? error : new Error(String(error)),\n job,\n })\n }\n }\n }\n\n logger.debug(\n `Scheduled ${scheduledCount} jobs successfully, skipped ${skippedCount}, errors: ${errors.length}`,\n )\n\n return {\n scheduledCount,\n skippedCount,\n errors,\n }\n }\n}\n","import {createEnum, InferSchemaType, schemaWithName} from '@orion-js/schema'\n\n/**\n * Enum representing the status of a job record.\n * - 'pending': Job is active and can be executed (default for existing records)\n * - 'maxTriesReached': Job has exhausted all retry attempts and won't be executed\n */\nexport const JobStatusEnum = createEnum('JobStatus', ['pending', 'maxTriesReached'])\n\nexport const JobRecordSchema = schemaWithName('JobRecord', {\n _id: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: createEnum('JobType', ['recurrent', 'event'])},\n priority: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n nextRunAt: {type: 'date'},\n lastRunAt: {type: 'date', optional: true},\n lockedUntil: {type: 'date', optional: true},\n tries: {type: 'number', optional: true},\n params: {type: 'blackbox', optional: true},\n /**\n * Status of the job. Optional for backwards compatibility with existing records.\n * Records without this field are treated as 'pending'.\n */\n status: {type: JobStatusEnum, optional: true},\n})\n\nexport type JobRecord = InferSchemaType<typeof JobRecordSchema>\n","export type Options = {\n getNextRun?: () => Date\n runIn?: number\n runEvery?: number\n runAt?: Date\n} & {[key: string]: any}\n\nexport const getNextRunDate = (options: Options) => {\n if (options.runIn) {\n return new Date(Date.now() + options.runIn)\n }\n\n if (options.runEvery) {\n return new Date(Date.now() + options.runEvery)\n }\n\n if (options.runAt) {\n return options.runAt\n }\n\n if (options.getNextRun) {\n return options.getNextRun()\n }\n\n return new Date()\n}\n","import {sleep} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinitionWithName, JobsDefinition} from '../types/JobsDefinition'\nimport {StartWorkersConfig} from '../types/StartConfig'\nimport {WorkerInstance, WorkersInstance} from '../types/Worker'\nimport {ExecuteJobConfig, Executor} from './Executor'\n\n@Service()\nexport class WorkerService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n @Inject(() => Executor)\n private executor: Executor\n\n getJobNames(jobs: JobsDefinition) {\n return Object.keys(jobs)\n }\n\n getJobs(jobs: JobsDefinition): JobDefinitionWithName[] {\n return Object.keys(jobs).map(name => {\n return {\n name,\n ...jobs[name],\n }\n })\n }\n\n async runWorkerLoop(\n config: StartWorkersConfig,\n workerInstance: WorkerInstance,\n jobNames: string[],\n executeConfig: ExecuteJobConfig,\n ) {\n const jobToRun = await this.jobsRepo.getJobAndLock(jobNames, config.defaultLockTime)\n if (!jobToRun) {\n logger.debug('No job to run')\n return false\n }\n\n logger.debug(`Got job [w${workerInstance.workerIndex}] to run:`, jobToRun)\n\n await this.executor.executeJob(executeConfig, jobToRun, workerInstance.respawn)\n\n return true\n }\n\n async startWorker(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n const names = this.getJobNames(config.jobs)\n logger.debug(\n `Running worker loop [w${workerInstance.workerIndex}] for jobs \"${names.join(', ')}\"...`,\n )\n const executeConfig: ExecuteJobConfig = {\n jobs: config.jobs,\n maxTries: config.maxTries,\n onMaxTriesReached: config.onMaxTriesReached,\n }\n\n while (true) {\n if (!workerInstance.running) {\n logger.info(`Got signal to stop. Stopping worker [w${workerInstance.workerIndex}]...`)\n return\n }\n\n try {\n const didRun = await this.runWorkerLoop(config, workerInstance, names, executeConfig)\n if (!didRun) await sleep(config.pollInterval)\n if (didRun) await sleep(config.cooldownPeriod)\n } catch (error) {\n logger.error('Error in job runner.', {error})\n await sleep(config.pollInterval)\n }\n }\n }\n\n createWorkersInstanceDefinition(config: StartWorkersConfig): WorkersInstance {\n const workersInstance: WorkersInstance = {\n running: true,\n workersCount: config.workersCount,\n workers: [],\n stop: async () => {\n logger.info('Stopping workers...')\n workersInstance.running = false\n const stopingPromises = workersInstance.workers.map(worker => worker.stop())\n await Promise.all(stopingPromises)\n },\n }\n\n return workersInstance\n }\n\n async ensureRecords(config: StartWorkersConfig) {\n const jobs = this.getJobs(config.jobs)\n\n await Promise.all(\n jobs\n .filter(job => job.type === 'recurrent')\n .map(async job => {\n logger.debug(`Ensuring records for job \"${job.name}\"...`)\n await this.jobsRepo.ensureJobRecord(job)\n }),\n )\n }\n\n async startANewWorker(\n config: StartWorkersConfig,\n workersInstance: WorkersInstance,\n workerIndex = workersInstance.workers.length,\n ) {\n if (!workersInstance.running) {\n return\n }\n\n const workerInstance: WorkerInstance = {\n running: true,\n workerIndex,\n stop: async () => {\n logger.info(`Stopping worker [w${workerIndex}]...`)\n workerInstance.running = false\n await workerInstance.promise\n },\n respawn: async () => {\n logger.info(`Respawning worker [w${workerIndex}]...`)\n workerInstance.running = false\n await this.startANewWorker(config, workersInstance, workerIndex)\n },\n }\n\n const workerPromise = this.startWorker(config, workerInstance)\n\n workerInstance.promise = workerPromise\n workersInstance.workers[workerIndex] = workerInstance\n }\n\n async runWorkers(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n logger.debug('Will ensure records for recurrent jobs')\n await this.ensureRecords(config)\n\n const workersCount = config.workersCount\n const workerWord = workersCount === 1 ? 'worker' : 'workers'\n logger.info(`Starting ${workersCount} ${workerWord}`)\n\n for (let workerIndex = 0; workerIndex < workersCount; workerIndex++) {\n this.startANewWorker(config, workersInstance, workerIndex)\n }\n }\n\n /**\n * Starts the job workers with the provided configuration.\n * @param userConfig - Configuration for the workers. Required fields: jobs, maxTries, onMaxTriesReached\n */\n startWorkers(userConfig: StartWorkersConfig): WorkersInstance {\n // Apply defaults for optional fields\n const config: StartWorkersConfig = {\n cooldownPeriod: 100,\n pollInterval: 3000,\n workersCount: 4,\n defaultLockTime: 30 * 1000,\n ...userConfig,\n }\n\n setNameToJobs(config.jobs)\n\n const workersInstance = this.createWorkersInstanceDefinition(config)\n logger.debug('Starting workers', config)\n\n this.runWorkers(config, workersInstance)\n\n return workersInstance\n }\n}\n\nfunction setNameToJobs(jobs: JobsDefinition) {\n for (const name of Object.keys(jobs)) {\n jobs[name].jobName = name\n }\n}\n","import {SpanStatusCode, trace} from '@opentelemetry/api'\nimport {logger, runWithOrionAsyncContext, updateOrionAsyncContext} from '@orion-js/logger'\nimport {Blackbox} from '@orion-js/schema'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsHistoryRepo} from '../repos/JobsHistoryRepo'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinition, JobsDefinition} from '../types/JobsDefinition'\nimport {ExecutionContext, JobToRun} from '../types/Worker'\nimport {getNextRunDate} from './getNextRunDate'\n\n/**\n * Configuration for job execution including max tries settings.\n */\nexport interface ExecuteJobConfig {\n jobs: JobsDefinition\n maxTries: number\n onMaxTriesReached: (job: JobToRun) => Promise<void>\n}\n\n@Service()\nexport class Executor {\n @Inject(() => JobsRepo)\n private readonly jobsRepo: JobsRepo\n\n @Inject(() => JobsHistoryRepo)\n private readonly jobsHistoryRepo: JobsHistoryRepo\n\n /**\n * Determines the effective lock time for a job execution.\n * Job-specific lockTime takes precedence over the default lockTime from config.\n */\n getEffectiveLockTime(job: JobDefinition, jobToRun: JobToRun): number {\n return job.lockTime ?? jobToRun.lockTime\n }\n\n getContext(job: JobDefinition, jobToRun: JobToRun, onStale: Function): ExecutionContext {\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n let staleTimeout = setTimeout(() => onStale(), effectiveLockTime)\n staleTimeout.unref?.()\n return {\n definition: job,\n record: jobToRun,\n tries: jobToRun.tries || 0,\n clearStaleTimeout: () => clearTimeout(staleTimeout),\n extendLockTime: async (extraTime: number) => {\n clearTimeout(staleTimeout)\n staleTimeout = setTimeout(() => onStale(), extraTime)\n staleTimeout.unref?.()\n await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime)\n },\n logger: logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n }),\n }\n }\n\n getJobDefinition(jobToRun: JobToRun, jobs: JobsDefinition) {\n const job = jobs[jobToRun.name]\n\n if (jobToRun.type !== job.type) {\n logger.warn(\n `Job record \"${jobToRun.name}\" is \"${jobToRun.type}\" but definition is \"${job.type}\"`,\n )\n return\n }\n\n return job\n }\n\n /**\n * Determines the effective max tries for a job.\n * Job-specific maxTries takes precedence over the global maxTries from config.\n */\n getEffectiveMaxTries(job: JobDefinition, globalMaxTries: number): number {\n return job.maxTries ?? globalMaxTries\n }\n\n /**\n * Handles when a job has reached its maximum retry attempts.\n * Marks the job in the database and invokes the onMaxTriesReached callback.\n */\n async handleMaxTriesReached(\n jobToRun: JobToRun,\n context: ExecutionContext,\n onMaxTriesReached: (job: JobToRun) => Promise<void>,\n ) {\n context.logger.warn(\n `Job \"${jobToRun.name}\" has reached max tries (${jobToRun.tries}). Marking as maxTriesReached.`,\n )\n await this.jobsRepo.markJobAsMaxTriesReached(jobToRun.jobId)\n\n // Invoke the callback to notify administrators\n try {\n await onMaxTriesReached(jobToRun)\n } catch (callbackError) {\n context.logger.error(`Error in onMaxTriesReached callback for job \"${jobToRun.name}\"`, {\n error: callbackError,\n })\n }\n }\n\n async onError(\n error: unknown,\n job: JobDefinition,\n jobToRun: JobToRun,\n context: ExecutionContext,\n config: ExecuteJobConfig,\n ) {\n const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries)\n\n // Helper to schedule next run for recurrent jobs (used when dismissing)\n const scheduleRecurrent = async () => {\n if (job.type === 'recurrent') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n }\n\n // Helper to handle retry with max tries check\n const handleRetry = async (nextRunAt: Date) => {\n // Check if we've reached max tries before scheduling another retry\n if (jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, context, config.onMaxTriesReached)\n return\n }\n\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt,\n addTries: true,\n priority: job.type === 'recurrent' ? job.priority : jobToRun.priority,\n })\n }\n\n // If no custom error handler, check max tries and schedule recurrent if applicable\n if (!job.onError) {\n context.logger.error(`Error executing job \"${jobToRun.name}\"`, {error})\n\n // For jobs without onError, check if max tries reached\n if (jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, context, config.onMaxTriesReached)\n return\n }\n\n await scheduleRecurrent()\n return\n }\n\n context.logger.info(`Error executing job \"${jobToRun.name}\"`, {error})\n const result = await job.onError(\n error instanceof Error ? error : new Error(String(error)),\n jobToRun.params,\n context,\n )\n\n if (result.action === 'dismiss') {\n await scheduleRecurrent()\n return\n }\n\n if (result.action === 'retry') {\n await handleRetry(getNextRunDate(result))\n }\n }\n\n async saveExecution(options: {\n startedAt: Date\n status: 'stale' | 'error' | 'success'\n errorMessage?: string\n result?: Blackbox\n job: JobDefinition\n jobToRun: JobToRun\n }) {\n const {startedAt, status, errorMessage, result, job, jobToRun} = options\n const endedAt = new Date()\n\n if (job.saveExecutionsFor !== 0) {\n const oneWeek = 1000 * 60 * 60 * 24 * 7\n const saveExecutionsFor = job.saveExecutionsFor || oneWeek\n await this.jobsHistoryRepo.saveExecution({\n jobId: jobToRun.jobId,\n executionId: jobToRun.executionId,\n jobName: jobToRun.name,\n type: jobToRun.type,\n priority: jobToRun.priority,\n tries: jobToRun.tries,\n uniqueIdentifier: jobToRun.uniqueIdentifier,\n startedAt,\n endedAt,\n duration: endedAt.getTime() - startedAt.getTime(),\n expiresAt: new Date(Date.now() + saveExecutionsFor),\n status,\n errorMessage,\n params: jobToRun.params,\n result,\n })\n }\n }\n\n async afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n if (job.type === 'recurrent') {\n context.logger.debug(`Scheduling next run for recurrent job \"${jobToRun.name}\"`)\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n if (job.type === 'event') {\n context.logger.debug(`Removing event job after success \"${jobToRun.name}\"`)\n await this.jobsRepo.deleteEventJob(jobToRun.jobId)\n }\n }\n\n async executeJob(config: ExecuteJobConfig, jobToRun: JobToRun, respawnWorker: () => void) {\n const job = this.getJobDefinition(jobToRun, config.jobs)\n if (!job) return\n\n // If job has a custom lockTime different from the default, update the database lock\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n if (effectiveLockTime !== jobToRun.lockTime) {\n await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime)\n }\n\n const tracer = trace.getTracer('orionjs.dogs', '1.0')\n\n await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async span => {\n try {\n const startedAt = new Date()\n\n const onStale = async () => {\n if (job.onStale) {\n context.logger.info(`Job \"${jobToRun.name}\" is stale`)\n job.onStale(jobToRun.params, context)\n } else {\n context.logger.error(`Job \"${jobToRun.name}\" is stale`)\n }\n\n await this.jobsRepo.setJobRecordPriority(jobToRun.jobId, 0)\n\n void respawnWorker()\n\n void this.saveExecution({\n startedAt,\n status: 'stale',\n result: null,\n errorMessage: null,\n job,\n jobToRun,\n }).catch(error => {\n context.logger.error('Error saving stale execution history', {error})\n })\n }\n\n const context = this.getContext(job, jobToRun, onStale)\n\n const extraContext = {\n controllerType: 'job' as const,\n jobName: jobToRun.name,\n params: jobToRun.params,\n }\n\n await runWithOrionAsyncContext(extraContext, async () => {\n try {\n // Inject async context update\n updateOrionAsyncContext({\n jobName: jobToRun.name,\n params: jobToRun.params,\n })\n const result = await job.resolve(jobToRun.params, context)\n context.clearStaleTimeout()\n\n void this.saveExecution({\n startedAt,\n status: 'success',\n result: result || null,\n errorMessage: null,\n job,\n jobToRun,\n }).catch(error => {\n context.logger.error('Error saving successful execution history', {error})\n })\n\n await this.afterExecutionSuccess(job, jobToRun, context)\n } catch (error) {\n context.clearStaleTimeout()\n void this.saveExecution({\n startedAt,\n status: 'error',\n result: null,\n errorMessage: (error as Error).message,\n job,\n jobToRun,\n }).catch(saveError => {\n context.logger.error('Error saving failed execution history', {error: saveError})\n })\n\n await this.onError(error, job, jobToRun, context, config)\n }\n })\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: (error as Error).message,\n })\n throw error\n } finally {\n span.end()\n }\n })\n }\n}\n","import {Collection, MongoCollection, Repository, MongoDB} from '@orion-js/mongodb'\nimport {omit} from 'rambdax'\nimport {HistoryRecord, HistoryRecordSchema} from '../types/HistoryRecord'\n\n@Repository()\nexport class JobsHistoryRepo {\n @MongoCollection({\n name: 'orionjs.jobs_dogs_history',\n idGeneration: 'uuid',\n schema: HistoryRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n startedAt: 1,\n },\n },\n {\n keys: {\n executionId: 1,\n },\n },\n {\n keys: {\n expiresAt: 1,\n },\n options: {\n expireAfterSeconds: 0,\n },\n },\n ],\n })\n history: Collection<HistoryRecord>\n\n async saveExecution(record: MongoDB.WithoutId<HistoryRecord>) {\n await this.history.upsert(\n {executionId: record.executionId},\n {\n $setOnInsert: {\n status: record.status,\n },\n $set: {\n ...omit(['status'], record),\n },\n },\n )\n }\n\n async getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]> {\n const cursor = this.history.find({jobName}).sort({startedAt: -1})\n\n if (skip) {\n cursor.skip(skip)\n }\n\n if (limit) {\n cursor.limit(limit)\n }\n\n return await cursor.toArray()\n }\n}\n","function _isInteger(n){\n return n << 0 === n\n}\n\nexport const isInteger = Number.isInteger || _isInteger\n\n/**\n * Check if `index` is integer even if it is a string.\n */\nexport const isIndexInteger = index => Number.isInteger(Number(index))\n","import { isInteger } from './isInteger.js'\n\nexport function createPath(path, delimiter = '.'){\n return typeof path === 'string' ?\n path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) :\n path\n}\n","export function compare(a, b){\n return String(a) === String(b)\n}\n","import { compare } from './compare.js'\n\nexport function includes(a, list){\n let index = -1\n const { length } = list\n\n while (++index < length)\n if (compare(list[ index ], a))\n return true\n\n return false\n}\n","import { createPath } from './_internals/createPath.js'\nimport { includes } from './_internals/includes.js'\n\nexport function omit(propsToOmit, obj){\n if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)\n\n if (obj === null || obj === undefined)\n return undefined\n\n const propsToOmitValue = createPath(propsToOmit, ',')\n const willReturn = {}\n\n for (const key in obj)\n if (!includes(key, propsToOmitValue))\n willReturn[ key ] = obj[ key ]\n\n return willReturn\n}\n","import {InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const HistoryRecordSchema = schemaWithName('HistoryRecord', {\n _id: {type: 'string'},\n jobId: {type: 'string'},\n executionId: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: 'string'},\n priority: {type: 'number'},\n tries: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n startedAt: {type: 'date'},\n endedAt: {type: 'date'},\n duration: {type: 'number'},\n expiresAt: {type: 'date', optional: true},\n status: {type: 'string', enum: ['success', 'error', 'stale']},\n errorMessage: {type: 'string', optional: true},\n params: {type: 'blackbox', optional: true},\n result: {type: 'any', optional: true},\n})\n\nexport type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>\n","import {getInstance, Service} from '@orion-js/services'\nimport {createEventJob, defineJob} from '../defineJob'\nimport type {CreateEventJobOptions, JobDefinition, RecurrentJobDefinition} from '../types'\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst jobsMetadata = new Map<any, Record<string, any>>()\n\nexport function Jobs() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n Service()(target, context)\n\n context.addInitializer(function (this) {\n serviceMetadata.set(this, {_serviceType: 'jobs'})\n })\n }\n}\n\nexport function RecurrentJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function RecurrentJob(\n options: Omit<RecurrentJobDefinition, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function RecurrentJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = defineJob({\n ...options,\n type: 'recurrent',\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function EventJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EventJob(\n options: Omit<CreateEventJobOptions<any>, 'resolve'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EventJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n context.addInitializer(function (this) {\n const jobs = jobsMetadata.get(this) || {}\n\n if (context.kind === 'method') {\n jobs[propertyKey] = createEventJob({\n ...options,\n resolve: this[propertyKey].bind(this),\n })\n }\n\n if (context.kind === 'field') {\n jobs[propertyKey] = this[propertyKey]\n }\n\n jobsMetadata.set(this, jobs)\n })\n\n return method\n }\n}\n\nexport function getServiceJobs(target: any): {\n [key: string]: JobDefinition\n} {\n const instance = getInstance(target)\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'jobs') {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const jobsMap = jobsMetadata.get(instance) || {}\n\n return jobsMap\n}\n\n/**\n * Logs\n * after event job {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n}\nbefore recurrent job Map(1) {\n ExampleJobsService {} => {\n job1: { type: 'event', resolve: [Function: bound job1] AsyncFunction }\n }\n}\nbefore recurrent job undefined\nafter recurrent job {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n}\n{\n serviceJobs: {\n job2: {\n runEvery: 1000,\n type: 'recurrent',\n resolve: [Function: bound job2] AsyncFunction,\n priority: 100\n }\n }\n}\n */\n","import {\n CreateEventJobOptions,\n CreateJobOptions,\n CreateRecurrentJobOptions,\n EventJobDefinition,\n JobDefinition,\n RecurrentJobDefinition,\n} from '../types/JobsDefinition'\nimport {scheduleJob, ScheduleJobsResult, scheduleJobs} from '..'\nimport {ScheduleJobOptionsWithoutName} from '../types/Events'\nimport {cleanAndValidate, SchemaInAnyOrionForm} from '@orion-js/schema'\nimport parse from 'parse-duration'\n\nexport function createEventJob<TParamsSchema extends SchemaInAnyOrionForm>(\n options: CreateEventJobOptions<TParamsSchema>,\n): EventJobDefinition<TParamsSchema> {\n const jobDefinition: EventJobDefinition<TParamsSchema> = {\n ...options,\n type: 'event',\n schedule: null,\n scheduleJobs: null,\n }\n\n jobDefinition.schedule = async (scheduleOptions: ScheduleJobOptionsWithoutName<TParamsSchema>) => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return await scheduleJob({\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n })\n }\n\n jobDefinition.scheduleJobs = async (\n jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>,\n ): Promise<ScheduleJobsResult> => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n // Process all job parameters if schema validation is needed\n const processedJobs = await Promise.all(\n jobs.map(async scheduleOptions => {\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return {\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n }\n }),\n )\n\n return await scheduleJobs(processedJobs)\n }\n\n return jobDefinition\n}\n\nexport function createRecurrentJob(options: CreateRecurrentJobOptions): RecurrentJobDefinition {\n const jobDefinition: RecurrentJobDefinition = {\n ...options,\n priority: options.priority ?? 100,\n type: 'recurrent',\n runEvery: typeof options.runEvery === 'string' ? parse(options.runEvery) : options.runEvery,\n }\n\n return jobDefinition\n}\n\n/**\n * @deprecated Use `createEventJob` or `createRecurrentJob` instead.\n */\nexport const defineJob = (\n options: CreateJobOptions & {type: 'event' | 'recurrent'},\n): JobDefinition => {\n return options.type === 'event'\n ? createEventJob(options as any)\n : createRecurrentJob(options as any)\n}\n"],"mappings":"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","names":["getInstance","logger","_init","logger","logger","Inject","Service","logger","Inject","Service","MongoCollection","Repository","schemaWithName","_init","Repository","MongoCollection","_jobsRepo_dec","_init","Service","Inject","_a","logger","_jobsRepo_dec","_init","Service","Inject","logger","Service","Service","getInstance"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/services/EventsService.ts","../src/repos/JobsRepo.ts","../src/types/JobRecord.ts","../src/services/getNextRunDate.ts","../src/services/WorkerService.ts","../src/services/Executor.ts","../src/repos/JobsHistoryRepo.ts","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/isInteger.js","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/createPath.js","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/compare.js","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/_internals/includes.js","../../../node_modules/.bun/rambdax@11.3.1/node_modules/rambdax/src/omit.js","../src/types/HistoryRecord.ts","../src/service/index.ts","../src/defineJob/index.ts"],"sourcesContent":["import {getInstance} from '@orion-js/services'\nimport {EventsService} from './services/EventsService'\nimport {WorkerService} from './services/WorkerService'\nimport {StartWorkersConfig} from './types/StartConfig'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from './types/Events'\nimport {JobsHistoryRepo} from './repos/JobsHistoryRepo'\nimport {JobsRepo} from './repos/JobsRepo'\nimport {SchemaInAnyOrionForm} from '@orion-js/schema'\n\nexport * from './types'\nexport * from './service'\nexport * from './defineJob'\n\nconst workerService = getInstance(WorkerService)\nconst eventsService = getInstance(EventsService)\nconst jobsHistoryRepo = getInstance(JobsHistoryRepo)\nconst jobsRepo = getInstance(JobsRepo)\n\nconst startWorkers = (config: StartWorkersConfig) => {\n return workerService.startWorkers(config)\n}\n\n/**\n * @deprecated Use the event job definition.schedule method instead.\n */\nconst scheduleJob = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n options: ScheduleJobOptions<TParamsSchema>,\n) => {\n return eventsService.scheduleJob(options)\n}\n\n/**\n * Schedule multiple jobs at once for better performance.\n * @deprecated Use the event job definition.scheduleJobs method instead.\n */\nconst scheduleJobs = <TParamsSchema extends SchemaInAnyOrionForm = any>(\n jobs: ScheduleJobsOptions<TParamsSchema>,\n): Promise<ScheduleJobsResult> => {\n return eventsService.scheduleJobs(jobs)\n}\n\nexport {startWorkers, scheduleJob, scheduleJobs, jobsHistoryRepo, jobsRepo}\n","import {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {ScheduleJobOptions, ScheduleJobsOptions, ScheduleJobsResult} from '../types/Events'\nimport {getNextRunDate} from './getNextRunDate'\n\n@Service()\nexport class EventsService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n async scheduleJob(options: ScheduleJobOptions) {\n logger.debug('Scheduling job...', options)\n\n await this.jobsRepo.scheduleJob({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n })\n }\n\n async scheduleJobs(jobs: ScheduleJobsOptions): Promise<ScheduleJobsResult> {\n logger.debug(`Scheduling ${jobs.length} jobs...`)\n\n const jobRecords = jobs.map(options => ({\n name: options.name,\n priority: options.priority || 100,\n nextRunAt: getNextRunDate(options),\n params: options.params || null,\n uniqueIdentifier: options.uniqueIdentifier,\n }))\n\n return await this.jobsRepo.scheduleJobs(jobRecords)\n }\n}\n","import {generateId} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Collection, MongoCollection, MongoDB, Repository} from '@orion-js/mongodb'\nimport {ScheduleJobRecordOptions, ScheduleJobsResult} from '../types/Events'\nimport {JobRecord, JobRecordSchema} from '../types/JobRecord'\nimport {JobDefinitionWithName, RecurrentJobDefinition} from '../types/JobsDefinition'\nimport {JobToRun} from '../types/Worker'\n\n@Repository()\nexport class JobsRepo {\n @MongoCollection({\n idGeneration: 'uuid',\n name: 'orionjs.jobs_dogs_records',\n schema: JobRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n priority: -1,\n nextRunAt: 1,\n },\n },\n {\n keys: {\n jobName: 1,\n },\n options: {\n unique: true,\n partialFilterExpression: {type: 'recurrent'},\n },\n },\n {\n keys: {\n uniqueIdentifier: 1,\n },\n options: {\n unique: true,\n sparse: true,\n },\n },\n ],\n })\n jobs: Collection<JobRecord>\n\n async getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun> {\n const lockedUntil = new Date(Date.now() + lockTime)\n\n const job = await this.jobs.findOneAndUpdate(\n {\n jobName: {$in: jobNames},\n nextRunAt: {$lte: new Date()},\n $or: [{lockedUntil: {$exists: false}}, {lockedUntil: {$lte: new Date()}}],\n // Exclude jobs that have reached max tries. Using $ne handles backwards compatibility\n // since records without the status field will still match (undefined !== 'maxTriesReached')\n status: {$ne: 'maxTriesReached'},\n },\n {\n $set: {lockedUntil, lastRunAt: new Date()},\n },\n {\n mongoOptions: {\n sort: {\n priority: -1,\n nextRunAt: 1,\n },\n returnDocument: 'before',\n },\n },\n )\n\n if (!job) return\n\n let tries = job.tries || 1\n const wasStale = Boolean(job.lockedUntil)\n\n if (wasStale) {\n logger.info(`Running job \"${job.jobName}\" that was staled`)\n await this.jobs.updateOne(job._id, {$inc: {tries: 1}})\n tries++\n }\n\n return {\n jobId: job._id,\n executionId: generateId(),\n name: job.jobName,\n params: job.params,\n type: job.type,\n tries,\n lockTime,\n priority: job.priority,\n uniqueIdentifier: job.uniqueIdentifier,\n wasStale,\n }\n }\n\n async setJobRecordPriority(jobId: string, priority: number) {\n await this.jobs.updateOne(jobId, {$set: {priority}})\n }\n\n async scheduleNextRun(options: {\n jobId: string\n nextRunAt: Date\n addTries: boolean\n priority: number\n }) {\n const updator: MongoDB.UpdateFilter<JobRecord> = {\n $set: {\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n ...(options.addTries ? {} : {tries: 0}),\n },\n $unset: {lockedUntil: ''},\n ...(options.addTries ? {$inc: {tries: 1}} : {}),\n }\n\n await this.jobs.updateOne(options.jobId, updator)\n }\n\n async deleteEventJob(jobId: string) {\n await this.jobs.deleteOne({_id: jobId, type: 'event'})\n }\n\n /**\n * Marks a job as having reached its maximum tries limit.\n * The job will remain in the database but won't be picked up for execution.\n */\n async markJobAsMaxTriesReached(jobId: string) {\n await this.jobs.updateOne(\n {_id: jobId},\n {\n $set: {status: 'maxTriesReached'},\n $unset: {lockedUntil: ''},\n },\n )\n }\n\n async extendLockTime(jobId: string, extraTime: number) {\n await this.updateLockTime(jobId, extraTime)\n }\n\n /**\n * Updates the lock time for a job to the specified duration from now.\n * Can be used to both extend or shorten the lock time.\n */\n async updateLockTime(jobId: string, lockDuration: number) {\n const lockedUntil = new Date(Date.now() + lockDuration)\n await this.jobs.updateOne(\n {\n _id: jobId,\n },\n {\n $set: {lockedUntil},\n },\n )\n }\n\n async unlockAllJobs(): Promise<number> {\n const result = await this.jobs.updateMany(\n {\n lockedUntil: {$exists: true},\n },\n {\n $unset: {lockedUntil: ''},\n },\n )\n\n return result.modifiedCount\n }\n\n async ensureJobRecord(job: JobDefinitionWithName) {\n const result = await this.jobs.upsert(\n {\n jobName: job.name,\n },\n {\n $set: {\n type: job.type,\n priority: (job as RecurrentJobDefinition).priority,\n },\n $setOnInsert: {\n nextRunAt: new Date(),\n },\n },\n )\n\n if (result.upsertedId) {\n logger.debug(`Created job record for \"${job.name}\"`)\n } else {\n logger.debug(`Record for job \"${job.name}\" already exists`)\n }\n }\n\n async scheduleJob(options: ScheduleJobRecordOptions) {\n try {\n await this.jobs.insertOne({\n jobName: options.name,\n uniqueIdentifier: options.uniqueIdentifier,\n params: options.params,\n nextRunAt: options.nextRunAt,\n priority: options.priority,\n type: 'event',\n })\n } catch (error) {\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n options.uniqueIdentifier\n ) {\n logger.info(\n `Job \"${options.name}\" with identifier \"${options.uniqueIdentifier}\" already exists`,\n )\n } else {\n throw error\n }\n }\n }\n\n async scheduleJobs(jobs: ScheduleJobRecordOptions[]): Promise<ScheduleJobsResult> {\n if (jobs.length === 0) {\n return {scheduledCount: 0, skippedCount: 0, errors: []}\n }\n\n // Process each job individually to handle errors properly\n let scheduledCount = 0\n let skippedCount = 0\n const errors: Array<{index: number; error: Error; job: ScheduleJobRecordOptions}> = []\n\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i]\n try {\n // Insert directly to get better error handling than the single scheduleJob method\n await this.jobs.insertOne({\n jobName: job.name,\n uniqueIdentifier: job.uniqueIdentifier,\n params: job.params,\n nextRunAt: job.nextRunAt,\n priority: job.priority,\n type: 'event',\n })\n scheduledCount++\n } catch (error) {\n // Check if it's a validation error with uniqueIdentifier constraint\n if (\n error.isValidationError &&\n Object.values(error.validationErrors).includes('notUnique') &&\n job.uniqueIdentifier\n ) {\n logger.info(`Job \"${job.name}\" with identifier \"${job.uniqueIdentifier}\" already exists`)\n skippedCount++\n } else {\n errors.push({\n index: i,\n error: error instanceof Error ? error : new Error(String(error)),\n job,\n })\n }\n }\n }\n\n logger.debug(\n `Scheduled ${scheduledCount} jobs successfully, skipped ${skippedCount}, errors: ${errors.length}`,\n )\n\n return {\n scheduledCount,\n skippedCount,\n errors,\n }\n }\n}\n","import {createEnum, InferSchemaType, schemaWithName} from '@orion-js/schema'\n\n/**\n * Enum representing the status of a job record.\n * - 'pending': Job is active and can be executed (default for existing records)\n * - 'maxTriesReached': Job has exhausted all retry attempts and won't be executed\n */\nexport const JobStatusEnum = createEnum('JobStatus', ['pending', 'maxTriesReached'])\n\nexport const JobRecordSchema = schemaWithName('JobRecord', {\n _id: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: createEnum('JobType', ['recurrent', 'event'])},\n priority: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n nextRunAt: {type: 'date'},\n lastRunAt: {type: 'date', optional: true},\n lockedUntil: {type: 'date', optional: true},\n tries: {type: 'number', optional: true},\n params: {type: 'blackbox', optional: true},\n /**\n * Status of the job. Optional for backwards compatibility with existing records.\n * Records without this field are treated as 'pending'.\n */\n status: {type: JobStatusEnum, optional: true},\n})\n\nexport type JobRecord = InferSchemaType<typeof JobRecordSchema>\n","export type Options = {\n getNextRun?: () => Date\n runIn?: number\n runEvery?: number\n runAt?: Date\n} & {[key: string]: any}\n\nexport const getNextRunDate = (options: Options) => {\n if (options.runIn) {\n return new Date(Date.now() + options.runIn)\n }\n\n if (options.runEvery) {\n return new Date(Date.now() + options.runEvery)\n }\n\n if (options.runAt) {\n return options.runAt\n }\n\n if (options.getNextRun) {\n return options.getNextRun()\n }\n\n return new Date()\n}\n","import {sleep} from '@orion-js/helpers'\nimport {logger} from '@orion-js/logger'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinitionWithName, JobsDefinition} from '../types/JobsDefinition'\nimport {StartWorkersConfig} from '../types/StartConfig'\nimport {WorkerInstance, WorkersInstance} from '../types/Worker'\nimport {ExecuteJobConfig, Executor} from './Executor'\n\n@Service()\nexport class WorkerService {\n @Inject(() => JobsRepo)\n private jobsRepo: JobsRepo\n\n @Inject(() => Executor)\n private executor: Executor\n\n getJobNames(jobs: JobsDefinition) {\n return Object.keys(jobs)\n }\n\n getJobs(jobs: JobsDefinition): JobDefinitionWithName[] {\n return Object.keys(jobs).map(name => {\n return {\n name,\n ...jobs[name],\n }\n })\n }\n\n async runWorkerLoop(\n config: StartWorkersConfig,\n workerInstance: WorkerInstance,\n jobNames: string[],\n executeConfig: ExecuteJobConfig,\n ) {\n const jobToRun = await this.jobsRepo.getJobAndLock(jobNames, config.defaultLockTime)\n if (!jobToRun) {\n logger.debug('No job to run')\n return false\n }\n\n logger.debug(`Got job [w${workerInstance.workerIndex}] to run:`, jobToRun)\n\n await this.executor.executeJob(executeConfig, jobToRun, workerInstance.respawn)\n\n return true\n }\n\n async startWorker(config: StartWorkersConfig, workerInstance: WorkerInstance) {\n const names = this.getJobNames(config.jobs)\n logger.debug(\n `Running worker loop [w${workerInstance.workerIndex}] for jobs \"${names.join(', ')}\"...`,\n )\n const executeConfig: ExecuteJobConfig = {\n jobs: config.jobs,\n maxTries: config.maxTries,\n onMaxTriesReached: config.onMaxTriesReached,\n }\n\n while (true) {\n if (!workerInstance.running) {\n logger.info(`Got signal to stop. Stopping worker [w${workerInstance.workerIndex}]...`)\n return\n }\n\n try {\n const didRun = await this.runWorkerLoop(config, workerInstance, names, executeConfig)\n if (!didRun) await sleep(config.pollInterval)\n if (didRun) await sleep(config.cooldownPeriod)\n } catch (error) {\n logger.error('Error in job runner.', {error})\n await sleep(config.pollInterval)\n }\n }\n }\n\n createWorkersInstanceDefinition(config: StartWorkersConfig): WorkersInstance {\n const workersInstance: WorkersInstance = {\n running: true,\n workersCount: config.workersCount,\n workers: [],\n stop: async () => {\n logger.info('Stopping workers...')\n workersInstance.running = false\n const stopingPromises = workersInstance.workers.map(worker => worker.stop())\n await Promise.all(stopingPromises)\n },\n }\n\n return workersInstance\n }\n\n async ensureRecords(config: StartWorkersConfig) {\n const jobs = this.getJobs(config.jobs)\n\n await Promise.all(\n jobs\n .filter(job => job.type === 'recurrent')\n .map(async job => {\n logger.debug(`Ensuring records for job \"${job.name}\"...`)\n await this.jobsRepo.ensureJobRecord(job)\n }),\n )\n }\n\n async startANewWorker(\n config: StartWorkersConfig,\n workersInstance: WorkersInstance,\n workerIndex = workersInstance.workers.length,\n ) {\n if (!workersInstance.running) {\n return\n }\n\n const workerInstance: WorkerInstance = {\n running: true,\n workerIndex,\n stop: async () => {\n logger.info(`Stopping worker [w${workerIndex}]...`)\n workerInstance.running = false\n await workerInstance.promise\n },\n respawn: async () => {\n logger.info(`Respawning worker [w${workerIndex}]...`)\n workerInstance.running = false\n await this.startANewWorker(config, workersInstance, workerIndex)\n },\n }\n\n const workerPromise = this.startWorker(config, workerInstance)\n\n workerInstance.promise = workerPromise\n workersInstance.workers[workerIndex] = workerInstance\n }\n\n async runWorkers(config: StartWorkersConfig, workersInstance: WorkersInstance) {\n logger.debug('Will ensure records for recurrent jobs')\n await this.ensureRecords(config)\n\n const workersCount = config.workersCount\n const workerWord = workersCount === 1 ? 'worker' : 'workers'\n logger.info(`Starting ${workersCount} ${workerWord}`)\n\n for (let workerIndex = 0; workerIndex < workersCount; workerIndex++) {\n this.startANewWorker(config, workersInstance, workerIndex)\n }\n }\n\n /**\n * Starts the job workers with the provided configuration.\n * @param userConfig - Configuration for the workers. Required fields: jobs, maxTries, onMaxTriesReached\n */\n startWorkers(userConfig: StartWorkersConfig): WorkersInstance {\n // Apply defaults for optional fields\n const config: StartWorkersConfig = {\n cooldownPeriod: 100,\n pollInterval: 3000,\n workersCount: 4,\n defaultLockTime: 30 * 1000,\n ...userConfig,\n }\n\n setNameToJobs(config.jobs)\n\n const workersInstance = this.createWorkersInstanceDefinition(config)\n logger.debug('Starting workers', config)\n\n this.runWorkers(config, workersInstance)\n\n return workersInstance\n }\n}\n\nfunction setNameToJobs(jobs: JobsDefinition) {\n for (const name of Object.keys(jobs)) {\n jobs[name].jobName = name\n }\n}\n","import {SpanStatusCode, trace} from '@opentelemetry/api'\nimport {logger, runWithOrionAsyncContext, updateOrionAsyncContext} from '@orion-js/logger'\nimport {Blackbox} from '@orion-js/schema'\nimport {Inject, Service} from '@orion-js/services'\nimport {JobsHistoryRepo} from '../repos/JobsHistoryRepo'\nimport {JobsRepo} from '../repos/JobsRepo'\nimport {JobDefinition, JobsDefinition} from '../types/JobsDefinition'\nimport {ExecutionContext, JobToRun} from '../types/Worker'\nimport {getNextRunDate} from './getNextRunDate'\n\n/**\n * Configuration for job execution including max tries settings.\n */\nexport interface ExecuteJobConfig {\n jobs: JobsDefinition\n maxTries: number\n onMaxTriesReached: (job: JobToRun) => Promise<void>\n}\n\n@Service()\nexport class Executor {\n @Inject(() => JobsRepo)\n private readonly jobsRepo: JobsRepo\n\n @Inject(() => JobsHistoryRepo)\n private readonly jobsHistoryRepo: JobsHistoryRepo\n\n /**\n * Determines the effective lock time for a job execution.\n * Job-specific lockTime takes precedence over the default lockTime from config.\n */\n getEffectiveLockTime(job: JobDefinition, jobToRun: JobToRun): number {\n return job.lockTime ?? jobToRun.lockTime\n }\n\n getContext(job: JobDefinition, jobToRun: JobToRun, onStale: Function): ExecutionContext {\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n let staleTimeout = setTimeout(() => onStale(), effectiveLockTime)\n staleTimeout.unref?.()\n return {\n definition: job,\n record: jobToRun,\n tries: jobToRun.tries || 0,\n clearStaleTimeout: () => clearTimeout(staleTimeout),\n extendLockTime: async (extraTime: number) => {\n clearTimeout(staleTimeout)\n staleTimeout = setTimeout(() => onStale(), extraTime)\n staleTimeout.unref?.()\n await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime)\n },\n logger: logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n }),\n }\n }\n\n getJobDefinition(jobToRun: JobToRun, jobs: JobsDefinition) {\n const job = jobs[jobToRun.name]\n\n if (jobToRun.type !== job.type) {\n logger.warn(\n `Job record \"${jobToRun.name}\" is \"${jobToRun.type}\" but definition is \"${job.type}\"`,\n )\n return\n }\n\n return job\n }\n\n /**\n * Determines the effective max tries for a job.\n * Job-specific maxTries takes precedence over the global maxTries from config.\n */\n getEffectiveMaxTries(job: JobDefinition, globalMaxTries: number): number {\n return job.maxTries ?? globalMaxTries\n }\n\n /**\n * Handles when a job has reached its maximum retry attempts.\n * Marks the job in the database and invokes the onMaxTriesReached callback.\n */\n async handleMaxTriesReached(\n jobToRun: JobToRun,\n onMaxTriesReached: (job: JobToRun) => Promise<void>,\n ) {\n const jobLogger = logger.addMetadata({\n jobName: jobToRun.name,\n jobId: jobToRun.jobId,\n })\n\n jobLogger.warn(\n `Job \"${jobToRun.name}\" has reached max tries (${jobToRun.tries}). Marking as maxTriesReached.`,\n )\n await this.jobsRepo.markJobAsMaxTriesReached(jobToRun.jobId)\n\n // Invoke the callback to notify administrators\n try {\n await onMaxTriesReached(jobToRun)\n } catch (callbackError) {\n jobLogger.error(`Error in onMaxTriesReached callback for job \"${jobToRun.name}\"`, {\n error: callbackError,\n })\n }\n }\n\n async onError(\n error: unknown,\n job: JobDefinition,\n jobToRun: JobToRun,\n context: ExecutionContext,\n config: ExecuteJobConfig,\n ) {\n const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries)\n\n // Helper to schedule next run for recurrent jobs (used when dismissing)\n const scheduleRecurrent = async () => {\n if (job.type === 'recurrent') {\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n }\n\n // Helper to handle retry with max tries check\n const handleRetry = async (nextRunAt: Date) => {\n // Check if we've reached max tries before scheduling another retry\n if (jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached)\n return\n }\n\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt,\n addTries: true,\n priority: job.type === 'recurrent' ? job.priority : jobToRun.priority,\n })\n }\n\n // If no custom error handler, check max tries and schedule recurrent if applicable\n if (!job.onError) {\n context.logger.error(`Error executing job \"${jobToRun.name}\"`, {error})\n\n // For jobs without onError, check if max tries reached\n if (jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached)\n return\n }\n\n await scheduleRecurrent()\n return\n }\n\n context.logger.info(`Error executing job \"${jobToRun.name}\"`, {error})\n const result = await job.onError(\n error instanceof Error ? error : new Error(String(error)),\n jobToRun.params,\n context,\n )\n\n if (result.action === 'dismiss') {\n await scheduleRecurrent()\n return\n }\n\n if (result.action === 'retry') {\n await handleRetry(getNextRunDate(result))\n }\n }\n\n async saveExecution(options: {\n startedAt: Date\n status: 'stale' | 'error' | 'success'\n errorMessage?: string\n result?: Blackbox\n job: JobDefinition\n jobToRun: JobToRun\n }) {\n const {startedAt, status, errorMessage, result, job, jobToRun} = options\n const endedAt = new Date()\n\n if (job.saveExecutionsFor !== 0) {\n const oneWeek = 1000 * 60 * 60 * 24 * 7\n const saveExecutionsFor = job.saveExecutionsFor || oneWeek\n await this.jobsHistoryRepo.saveExecution({\n jobId: jobToRun.jobId,\n executionId: jobToRun.executionId,\n jobName: jobToRun.name,\n type: jobToRun.type,\n priority: jobToRun.priority,\n tries: jobToRun.tries,\n uniqueIdentifier: jobToRun.uniqueIdentifier,\n startedAt,\n endedAt,\n duration: endedAt.getTime() - startedAt.getTime(),\n expiresAt: new Date(Date.now() + saveExecutionsFor),\n status,\n errorMessage,\n params: jobToRun.params,\n result,\n })\n }\n }\n\n async afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext) {\n if (job.type === 'recurrent') {\n context.logger.debug(`Scheduling next run for recurrent job \"${jobToRun.name}\"`)\n await this.jobsRepo.scheduleNextRun({\n jobId: jobToRun.jobId,\n nextRunAt: getNextRunDate(job),\n addTries: false,\n priority: job.priority,\n })\n }\n if (job.type === 'event') {\n context.logger.debug(`Removing event job after success \"${jobToRun.name}\"`)\n await this.jobsRepo.deleteEventJob(jobToRun.jobId)\n }\n }\n\n async executeJob(config: ExecuteJobConfig, jobToRun: JobToRun, respawnWorker: () => void) {\n const job = this.getJobDefinition(jobToRun, config.jobs)\n if (!job) return\n\n const effectiveMaxTries = this.getEffectiveMaxTries(job, config.maxTries)\n if (jobToRun.wasStale && jobToRun.tries >= effectiveMaxTries) {\n await this.handleMaxTriesReached(jobToRun, config.onMaxTriesReached)\n return\n }\n\n // If job has a custom lockTime different from the default, update the database lock\n const effectiveLockTime = this.getEffectiveLockTime(job, jobToRun)\n if (effectiveLockTime !== jobToRun.lockTime) {\n await this.jobsRepo.updateLockTime(jobToRun.jobId, effectiveLockTime)\n }\n\n const tracer = trace.getTracer('orionjs.dogs', '1.0')\n\n await tracer.startActiveSpan(`job.${jobToRun.name}.${jobToRun.executionId}`, async span => {\n try {\n const startedAt = new Date()\n\n const onStale = async () => {\n if (job.onStale) {\n context.logger.info(`Job \"${jobToRun.name}\" is stale`)\n job.onStale(jobToRun.params, context)\n } else {\n context.logger.error(`Job \"${jobToRun.name}\" is stale`)\n }\n\n await this.jobsRepo.setJobRecordPriority(jobToRun.jobId, 0)\n\n void respawnWorker()\n\n void this.saveExecution({\n startedAt,\n status: 'stale',\n result: null,\n errorMessage: null,\n job,\n jobToRun,\n }).catch(error => {\n context.logger.error('Error saving stale execution history', {error})\n })\n }\n\n const context = this.getContext(job, jobToRun, onStale)\n\n const extraContext = {\n controllerType: 'job' as const,\n jobName: jobToRun.name,\n params: jobToRun.params,\n }\n\n await runWithOrionAsyncContext(extraContext, async () => {\n try {\n // Inject async context update\n updateOrionAsyncContext({\n jobName: jobToRun.name,\n params: jobToRun.params,\n })\n const result = await job.resolve(jobToRun.params, context)\n context.clearStaleTimeout()\n\n void this.saveExecution({\n startedAt,\n status: 'success',\n result: result || null,\n errorMessage: null,\n job,\n jobToRun,\n }).catch(error => {\n context.logger.error('Error saving successful execution history', {error})\n })\n\n await this.afterExecutionSuccess(job, jobToRun, context)\n } catch (error) {\n context.clearStaleTimeout()\n void this.saveExecution({\n startedAt,\n status: 'error',\n result: null,\n errorMessage: (error as Error).message,\n job,\n jobToRun,\n }).catch(saveError => {\n context.logger.error('Error saving failed execution history', {error: saveError})\n })\n\n await this.onError(error, job, jobToRun, context, config)\n }\n })\n } catch (error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: (error as Error).message,\n })\n throw error\n } finally {\n span.end()\n }\n })\n }\n}\n","import {Collection, MongoCollection, Repository, MongoDB} from '@orion-js/mongodb'\nimport {omit} from 'rambdax'\nimport {HistoryRecord, HistoryRecordSchema} from '../types/HistoryRecord'\n\n@Repository()\nexport class JobsHistoryRepo {\n @MongoCollection({\n name: 'orionjs.jobs_dogs_history',\n idGeneration: 'uuid',\n schema: HistoryRecordSchema,\n indexes: [\n {\n keys: {\n jobName: 1,\n startedAt: 1,\n },\n },\n {\n keys: {\n executionId: 1,\n },\n },\n {\n keys: {\n expiresAt: 1,\n },\n options: {\n expireAfterSeconds: 0,\n },\n },\n ],\n })\n history: Collection<HistoryRecord>\n\n async saveExecution(record: MongoDB.WithoutId<HistoryRecord>) {\n await this.history.upsert(\n {executionId: record.executionId},\n {\n $setOnInsert: {\n status: record.status,\n },\n $set: {\n ...omit(['status'], record),\n },\n },\n )\n }\n\n async getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]> {\n const cursor = this.history.find({jobName}).sort({startedAt: -1})\n\n if (skip) {\n cursor.skip(skip)\n }\n\n if (limit) {\n cursor.limit(limit)\n }\n\n return await cursor.toArray()\n }\n}\n","function _isInteger(n){\n return n << 0 === n\n}\n\nexport const isInteger = Number.isInteger || _isInteger\n\n/**\n * Check if `index` is integer even if it is a string.\n */\nexport const isIndexInteger = index => Number.isInteger(Number(index))\n","import { isInteger } from './isInteger.js'\n\nexport function createPath(path, delimiter = '.'){\n return typeof path === 'string' ?\n path.split(delimiter).map(x => isInteger(x) ? Number(x) : x) :\n path\n}\n","export function compare(a, b){\n return String(a) === String(b)\n}\n","import { compare } from './compare.js'\n\nexport function includes(a, list){\n let index = -1\n const { length } = list\n\n while (++index < length)\n if (compare(list[ index ], a))\n return true\n\n return false\n}\n","import { createPath } from './_internals/createPath.js'\nimport { includes } from './_internals/includes.js'\n\nexport function omit(propsToOmit, obj){\n if (arguments.length === 1) return _obj => omit(propsToOmit, _obj)\n\n if (obj === null || obj === undefined)\n return undefined\n\n const propsToOmitValue = createPath(propsToOmit, ',')\n const willReturn = {}\n\n for (const key in obj)\n if (!includes(key, propsToOmitValue))\n willReturn[ key ] = obj[ key ]\n\n return willReturn\n}\n","import {InferSchemaType, schemaWithName} from '@orion-js/schema'\n\nexport const HistoryRecordSchema = schemaWithName('HistoryRecord', {\n _id: {type: 'string'},\n jobId: {type: 'string'},\n executionId: {type: 'string'},\n jobName: {type: 'string'},\n type: {type: 'string'},\n priority: {type: 'number'},\n tries: {type: 'number'},\n uniqueIdentifier: {type: 'string', optional: true},\n startedAt: {type: 'date'},\n endedAt: {type: 'date'},\n duration: {type: 'number'},\n expiresAt: {type: 'date', optional: true},\n status: {type: 'string', enum: ['success', 'error', 'stale']},\n errorMessage: {type: 'string', optional: true},\n params: {type: 'blackbox', optional: true},\n result: {type: 'any', optional: true},\n})\n\nexport type HistoryRecord = InferSchemaType<typeof HistoryRecordSchema>\n","import {getInstance, Service} from '@orion-js/services'\nimport {createEventJob, defineJob} from '../defineJob'\nimport type {CreateEventJobOptions, JobDefinition, RecurrentJobDefinition} from '../types'\n\n// Define metadata storage using WeakMaps\nconst serviceMetadata = new WeakMap<any, {_serviceType: string}>()\nconst jobsMetadata = new Map<any, Record<string, any>>()\nconst jobEntriesByClass = new Map<Function, Record<string, (instance: any) => any>>()\nlet pendingJobEntries: Record<string, (instance: any) => any> = {}\n\nexport function Jobs() {\n return (target: any, context: ClassDecoratorContext<any>) => {\n Service()(target, context)\n serviceMetadata.set(target, {_serviceType: 'jobs'})\n\n if (Object.keys(pendingJobEntries).length > 0) {\n jobEntriesByClass.set(target, pendingJobEntries)\n pendingJobEntries = {}\n }\n }\n}\n\nexport function RecurrentJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function RecurrentJob(\n options: Omit<RecurrentJobDefinition, 'resolve' | 'type'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function RecurrentJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingJobEntries[propertyKey] = (instance: any) =>\n defineJob({\n ...options,\n type: 'recurrent',\n resolve: instance[propertyKey].bind(instance),\n })\n }\n\n if (context.kind === 'field') {\n pendingJobEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nexport function EventJob(): (\n method: any,\n context: ClassFieldDecoratorContext | ClassMethodDecoratorContext,\n) => any\nexport function EventJob(\n options: Omit<CreateEventJobOptions<any>, 'resolve'>,\n): (method: any, context: ClassMethodDecoratorContext) => any\nexport function EventJob(options = {}) {\n return (method: any, context: ClassFieldDecoratorContext | ClassMethodDecoratorContext) => {\n const propertyKey = String(context.name)\n\n if (context.kind === 'method') {\n pendingJobEntries[propertyKey] = (instance: any) =>\n createEventJob({\n ...options,\n resolve: instance[propertyKey].bind(instance),\n })\n }\n\n if (context.kind === 'field') {\n pendingJobEntries[propertyKey] = (instance: any) => instance[propertyKey]\n }\n\n return method\n }\n}\n\nfunction initializeJobsIfNeeded(instance: any) {\n if (jobsMetadata.has(instance)) return\n const entries = jobEntriesByClass.get(instance.constructor) || {}\n const jobs: Record<string, any> = {}\n for (const [key, setup] of Object.entries(entries)) {\n jobs[key] = setup(instance)\n }\n jobsMetadata.set(instance, jobs)\n}\n\nexport function getServiceJobs(target: any): {\n [key: string]: JobDefinition\n} {\n const instance = getInstance(target)\n\n if (!serviceMetadata.has(instance.constructor)) {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n const instanceMetadata = serviceMetadata.get(instance.constructor)\n if (instanceMetadata._serviceType !== 'jobs') {\n throw new Error('You must pass a class decorated with @Jobs to getServiceJobs')\n }\n\n initializeJobsIfNeeded(instance)\n\n const jobsMap = jobsMetadata.get(instance) || {}\n\n return jobsMap\n}\n","import {\n CreateEventJobOptions,\n CreateJobOptions,\n CreateRecurrentJobOptions,\n EventJobDefinition,\n JobDefinition,\n RecurrentJobDefinition,\n} from '../types/JobsDefinition'\nimport {scheduleJob, ScheduleJobsResult, scheduleJobs} from '..'\nimport {ScheduleJobOptionsWithoutName} from '../types/Events'\nimport {cleanAndValidate, SchemaInAnyOrionForm} from '@orion-js/schema'\nimport parse from 'parse-duration'\n\nexport function createEventJob<TParamsSchema extends SchemaInAnyOrionForm>(\n options: CreateEventJobOptions<TParamsSchema>,\n): EventJobDefinition<TParamsSchema> {\n const jobDefinition: EventJobDefinition<TParamsSchema> = {\n ...options,\n type: 'event',\n schedule: null,\n scheduleJobs: null,\n }\n\n jobDefinition.schedule = async (scheduleOptions: ScheduleJobOptionsWithoutName<TParamsSchema>) => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return await scheduleJob({\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n })\n }\n\n jobDefinition.scheduleJobs = async (\n jobs: Array<ScheduleJobOptionsWithoutName<TParamsSchema>>,\n ): Promise<ScheduleJobsResult> => {\n if (!jobDefinition.jobName) {\n throw new Error('This job has not been registered in the workers')\n }\n\n // Process all job parameters if schema validation is needed\n const processedJobs = await Promise.all(\n jobs.map(async scheduleOptions => {\n const params = jobDefinition.params\n ? await cleanAndValidate(jobDefinition.params, scheduleOptions.params)\n : scheduleOptions.params\n\n return {\n ...scheduleOptions,\n name: jobDefinition.jobName,\n params,\n }\n }),\n )\n\n return await scheduleJobs(processedJobs)\n }\n\n return jobDefinition\n}\n\nexport function createRecurrentJob(options: CreateRecurrentJobOptions): RecurrentJobDefinition {\n const jobDefinition: RecurrentJobDefinition = {\n ...options,\n priority: options.priority ?? 100,\n type: 'recurrent',\n runEvery: typeof options.runEvery === 'string' ? parse(options.runEvery) : options.runEvery,\n }\n\n return jobDefinition\n}\n\n/**\n * @deprecated Use `createEventJob` or `createRecurrentJob` instead.\n */\nexport const defineJob = (\n options: CreateJobOptions & {type: 'event' | 'recurrent'},\n): JobDefinition => {\n return options.type === 'event'\n ? createEventJob(options as any)\n : createRecurrentJob(options as any)\n}\n"],"mappings":"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","names":["getInstance","logger","_init","logger","logger","Inject","Service","logger","Inject","Service","MongoCollection","Repository","schemaWithName","_init","Repository","MongoCollection","_jobsRepo_dec","_init","Service","Inject","_a","logger","_jobsRepo_dec","_init","Service","Inject","logger","Service","Service","getInstance"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-js/dogs",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -15,36 +15,36 @@
|
|
|
15
15
|
],
|
|
16
16
|
"author": "nicolaslopezj",
|
|
17
17
|
"license": "MIT",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"test": "bun test",
|
|
20
|
+
"prepare": "bun run build",
|
|
21
|
+
"clean": "rm -rf ./dist",
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch"
|
|
24
|
+
},
|
|
18
25
|
"dependencies": {
|
|
19
26
|
"@opentelemetry/api": "^1.9.0",
|
|
27
|
+
"@orion-js/helpers": "4.3.0",
|
|
28
|
+
"@orion-js/schema": "4.3.0",
|
|
29
|
+
"@orion-js/services": "4.3.0",
|
|
30
|
+
"@orion-js/typed-model": "4.3.0",
|
|
20
31
|
"dataloader": "2.2.2",
|
|
21
32
|
"dot-object": "^2.1.5",
|
|
22
|
-
"parse-duration": "^2.1.3"
|
|
23
|
-
"@orion-js/helpers": "4.2.0",
|
|
24
|
-
"@orion-js/schema": "4.2.1",
|
|
25
|
-
"@orion-js/typed-model": "4.2.1",
|
|
26
|
-
"@orion-js/services": "4.2.0"
|
|
33
|
+
"parse-duration": "^2.1.3"
|
|
27
34
|
},
|
|
28
35
|
"peerDependencies": {
|
|
29
|
-
"@orion-js/logger": "4.
|
|
30
|
-
"@orion-js/mongodb": "4.
|
|
36
|
+
"@orion-js/logger": "4.3.0",
|
|
37
|
+
"@orion-js/mongodb": "4.3.0"
|
|
31
38
|
},
|
|
32
39
|
"devDependencies": {
|
|
40
|
+
"@orion-js/logger": "4.3.0",
|
|
41
|
+
"@orion-js/mongodb": "4.3.0",
|
|
42
|
+
"mongodb-memory-server": "^10.1.4",
|
|
33
43
|
"tsup": "^8.0.1",
|
|
34
|
-
"typescript": "^5.4.5"
|
|
35
|
-
"vitest": "^3.0.8",
|
|
36
|
-
"@orion-js/mongodb": "4.2.10",
|
|
37
|
-
"@orion-js/logger": "4.2.0"
|
|
44
|
+
"typescript": "^5.4.5"
|
|
38
45
|
},
|
|
39
46
|
"publishConfig": {
|
|
40
47
|
"access": "public"
|
|
41
48
|
},
|
|
42
|
-
"gitHead": "2d14bc085d49a33b2a5566bec1caf60c7d0f897e"
|
|
43
|
-
|
|
44
|
-
"test": "vitest run",
|
|
45
|
-
"clean": "rm -rf ./dist",
|
|
46
|
-
"build": "tsup",
|
|
47
|
-
"upgrade-interactive": "pnpm upgrade --interactive",
|
|
48
|
-
"dev": "tsup --watch"
|
|
49
|
-
}
|
|
50
|
-
}
|
|
49
|
+
"gitHead": "2d14bc085d49a33b2a5566bec1caf60c7d0f897e"
|
|
50
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022 Orionjs Team
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|