@orion-js/dogs 3.12.0 → 3.13.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/LICENSE +21 -0
- package/lib/defineJob/index.d.ts +2 -0
- package/lib/defineJob/index.js +12 -0
- package/lib/events.test.d.ts +1 -0
- package/lib/events.test.js +133 -0
- package/lib/history.test.d.ts +1 -0
- package/lib/history.test.js +140 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.js +40 -0
- package/lib/recurrent.test.d.ts +1 -0
- package/lib/recurrent.test.js +47 -0
- package/lib/repos/JobsHistoryRepo.d.ts +7 -0
- package/lib/repos/JobsHistoryRepo.js +67 -0
- package/lib/repos/JobsRepo.d.ts +19 -0
- package/lib/repos/JobsRepo.js +158 -0
- package/lib/service/index.d.ts +10 -0
- package/lib/service/index.js +50 -0
- package/lib/service/index.test.d.ts +1 -0
- package/lib/service/index.test.js +51 -0
- package/lib/services/EventsService.d.ts +5 -0
- package/lib/services/EventsService.js +36 -0
- package/lib/services/Executor.d.ts +20 -0
- package/lib/services/Executor.js +195 -0
- package/lib/services/WorkerService.d.ts +16 -0
- package/lib/services/WorkerService.js +142 -0
- package/lib/services/WorkerService.test.d.ts +1 -0
- package/lib/services/WorkerService.test.js +10 -0
- package/lib/services/getNextRunDate.d.ts +9 -0
- package/lib/services/getNextRunDate.js +19 -0
- package/lib/stale.test.d.ts +1 -0
- package/lib/stale.test.js +108 -0
- package/lib/tests/setup.d.ts +1 -0
- package/lib/tests/setup.js +19 -0
- package/lib/types/Events.d.ts +21 -0
- package/lib/types/Events.js +2 -0
- package/lib/types/HistoryRecord.d.ts +21 -0
- package/lib/types/HistoryRecord.js +83 -0
- package/lib/types/JobRecord.d.ts +13 -0
- package/lib/types/JobRecord.js +59 -0
- package/lib/types/JobsDefinition.d.ts +61 -0
- package/lib/types/JobsDefinition.js +2 -0
- package/lib/types/StartConfig.d.ts +28 -0
- package/lib/types/StartConfig.js +2 -0
- package/lib/types/Worker.d.ts +38 -0
- package/lib/types/Worker.js +2 -0
- package/lib/types/index.d.ts +6 -0
- package/lib/types/index.js +22 -0
- package/package.json +22 -23
- package/dist/index.cjs +0 -114048
- package/dist/index.d.ts +0 -215
- package/dist/index.js +0 -114022
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const helpers_1 = require("@orion-js/helpers");
|
|
4
|
+
const logger_1 = require("@orion-js/logger");
|
|
5
|
+
const _1 = require(".");
|
|
6
|
+
(0, logger_1.setLogLevel)('none');
|
|
7
|
+
describe('Stale Jobs Management', () => {
|
|
8
|
+
it('Should spawn a new worker when a job is stale and kill the stale worker after it ends', async () => {
|
|
9
|
+
const jobName1 = 'job1' + (0, helpers_1.generateId)();
|
|
10
|
+
const job1 = (0, _1.defineJob)({
|
|
11
|
+
type: 'event',
|
|
12
|
+
async resolve(_, context) {
|
|
13
|
+
if (context.tries === 1) {
|
|
14
|
+
await (0, helpers_1.sleep)(100);
|
|
15
|
+
}
|
|
16
|
+
return { status: 'finished' };
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const jobName2 = 'job2' + (0, helpers_1.generateId)();
|
|
20
|
+
const job2 = (0, _1.defineJob)({
|
|
21
|
+
type: 'event',
|
|
22
|
+
async resolve() {
|
|
23
|
+
return { status: 'finished' };
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const instance = (0, _1.startWorkers)({
|
|
27
|
+
jobs: { [jobName1]: job1, [jobName2]: job2 },
|
|
28
|
+
workersCount: 1,
|
|
29
|
+
pollInterval: 5,
|
|
30
|
+
cooldownPeriod: 5,
|
|
31
|
+
lockTime: 10
|
|
32
|
+
});
|
|
33
|
+
await (0, _1.scheduleJob)({ name: jobName1 });
|
|
34
|
+
await (0, _1.scheduleJob)({ name: jobName2 });
|
|
35
|
+
await (0, helpers_1.sleep)(150);
|
|
36
|
+
await instance.stop();
|
|
37
|
+
const executions1 = await _1.jobsHistoryRepo.getExecutions(jobName1);
|
|
38
|
+
expect(executions1.length).toBe(2);
|
|
39
|
+
const executions2 = await _1.jobsHistoryRepo.getExecutions(jobName2);
|
|
40
|
+
expect(executions2.length).toBe(1);
|
|
41
|
+
expect(instance.workers.length).toBe(2);
|
|
42
|
+
});
|
|
43
|
+
it('Should run stale jobs in the lowest priority', async () => {
|
|
44
|
+
const executions = [];
|
|
45
|
+
const priotities = [];
|
|
46
|
+
const jobName1 = 'job1' + (0, helpers_1.generateId)();
|
|
47
|
+
const job1 = (0, _1.defineJob)({
|
|
48
|
+
type: 'event',
|
|
49
|
+
async resolve(_, context) {
|
|
50
|
+
executions.push('stale');
|
|
51
|
+
priotities.push(context.record.priority);
|
|
52
|
+
if (context.tries === 1) {
|
|
53
|
+
await (0, helpers_1.sleep)(100);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const jobName2 = 'job2' + (0, helpers_1.generateId)();
|
|
58
|
+
const job2 = (0, _1.defineJob)({
|
|
59
|
+
type: 'event',
|
|
60
|
+
async resolve() {
|
|
61
|
+
executions.push('success');
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const instance = (0, _1.startWorkers)({
|
|
65
|
+
jobs: { [jobName1]: job1, [jobName2]: job2 },
|
|
66
|
+
workersCount: 1,
|
|
67
|
+
pollInterval: 5,
|
|
68
|
+
cooldownPeriod: 5,
|
|
69
|
+
lockTime: 10
|
|
70
|
+
});
|
|
71
|
+
await (0, _1.scheduleJob)({ name: jobName1 });
|
|
72
|
+
await (0, _1.scheduleJob)({ name: jobName2 });
|
|
73
|
+
await (0, helpers_1.sleep)(150);
|
|
74
|
+
await instance.stop();
|
|
75
|
+
expect(priotities).toEqual([100, 0]);
|
|
76
|
+
expect(executions).toEqual(['stale', 'success', 'stale']);
|
|
77
|
+
});
|
|
78
|
+
it('Should revert to original priority when execution was stale on recurrent jobs', async () => {
|
|
79
|
+
const priotities = [];
|
|
80
|
+
let didStale = false;
|
|
81
|
+
const jobName = 'job' + (0, helpers_1.generateId)();
|
|
82
|
+
const job = (0, _1.defineJob)({
|
|
83
|
+
type: 'recurrent',
|
|
84
|
+
runEvery: 5,
|
|
85
|
+
async resolve(_, context) {
|
|
86
|
+
priotities.push(context.record.priority);
|
|
87
|
+
if (!didStale) {
|
|
88
|
+
didStale = true;
|
|
89
|
+
await (0, helpers_1.sleep)(100);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
const instance = (0, _1.startWorkers)({
|
|
94
|
+
jobs: { [jobName]: job },
|
|
95
|
+
workersCount: 1,
|
|
96
|
+
pollInterval: 5,
|
|
97
|
+
cooldownPeriod: 5,
|
|
98
|
+
lockTime: 10
|
|
99
|
+
});
|
|
100
|
+
await (0, helpers_1.sleep)(150);
|
|
101
|
+
await instance.stop();
|
|
102
|
+
const [first, second, ...others] = priotities;
|
|
103
|
+
expect(first).toBe(100);
|
|
104
|
+
expect(second).toBe(0);
|
|
105
|
+
expect(others.length).toBeGreaterThan(0);
|
|
106
|
+
expect(others).toEqual(Array(others.length).fill(100));
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const mongodb_1 = require("@orion-js/mongodb");
|
|
4
|
+
const url = `${global.__MONGO_URI__}jest`;
|
|
5
|
+
process.env.MONGO_URL = url;
|
|
6
|
+
beforeAll(async () => {
|
|
7
|
+
const connection = (0, mongodb_1.getMongoConnection)({ name: 'main' });
|
|
8
|
+
await connection.connectionPromise;
|
|
9
|
+
});
|
|
10
|
+
afterAll(async () => {
|
|
11
|
+
/**
|
|
12
|
+
* We need to wait on indexes promises to be resolved to close all the handlers
|
|
13
|
+
*/
|
|
14
|
+
await Promise.all(mongodb_1.createIndexesPromises);
|
|
15
|
+
for (const connectionName in mongodb_1.connections) {
|
|
16
|
+
const connection = mongodb_1.connections[connectionName];
|
|
17
|
+
await connection.client.close();
|
|
18
|
+
}
|
|
19
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PlainObject } from './HistoryRecord';
|
|
2
|
+
export interface ScheduleJobOptionsBase {
|
|
3
|
+
name: string;
|
|
4
|
+
params?: PlainObject;
|
|
5
|
+
priority?: number;
|
|
6
|
+
uniqueIdentifier?: string;
|
|
7
|
+
}
|
|
8
|
+
export type ScheduleJobOptionsRunIn = ScheduleJobOptionsBase & {
|
|
9
|
+
runIn: number;
|
|
10
|
+
};
|
|
11
|
+
export type ScheduleJobOptionsRunAt = ScheduleJobOptionsBase & {
|
|
12
|
+
runAt: Date;
|
|
13
|
+
};
|
|
14
|
+
export type ScheduleJobOptions = ScheduleJobOptionsRunIn | ScheduleJobOptionsRunAt | ScheduleJobOptionsBase;
|
|
15
|
+
export interface ScheduleJobRecordOptions {
|
|
16
|
+
name: string;
|
|
17
|
+
params: PlainObject;
|
|
18
|
+
nextRunAt: Date;
|
|
19
|
+
priority: number;
|
|
20
|
+
uniqueIdentifier?: string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type PlainObject = {
|
|
2
|
+
[name: string]: any;
|
|
3
|
+
};
|
|
4
|
+
export declare class HistoryRecord {
|
|
5
|
+
_id: string;
|
|
6
|
+
jobId: string;
|
|
7
|
+
executionId: string;
|
|
8
|
+
jobName: string;
|
|
9
|
+
type: 'recurrent' | 'event';
|
|
10
|
+
priority: number;
|
|
11
|
+
tries: number;
|
|
12
|
+
uniqueIdentifier?: string;
|
|
13
|
+
startedAt: Date;
|
|
14
|
+
endedAt: Date;
|
|
15
|
+
duration: number;
|
|
16
|
+
expiresAt?: Date;
|
|
17
|
+
status: 'success' | 'error' | 'stale';
|
|
18
|
+
errorMessage?: string;
|
|
19
|
+
params?: PlainObject;
|
|
20
|
+
result?: PlainObject;
|
|
21
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.HistoryRecord = void 0;
|
|
13
|
+
const typed_model_1 = require("@orion-js/typed-model");
|
|
14
|
+
let HistoryRecord = class HistoryRecord {
|
|
15
|
+
};
|
|
16
|
+
exports.HistoryRecord = HistoryRecord;
|
|
17
|
+
__decorate([
|
|
18
|
+
(0, typed_model_1.Prop)(),
|
|
19
|
+
__metadata("design:type", String)
|
|
20
|
+
], HistoryRecord.prototype, "_id", void 0);
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, typed_model_1.Prop)(),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], HistoryRecord.prototype, "jobId", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, typed_model_1.Prop)(),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], HistoryRecord.prototype, "executionId", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, typed_model_1.Prop)(),
|
|
31
|
+
__metadata("design:type", String)
|
|
32
|
+
], HistoryRecord.prototype, "jobName", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, typed_model_1.Prop)(),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], HistoryRecord.prototype, "type", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, typed_model_1.Prop)(),
|
|
39
|
+
__metadata("design:type", Number)
|
|
40
|
+
], HistoryRecord.prototype, "priority", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, typed_model_1.Prop)(),
|
|
43
|
+
__metadata("design:type", Number)
|
|
44
|
+
], HistoryRecord.prototype, "tries", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, typed_model_1.Prop)({ optional: true }),
|
|
47
|
+
__metadata("design:type", String)
|
|
48
|
+
], HistoryRecord.prototype, "uniqueIdentifier", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
(0, typed_model_1.Prop)(),
|
|
51
|
+
__metadata("design:type", Date)
|
|
52
|
+
], HistoryRecord.prototype, "startedAt", void 0);
|
|
53
|
+
__decorate([
|
|
54
|
+
(0, typed_model_1.Prop)(),
|
|
55
|
+
__metadata("design:type", Date)
|
|
56
|
+
], HistoryRecord.prototype, "endedAt", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
(0, typed_model_1.Prop)(),
|
|
59
|
+
__metadata("design:type", Number)
|
|
60
|
+
], HistoryRecord.prototype, "duration", void 0);
|
|
61
|
+
__decorate([
|
|
62
|
+
(0, typed_model_1.Prop)({ optional: true }),
|
|
63
|
+
__metadata("design:type", Date)
|
|
64
|
+
], HistoryRecord.prototype, "expiresAt", void 0);
|
|
65
|
+
__decorate([
|
|
66
|
+
(0, typed_model_1.Prop)(),
|
|
67
|
+
__metadata("design:type", String)
|
|
68
|
+
], HistoryRecord.prototype, "status", void 0);
|
|
69
|
+
__decorate([
|
|
70
|
+
(0, typed_model_1.Prop)({ optional: true }),
|
|
71
|
+
__metadata("design:type", String)
|
|
72
|
+
], HistoryRecord.prototype, "errorMessage", void 0);
|
|
73
|
+
__decorate([
|
|
74
|
+
(0, typed_model_1.Prop)({ type: 'blackbox', optional: true }),
|
|
75
|
+
__metadata("design:type", Object)
|
|
76
|
+
], HistoryRecord.prototype, "params", void 0);
|
|
77
|
+
__decorate([
|
|
78
|
+
(0, typed_model_1.Prop)({ type: 'blackbox', optional: true }),
|
|
79
|
+
__metadata("design:type", Object)
|
|
80
|
+
], HistoryRecord.prototype, "result", void 0);
|
|
81
|
+
exports.HistoryRecord = HistoryRecord = __decorate([
|
|
82
|
+
(0, typed_model_1.TypedModel)()
|
|
83
|
+
], HistoryRecord);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PlainObject } from './HistoryRecord';
|
|
2
|
+
export declare class JobRecord {
|
|
3
|
+
_id: string;
|
|
4
|
+
jobName: string;
|
|
5
|
+
type: 'recurrent' | 'event';
|
|
6
|
+
priority: number;
|
|
7
|
+
uniqueIdentifier?: string;
|
|
8
|
+
nextRunAt: Date;
|
|
9
|
+
lastRunAt?: Date;
|
|
10
|
+
lockedUntil?: Date;
|
|
11
|
+
tries?: number;
|
|
12
|
+
params?: PlainObject;
|
|
13
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.JobRecord = void 0;
|
|
13
|
+
const typed_model_1 = require("@orion-js/typed-model");
|
|
14
|
+
let JobRecord = class JobRecord {
|
|
15
|
+
};
|
|
16
|
+
exports.JobRecord = JobRecord;
|
|
17
|
+
__decorate([
|
|
18
|
+
(0, typed_model_1.Prop)(),
|
|
19
|
+
__metadata("design:type", String)
|
|
20
|
+
], JobRecord.prototype, "_id", void 0);
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, typed_model_1.Prop)(),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], JobRecord.prototype, "jobName", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, typed_model_1.Prop)(),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], JobRecord.prototype, "type", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, typed_model_1.Prop)(),
|
|
31
|
+
__metadata("design:type", Number)
|
|
32
|
+
], JobRecord.prototype, "priority", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, typed_model_1.Prop)({ optional: true }),
|
|
35
|
+
__metadata("design:type", String)
|
|
36
|
+
], JobRecord.prototype, "uniqueIdentifier", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, typed_model_1.Prop)(),
|
|
39
|
+
__metadata("design:type", Date)
|
|
40
|
+
], JobRecord.prototype, "nextRunAt", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, typed_model_1.Prop)({ optional: true }),
|
|
43
|
+
__metadata("design:type", Date)
|
|
44
|
+
], JobRecord.prototype, "lastRunAt", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, typed_model_1.Prop)({ optional: true }),
|
|
47
|
+
__metadata("design:type", Date)
|
|
48
|
+
], JobRecord.prototype, "lockedUntil", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
(0, typed_model_1.Prop)({ optional: true }),
|
|
51
|
+
__metadata("design:type", Number)
|
|
52
|
+
], JobRecord.prototype, "tries", void 0);
|
|
53
|
+
__decorate([
|
|
54
|
+
(0, typed_model_1.Prop)({ type: 'blackbox', optional: true }),
|
|
55
|
+
__metadata("design:type", Object)
|
|
56
|
+
], JobRecord.prototype, "params", void 0);
|
|
57
|
+
exports.JobRecord = JobRecord = __decorate([
|
|
58
|
+
(0, typed_model_1.TypedModel)()
|
|
59
|
+
], JobRecord);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { PlainObject } from './HistoryRecord';
|
|
2
|
+
import { ExecutionContext } from './Worker';
|
|
3
|
+
export interface JobRetryResultBase {
|
|
4
|
+
action: 'retry' | 'dismiss';
|
|
5
|
+
}
|
|
6
|
+
export type JobRetryResultRunIn = JobRetryResultBase & {
|
|
7
|
+
runIn: number;
|
|
8
|
+
};
|
|
9
|
+
export type JobRetryResultRunAt = JobRetryResultBase & {
|
|
10
|
+
runAt: Date;
|
|
11
|
+
};
|
|
12
|
+
export type JobRetryResult = JobRetryResultRunIn | JobRetryResultRunAt | JobRetryResultBase;
|
|
13
|
+
export interface BaseJobDefinition {
|
|
14
|
+
/**
|
|
15
|
+
* The function to execute when the job is executed.
|
|
16
|
+
*/
|
|
17
|
+
resolve: (params: PlainObject, context: ExecutionContext) => Promise<PlainObject | void>;
|
|
18
|
+
/**
|
|
19
|
+
* Called if the job fails.
|
|
20
|
+
*/
|
|
21
|
+
onError?: (error: Error, params: PlainObject, context: ExecutionContext) => Promise<JobRetryResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Called if the job locktime is expired. The job will be executed again.
|
|
24
|
+
*/
|
|
25
|
+
onStale?: (params: PlainObject, context: ExecutionContext) => Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Save the executions of the job time in milliseconds. Default is 1 week. Set to 0 to disable.
|
|
28
|
+
*/
|
|
29
|
+
saveExecutionsFor?: number;
|
|
30
|
+
}
|
|
31
|
+
export interface RecurrentJobDefinition extends BaseJobDefinition {
|
|
32
|
+
/**
|
|
33
|
+
* Type of the job.
|
|
34
|
+
*/
|
|
35
|
+
type: 'recurrent';
|
|
36
|
+
/**
|
|
37
|
+
* A function executed after each execution that returns the date of the next run.
|
|
38
|
+
*/
|
|
39
|
+
getNextRun?: () => Date;
|
|
40
|
+
/**
|
|
41
|
+
* Run every x milliseconds. This will be ignored if getNextRun is defined.
|
|
42
|
+
*/
|
|
43
|
+
runEvery?: number;
|
|
44
|
+
/**
|
|
45
|
+
* The priority of the job. Higher is more priority. Default is 100.
|
|
46
|
+
*/
|
|
47
|
+
priority?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface EventJobDefinition extends BaseJobDefinition {
|
|
50
|
+
/**
|
|
51
|
+
* Type of the job.
|
|
52
|
+
*/
|
|
53
|
+
type: 'event';
|
|
54
|
+
}
|
|
55
|
+
export type JobDefinition = RecurrentJobDefinition | EventJobDefinition;
|
|
56
|
+
export type JobDefinitionWithName = JobDefinition & {
|
|
57
|
+
name: string;
|
|
58
|
+
};
|
|
59
|
+
export interface JobsDefinition {
|
|
60
|
+
[jobName: string]: JobDefinition;
|
|
61
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { JobsDefinition } from './JobsDefinition';
|
|
2
|
+
export type LogLevels = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
3
|
+
export interface StartWorkersConfig {
|
|
4
|
+
/**
|
|
5
|
+
* Object map of the jobs that this workers will execute
|
|
6
|
+
*/
|
|
7
|
+
jobs: JobsDefinition;
|
|
8
|
+
/**
|
|
9
|
+
* Time in milliseconds to wait between each look without results for a job
|
|
10
|
+
* to run at the database. Default is 3000.
|
|
11
|
+
*/
|
|
12
|
+
pollInterval: number;
|
|
13
|
+
/**
|
|
14
|
+
* Time in milliseconds to wait too look for a job after a job execution. Default is 100.
|
|
15
|
+
*/
|
|
16
|
+
cooldownPeriod: number;
|
|
17
|
+
/**
|
|
18
|
+
* Number of workers to start. Default is 1.
|
|
19
|
+
*/
|
|
20
|
+
workersCount: number;
|
|
21
|
+
/**
|
|
22
|
+
* Time in milliseconds to lock a job for execution. Default is 30000 (30 seconds).
|
|
23
|
+
* If a job is locked for longer than this time, it will be considered as failed.
|
|
24
|
+
* This is to prevent a job from being executed multiple times at the same time.
|
|
25
|
+
* You can extend this time inside a job by calling extendLockTime from context.
|
|
26
|
+
*/
|
|
27
|
+
lockTime: number;
|
|
28
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { OrionLogger } from '@orion-js/logger';
|
|
2
|
+
import { PlainObject } from './HistoryRecord';
|
|
3
|
+
import { JobDefinition } from './JobsDefinition';
|
|
4
|
+
export interface JobToRun {
|
|
5
|
+
jobId: string;
|
|
6
|
+
executionId: string;
|
|
7
|
+
name: string;
|
|
8
|
+
type: 'event' | 'recurrent';
|
|
9
|
+
params: PlainObject;
|
|
10
|
+
tries: number;
|
|
11
|
+
lockTime: number;
|
|
12
|
+
priority: number;
|
|
13
|
+
uniqueIdentifier?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ExecutionContext {
|
|
16
|
+
record: JobToRun;
|
|
17
|
+
definition: JobDefinition;
|
|
18
|
+
tries: number;
|
|
19
|
+
logger: OrionLogger;
|
|
20
|
+
extendLockTime: (extraTime: number) => Promise<void>;
|
|
21
|
+
clearStaleTimeout: () => void;
|
|
22
|
+
}
|
|
23
|
+
export interface WorkerInstance {
|
|
24
|
+
running: boolean;
|
|
25
|
+
workerIndex: number;
|
|
26
|
+
stop: () => Promise<void>;
|
|
27
|
+
respawn: () => Promise<void>;
|
|
28
|
+
promise?: Promise<any>;
|
|
29
|
+
}
|
|
30
|
+
export interface WorkersInstance {
|
|
31
|
+
running: boolean;
|
|
32
|
+
workersCount: number;
|
|
33
|
+
workers: WorkerInstance[];
|
|
34
|
+
/**
|
|
35
|
+
* Stop all workers and wait for them to finish
|
|
36
|
+
*/
|
|
37
|
+
stop: () => Promise<void>;
|
|
38
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./Events"), exports);
|
|
18
|
+
__exportStar(require("./HistoryRecord"), exports);
|
|
19
|
+
__exportStar(require("./JobRecord"), exports);
|
|
20
|
+
__exportStar(require("./JobsDefinition"), exports);
|
|
21
|
+
__exportStar(require("./StartConfig"), exports);
|
|
22
|
+
__exportStar(require("./Worker"), exports);
|
package/package.json
CHANGED
|
@@ -1,45 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-js/dogs",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"module": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
"types": "./dist/index.d.ts",
|
|
10
|
-
"import": "./dist/index.js",
|
|
11
|
-
"require": "./dist/index.cjs"
|
|
12
|
-
},
|
|
3
|
+
"version": "3.13.1",
|
|
4
|
+
"main": "lib/index.js",
|
|
5
|
+
"types": "lib/index.d.ts",
|
|
13
6
|
"files": [
|
|
14
|
-
"
|
|
7
|
+
"/lib"
|
|
15
8
|
],
|
|
16
9
|
"author": "nicolaslopezj",
|
|
17
10
|
"license": "MIT",
|
|
18
11
|
"scripts": {
|
|
19
|
-
"test": "
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"prepare": "yarn run build",
|
|
14
|
+
"clean": "rm -rf ./lib",
|
|
15
|
+
"build": "yarn run clean && tsc",
|
|
16
|
+
"watch": "tsc -w",
|
|
17
|
+
"upgrade-interactive": "yarn upgrade-interactive"
|
|
23
18
|
},
|
|
24
19
|
"dependencies": {
|
|
25
20
|
"@opentelemetry/api": "^1.9.0",
|
|
26
|
-
"@orion-js/helpers": "^
|
|
27
|
-
"@orion-js/mongodb": "^
|
|
28
|
-
"@orion-js/services": "^
|
|
29
|
-
"@orion-js/typed-model": "^
|
|
21
|
+
"@orion-js/helpers": "^3.13.1",
|
|
22
|
+
"@orion-js/mongodb": "^3.13.1",
|
|
23
|
+
"@orion-js/services": "^3.13.1",
|
|
24
|
+
"@orion-js/typed-model": "^3.13.1"
|
|
30
25
|
},
|
|
31
26
|
"peerDependencies": {
|
|
32
27
|
"@orion-js/logger": "*"
|
|
33
28
|
},
|
|
34
29
|
"devDependencies": {
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
30
|
+
"@orion-js/logger": "^3.13.1",
|
|
31
|
+
"@shelf/jest-mongodb": "^4.3.2",
|
|
32
|
+
"@types/jest": "^29.5.12",
|
|
37
33
|
"@types/lodash": "4.14.176",
|
|
34
|
+
"@types/node": "16.11.7",
|
|
35
|
+
"jest": "29.7.0",
|
|
38
36
|
"reflect-metadata": "^0.1.13",
|
|
37
|
+
"ts-jest": "29.1.2",
|
|
39
38
|
"typescript": "^5.4.5"
|
|
40
39
|
},
|
|
41
40
|
"publishConfig": {
|
|
42
41
|
"access": "public"
|
|
43
42
|
},
|
|
44
|
-
"gitHead": "
|
|
45
|
-
}
|
|
43
|
+
"gitHead": "18ab5a9711863e6bd3d3c61e7bb8f9067afca82c"
|
|
44
|
+
}
|