@orion-js/dogs 3.1.0-alpha.1 → 3.1.0-alpha.13
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/lib/events.test.js +10 -13
- package/lib/history.test.js +11 -11
- package/lib/index.d.ts +6 -3
- package/lib/index.js +17 -3
- package/lib/recurrent.test.js +4 -4
- package/lib/repos/JobsHistoryRepo.d.ts +1 -1
- package/lib/repos/JobsRepo.d.ts +3 -1
- package/lib/repos/JobsRepo.js +13 -10
- package/lib/services/EventsService.js +2 -2
- package/lib/services/Executor.d.ts +1 -0
- package/lib/services/Executor.js +28 -20
- package/lib/services/WorkerService.js +12 -14
- package/lib/services/getNextRunDate.d.ts +4 -2
- package/lib/services/getNextRunDate.js +4 -1
- package/lib/types/Events.d.ts +1 -1
- package/lib/types/HistoryRecord.d.ts +1 -1
- package/lib/types/HistoryRecord.js +2 -2
- package/lib/types/JobRecord.d.ts +1 -1
- package/lib/types/JobRecord.js +2 -2
- package/lib/types/JobsDefinition.d.ts +1 -1
- package/lib/types/StartConfig.d.ts +0 -4
- package/lib/types/Worker.d.ts +3 -1
- package/lib/types/index.d.ts +6 -0
- package/lib/types/index.js +18 -0
- package/package.json +6 -2
- package/lib/log/index.d.ts +0 -5
- package/lib/log/index.js +0 -31
package/lib/events.test.js
CHANGED
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
require("reflect-metadata");
|
|
4
4
|
const helpers_1 = require("@orion-js/helpers");
|
|
5
5
|
const _1 = require(".");
|
|
6
|
+
const logger_1 = require("@orion-js/logger");
|
|
7
|
+
(0, logger_1.setLogLevel)('error');
|
|
6
8
|
describe('Event tests', () => {
|
|
7
9
|
it('Should run an event job', async () => {
|
|
8
10
|
let count = 0;
|
|
@@ -16,8 +18,7 @@ describe('Event tests', () => {
|
|
|
16
18
|
jobs: { job3 },
|
|
17
19
|
workersCount: 1,
|
|
18
20
|
pollInterval: 10,
|
|
19
|
-
cooldownPeriod: 10
|
|
20
|
-
logLevel: 'info'
|
|
21
|
+
cooldownPeriod: 10
|
|
21
22
|
});
|
|
22
23
|
expect(count).toBe(0);
|
|
23
24
|
await (0, _1.scheduleJob)({
|
|
@@ -55,8 +56,7 @@ describe('Event tests', () => {
|
|
|
55
56
|
jobs: { job4 },
|
|
56
57
|
workersCount: 1,
|
|
57
58
|
pollInterval: 10,
|
|
58
|
-
cooldownPeriod: 10
|
|
59
|
-
logLevel: 'info'
|
|
59
|
+
cooldownPeriod: 10
|
|
60
60
|
});
|
|
61
61
|
expect(passes).toBe(false);
|
|
62
62
|
await (0, _1.scheduleJob)({
|
|
@@ -74,8 +74,7 @@ describe('Event tests', () => {
|
|
|
74
74
|
const job = (0, _1.defineJob)({
|
|
75
75
|
type: 'event',
|
|
76
76
|
async resolve(params, context) {
|
|
77
|
-
if (
|
|
78
|
-
expect(context.tries).toBe(2);
|
|
77
|
+
if (context.tries === 2) {
|
|
79
78
|
context.extendLockTime(10000);
|
|
80
79
|
}
|
|
81
80
|
await (0, helpers_1.sleep)(100);
|
|
@@ -88,20 +87,19 @@ describe('Event tests', () => {
|
|
|
88
87
|
});
|
|
89
88
|
const instance = (0, _1.startWorkers)({
|
|
90
89
|
jobs: { [jobId]: job },
|
|
91
|
-
workersCount:
|
|
90
|
+
workersCount: 2,
|
|
92
91
|
pollInterval: 10,
|
|
93
92
|
cooldownPeriod: 10,
|
|
94
|
-
lockTime:
|
|
95
|
-
logLevel: 'info'
|
|
93
|
+
lockTime: 10
|
|
96
94
|
});
|
|
97
95
|
await (0, _1.scheduleJob)({
|
|
98
96
|
name: jobId,
|
|
99
97
|
runIn: 1
|
|
100
98
|
});
|
|
101
|
-
await (0, helpers_1.sleep)(
|
|
99
|
+
await (0, helpers_1.sleep)(300);
|
|
102
100
|
await instance.stop();
|
|
103
|
-
expect(ranCount).toBe(2);
|
|
104
101
|
expect(staleCount).toBe(1);
|
|
102
|
+
expect(ranCount).toBe(2);
|
|
105
103
|
});
|
|
106
104
|
it('Should only schedule one job with uniqueIdentifier', async () => {
|
|
107
105
|
const jobId = (0, helpers_1.generateId)();
|
|
@@ -116,8 +114,7 @@ describe('Event tests', () => {
|
|
|
116
114
|
jobs: { [jobId]: job },
|
|
117
115
|
workersCount: 1,
|
|
118
116
|
pollInterval: 10,
|
|
119
|
-
cooldownPeriod: 10
|
|
120
|
-
logLevel: 'warn'
|
|
117
|
+
cooldownPeriod: 10
|
|
121
118
|
});
|
|
122
119
|
await (0, _1.scheduleJob)({
|
|
123
120
|
name: jobId,
|
package/lib/history.test.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const helpers_1 = require("@orion-js/helpers");
|
|
4
4
|
const _1 = require(".");
|
|
5
|
+
const logger_1 = require("@orion-js/logger");
|
|
6
|
+
(0, logger_1.setLogLevel)('error');
|
|
5
7
|
describe('Test Jobs History', () => {
|
|
6
8
|
it('Should save success history types', async () => {
|
|
7
9
|
const jobId = (0, helpers_1.generateId)();
|
|
@@ -26,7 +28,7 @@ describe('Test Jobs History', () => {
|
|
|
26
28
|
});
|
|
27
29
|
await (0, helpers_1.sleep)(100);
|
|
28
30
|
await instance.stop();
|
|
29
|
-
const executions = await _1.
|
|
31
|
+
const executions = await _1.jobsHistoryRepo.getExecutions(jobId);
|
|
30
32
|
expect(executions.length).toBe(1);
|
|
31
33
|
const execution = executions[0];
|
|
32
34
|
expect(execution.duration).toBeGreaterThan(49);
|
|
@@ -34,7 +36,7 @@ describe('Test Jobs History', () => {
|
|
|
34
36
|
_id: expect.any(String),
|
|
35
37
|
executionId: expect.any(String),
|
|
36
38
|
jobName: jobId,
|
|
37
|
-
|
|
39
|
+
type: 'event',
|
|
38
40
|
priority: 1,
|
|
39
41
|
tries: 1,
|
|
40
42
|
startedAt: expect.any(Date),
|
|
@@ -58,8 +60,7 @@ describe('Test Jobs History', () => {
|
|
|
58
60
|
const instance = (0, _1.startWorkers)({
|
|
59
61
|
jobs: { [jobId]: job },
|
|
60
62
|
workersCount: 1,
|
|
61
|
-
pollInterval: 10
|
|
62
|
-
logLevel: 'none'
|
|
63
|
+
pollInterval: 10
|
|
63
64
|
});
|
|
64
65
|
await (0, _1.scheduleJob)({
|
|
65
66
|
name: jobId,
|
|
@@ -68,14 +69,14 @@ describe('Test Jobs History', () => {
|
|
|
68
69
|
});
|
|
69
70
|
await (0, helpers_1.sleep)(100);
|
|
70
71
|
await instance.stop();
|
|
71
|
-
const executions = await _1.
|
|
72
|
+
const executions = await _1.jobsHistoryRepo.getExecutions(jobId);
|
|
72
73
|
expect(executions.length).toBe(1);
|
|
73
74
|
const execution = executions[0];
|
|
74
75
|
expect(execution).toEqual({
|
|
75
76
|
_id: expect.any(String),
|
|
76
77
|
executionId: expect.any(String),
|
|
77
78
|
jobName: jobId,
|
|
78
|
-
|
|
79
|
+
type: 'event',
|
|
79
80
|
priority: 1,
|
|
80
81
|
tries: 1,
|
|
81
82
|
startedAt: expect.any(Date),
|
|
@@ -101,8 +102,7 @@ describe('Test Jobs History', () => {
|
|
|
101
102
|
jobs: { [jobId]: job },
|
|
102
103
|
workersCount: 1,
|
|
103
104
|
pollInterval: 10,
|
|
104
|
-
lockTime: 10
|
|
105
|
-
logLevel: 'none'
|
|
105
|
+
lockTime: 10
|
|
106
106
|
});
|
|
107
107
|
await (0, _1.scheduleJob)({
|
|
108
108
|
name: jobId,
|
|
@@ -110,7 +110,7 @@ describe('Test Jobs History', () => {
|
|
|
110
110
|
});
|
|
111
111
|
await (0, helpers_1.sleep)(150);
|
|
112
112
|
await instance.stop();
|
|
113
|
-
const executions = await _1.
|
|
113
|
+
const executions = await _1.jobsHistoryRepo.getExecutions(jobId);
|
|
114
114
|
expect(executions.length).toBe(2);
|
|
115
115
|
const execution1 = executions[1];
|
|
116
116
|
expect(execution1.duration).toBeGreaterThanOrEqual(10);
|
|
@@ -119,7 +119,7 @@ describe('Test Jobs History', () => {
|
|
|
119
119
|
_id: expect.any(String),
|
|
120
120
|
executionId: expect.any(String),
|
|
121
121
|
jobName: jobId,
|
|
122
|
-
|
|
122
|
+
type: 'event',
|
|
123
123
|
priority: 1,
|
|
124
124
|
tries: 1,
|
|
125
125
|
startedAt: expect.any(Date),
|
|
@@ -137,7 +137,7 @@ describe('Test Jobs History', () => {
|
|
|
137
137
|
_id: expect.any(String),
|
|
138
138
|
executionId: expect.any(String),
|
|
139
139
|
jobName: jobId,
|
|
140
|
-
|
|
140
|
+
type: 'event',
|
|
141
141
|
priority: 1,
|
|
142
142
|
tries: 1,
|
|
143
143
|
startedAt: expect.any(Date),
|
package/lib/index.d.ts
CHANGED
|
@@ -2,7 +2,10 @@ import { defineJob } from './defineJob';
|
|
|
2
2
|
import { StartWorkersConfig } from './types/StartConfig';
|
|
3
3
|
import { ScheduleJobOptions } from './types/Events';
|
|
4
4
|
import { JobsHistoryRepo } from './repos/JobsHistoryRepo';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { JobsRepo } from './repos/JobsRepo';
|
|
6
|
+
export * from './types';
|
|
7
|
+
declare const jobsHistoryRepo: JobsHistoryRepo;
|
|
8
|
+
declare const jobsRepo: JobsRepo;
|
|
9
|
+
declare const startWorkers: (config: Partial<StartWorkersConfig>) => import("./types").WorkersInstance;
|
|
7
10
|
declare const scheduleJob: (options: ScheduleJobOptions) => Promise<void>;
|
|
8
|
-
export { defineJob, startWorkers, scheduleJob,
|
|
11
|
+
export { defineJob, startWorkers, scheduleJob, jobsHistoryRepo, jobsRepo };
|
package/lib/index.js
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
2
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
13
|
+
exports.jobsRepo = exports.jobsHistoryRepo = exports.scheduleJob = exports.startWorkers = exports.defineJob = void 0;
|
|
4
14
|
const services_1 = require("@orion-js/services");
|
|
5
15
|
const defineJob_1 = require("./defineJob");
|
|
6
16
|
Object.defineProperty(exports, "defineJob", { enumerable: true, get: function () { return defineJob_1.defineJob; } });
|
|
7
17
|
const EventsService_1 = require("./services/EventsService");
|
|
8
18
|
const WorkerService_1 = require("./services/WorkerService");
|
|
9
19
|
const JobsHistoryRepo_1 = require("./repos/JobsHistoryRepo");
|
|
20
|
+
const JobsRepo_1 = require("./repos/JobsRepo");
|
|
21
|
+
__exportStar(require("./types"), exports);
|
|
10
22
|
const workerService = (0, services_1.getInstance)(WorkerService_1.WorkerService);
|
|
11
23
|
const eventsService = (0, services_1.getInstance)(EventsService_1.EventsService);
|
|
12
|
-
const
|
|
13
|
-
exports.
|
|
24
|
+
const jobsHistoryRepo = (0, services_1.getInstance)(JobsHistoryRepo_1.JobsHistoryRepo);
|
|
25
|
+
exports.jobsHistoryRepo = jobsHistoryRepo;
|
|
26
|
+
const jobsRepo = (0, services_1.getInstance)(JobsRepo_1.JobsRepo);
|
|
27
|
+
exports.jobsRepo = jobsRepo;
|
|
14
28
|
const startWorkers = (config) => {
|
|
15
29
|
return workerService.startWorkers(config);
|
|
16
30
|
};
|
package/lib/recurrent.test.js
CHANGED
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
require("reflect-metadata");
|
|
4
4
|
const helpers_1 = require("@orion-js/helpers");
|
|
5
5
|
const _1 = require(".");
|
|
6
|
+
const logger_1 = require("@orion-js/logger");
|
|
7
|
+
(0, logger_1.setLogLevel)('error');
|
|
6
8
|
describe('Recurrent tests', () => {
|
|
7
9
|
it('Should run a recurrent job', async () => {
|
|
8
10
|
let ran = false;
|
|
@@ -17,8 +19,7 @@ describe('Recurrent tests', () => {
|
|
|
17
19
|
jobs: { job1 },
|
|
18
20
|
workersCount: 1,
|
|
19
21
|
pollInterval: 100,
|
|
20
|
-
cooldownPeriod: 100
|
|
21
|
-
logLevel: 'info'
|
|
22
|
+
cooldownPeriod: 100
|
|
22
23
|
});
|
|
23
24
|
await (0, helpers_1.sleep)(500);
|
|
24
25
|
await instance.stop();
|
|
@@ -37,8 +38,7 @@ describe('Recurrent tests', () => {
|
|
|
37
38
|
jobs: { job2 },
|
|
38
39
|
workersCount: 1,
|
|
39
40
|
pollInterval: 10,
|
|
40
|
-
cooldownPeriod: 10
|
|
41
|
-
logLevel: 'info'
|
|
41
|
+
cooldownPeriod: 10
|
|
42
42
|
});
|
|
43
43
|
await (0, helpers_1.sleep)(200);
|
|
44
44
|
await instance.stop();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ModelToDocumentTypeWithoutId } from '@orion-js/mongodb';
|
|
2
2
|
import { HistoryRecord } from '../types/HistoryRecord';
|
|
3
3
|
export declare class JobsHistoryRepo {
|
|
4
|
-
|
|
4
|
+
history: import("@orion-js/mongodb").Collection<HistoryRecord>;
|
|
5
5
|
saveExecution(record: ModelToDocumentTypeWithoutId<HistoryRecord>): Promise<void>;
|
|
6
6
|
getExecutions(jobName: string, limit?: number, skip?: number): Promise<HistoryRecord[]>;
|
|
7
7
|
}
|
package/lib/repos/JobsRepo.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { ScheduleJobRecordOptions } from '../types/Events';
|
|
2
|
+
import { JobRecord } from '../types/JobRecord';
|
|
2
3
|
import { JobDefinitionWithName } from '../types/JobsDefinition';
|
|
3
4
|
import { JobToRun } from '../types/Worker';
|
|
4
5
|
export declare class JobsRepo {
|
|
5
|
-
|
|
6
|
+
jobs: import("@orion-js/mongodb").Collection<JobRecord>;
|
|
6
7
|
getJobAndLock(jobNames: string[], lockTime: number): Promise<JobToRun>;
|
|
7
8
|
scheduleNextRun(options: {
|
|
8
9
|
jobId: string;
|
|
9
10
|
nextRunAt: Date;
|
|
10
11
|
addTries: boolean;
|
|
11
12
|
}): Promise<void>;
|
|
13
|
+
deleteEventJob(jobId: string): Promise<void>;
|
|
12
14
|
extendLockTime(jobId: string, extraTime: number): Promise<void>;
|
|
13
15
|
ensureJobRecord(job: JobDefinitionWithName): Promise<void>;
|
|
14
16
|
scheduleJob(options: ScheduleJobRecordOptions): Promise<void>;
|
package/lib/repos/JobsRepo.js
CHANGED
|
@@ -7,9 +7,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
};
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.JobsRepo = void 0;
|
|
10
|
+
const logger_1 = require("@orion-js/logger");
|
|
10
11
|
const mongodb_1 = require("@orion-js/mongodb");
|
|
11
12
|
const services_1 = require("@orion-js/services");
|
|
12
|
-
const log_1 = require("../log");
|
|
13
13
|
const JobRecord_1 = require("../types/JobRecord");
|
|
14
14
|
let JobsRepo = class JobsRepo {
|
|
15
15
|
constructor() {
|
|
@@ -31,7 +31,7 @@ let JobsRepo = class JobsRepo {
|
|
|
31
31
|
},
|
|
32
32
|
options: {
|
|
33
33
|
unique: true,
|
|
34
|
-
partialFilterExpression: {
|
|
34
|
+
partialFilterExpression: { type: 'recurrent' }
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
{
|
|
@@ -53,7 +53,7 @@ let JobsRepo = class JobsRepo {
|
|
|
53
53
|
nextRunAt: { $lte: new Date() },
|
|
54
54
|
$or: [{ lockedUntil: { $exists: false } }, { lockedUntil: { $lte: new Date() } }]
|
|
55
55
|
}, {
|
|
56
|
-
$set: { lockedUntil }
|
|
56
|
+
$set: { lockedUntil, lastRunAt: new Date() }
|
|
57
57
|
}, {
|
|
58
58
|
mongoOptions: {
|
|
59
59
|
sort: {
|
|
@@ -67,7 +67,7 @@ let JobsRepo = class JobsRepo {
|
|
|
67
67
|
return;
|
|
68
68
|
let tries = job.tries || 1;
|
|
69
69
|
if (job.lockedUntil) {
|
|
70
|
-
|
|
70
|
+
logger_1.logger.info(`Running job "${job.jobName}" that was staled`);
|
|
71
71
|
this.jobs.updateOne(job._id, { $inc: { tries: 1 } });
|
|
72
72
|
tries++;
|
|
73
73
|
}
|
|
@@ -75,7 +75,7 @@ let JobsRepo = class JobsRepo {
|
|
|
75
75
|
jobId: job._id,
|
|
76
76
|
name: job.jobName,
|
|
77
77
|
params: job.params,
|
|
78
|
-
|
|
78
|
+
type: job.type,
|
|
79
79
|
tries,
|
|
80
80
|
lockTime,
|
|
81
81
|
priority: job.priority,
|
|
@@ -92,6 +92,9 @@ let JobsRepo = class JobsRepo {
|
|
|
92
92
|
}
|
|
93
93
|
await this.jobs.updateOne(options.jobId, updator);
|
|
94
94
|
}
|
|
95
|
+
async deleteEventJob(jobId) {
|
|
96
|
+
await this.jobs.deleteOne({ _id: jobId, type: 'event' });
|
|
97
|
+
}
|
|
95
98
|
async extendLockTime(jobId, extraTime) {
|
|
96
99
|
const lockedUntil = new Date(Date.now() + extraTime);
|
|
97
100
|
await this.jobs.updateOne({
|
|
@@ -105,7 +108,7 @@ let JobsRepo = class JobsRepo {
|
|
|
105
108
|
jobName: job.name
|
|
106
109
|
}, {
|
|
107
110
|
$set: {
|
|
108
|
-
|
|
111
|
+
type: job.type,
|
|
109
112
|
priority: job.priority || 1
|
|
110
113
|
},
|
|
111
114
|
$setOnInsert: {
|
|
@@ -113,10 +116,10 @@ let JobsRepo = class JobsRepo {
|
|
|
113
116
|
}
|
|
114
117
|
});
|
|
115
118
|
if (result.upsertedId) {
|
|
116
|
-
|
|
119
|
+
logger_1.logger.info(`Created job record for "${job.name}"`);
|
|
117
120
|
}
|
|
118
121
|
else {
|
|
119
|
-
|
|
122
|
+
logger_1.logger.info(`Record for job "${job.name}" already exists`);
|
|
120
123
|
}
|
|
121
124
|
}
|
|
122
125
|
async scheduleJob(options) {
|
|
@@ -127,12 +130,12 @@ let JobsRepo = class JobsRepo {
|
|
|
127
130
|
params: options.params,
|
|
128
131
|
nextRunAt: options.nextRunAt,
|
|
129
132
|
priority: options.priority,
|
|
130
|
-
|
|
133
|
+
type: 'event'
|
|
131
134
|
});
|
|
132
135
|
}
|
|
133
136
|
catch (error) {
|
|
134
137
|
if (error.code === 11000 && options.uniqueIdentifier) {
|
|
135
|
-
|
|
138
|
+
logger_1.logger.info(`Job "${options.name}" with identifier "${options.uniqueIdentifier}" already exists`);
|
|
136
139
|
}
|
|
137
140
|
else {
|
|
138
141
|
throw error;
|
|
@@ -10,13 +10,13 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.EventsService = void 0;
|
|
13
|
+
const logger_1 = require("@orion-js/logger");
|
|
13
14
|
const services_1 = require("@orion-js/services");
|
|
14
|
-
const log_1 = require("../log");
|
|
15
15
|
const JobsRepo_1 = require("../repos/JobsRepo");
|
|
16
16
|
const getNextRunDate_1 = require("./getNextRunDate");
|
|
17
17
|
let EventsService = class EventsService {
|
|
18
18
|
async scheduleJob(options) {
|
|
19
|
-
|
|
19
|
+
logger_1.logger.info('Scheduling job...', options);
|
|
20
20
|
await this.jobsRepo.scheduleJob({
|
|
21
21
|
name: options.name,
|
|
22
22
|
priority: options.priority || 1,
|
|
@@ -15,5 +15,6 @@ export declare class Executor {
|
|
|
15
15
|
job: JobDefinition;
|
|
16
16
|
jobToRun: JobToRun;
|
|
17
17
|
}): Promise<void>;
|
|
18
|
+
afterExecutionSuccess(job: JobDefinition, jobToRun: JobToRun, context: ExecutionContext): Promise<void>;
|
|
18
19
|
executeJob(jobs: JobsDefinition, jobToRun: JobToRun): Promise<void>;
|
|
19
20
|
}
|
package/lib/services/Executor.js
CHANGED
|
@@ -10,8 +10,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.Executor = void 0;
|
|
13
|
+
const logger_1 = require("@orion-js/logger");
|
|
13
14
|
const services_1 = require("@orion-js/services");
|
|
14
|
-
const log_1 = require("../log");
|
|
15
15
|
const JobsHistoryRepo_1 = require("../repos/JobsHistoryRepo");
|
|
16
16
|
const JobsRepo_1 = require("../repos/JobsRepo");
|
|
17
17
|
const getNextRunDate_1 = require("./getNextRunDate");
|
|
@@ -27,17 +27,17 @@ let Executor = class Executor {
|
|
|
27
27
|
clearTimeout(staleTimeout);
|
|
28
28
|
staleTimeout = setTimeout(() => onStale(), extraTime);
|
|
29
29
|
await this.jobsRepo.extendLockTime(jobToRun.jobId, extraTime);
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
|
+
logger: logger_1.logger.addMetadata({
|
|
32
|
+
jobName: jobToRun.name,
|
|
33
|
+
jobId: jobToRun.jobId
|
|
34
|
+
})
|
|
31
35
|
};
|
|
32
36
|
}
|
|
33
37
|
getJobDefinition(jobToRun, jobs) {
|
|
34
38
|
const job = jobs[jobToRun.name];
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (jobToRun.isRecurrent && job.type === 'event') {
|
|
40
|
-
(0, log_1.log)('warn', `Job record ${jobToRun.name} is recurrent but definition is event`);
|
|
39
|
+
if (jobToRun.type !== job.type) {
|
|
40
|
+
logger_1.logger.warn(`Job record "${jobToRun.name}" is "${jobToRun.type}" but definition is "${job.type}"`);
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
return job;
|
|
@@ -53,12 +53,12 @@ let Executor = class Executor {
|
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
if (!job.onError) {
|
|
56
|
-
|
|
56
|
+
context.logger.error(`Error executing job "${jobToRun.name}"`, error);
|
|
57
57
|
await scheduleRecurrent();
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
|
-
|
|
61
|
+
context.logger.info(`Error executing job "${jobToRun.name}"`, error);
|
|
62
62
|
}
|
|
63
63
|
const result = await job.onError(error, jobToRun.params, context);
|
|
64
64
|
if (result.action === 'dismiss') {
|
|
@@ -81,7 +81,7 @@ let Executor = class Executor {
|
|
|
81
81
|
await this.jobsHistoryRepo.saveExecution({
|
|
82
82
|
executionId: jobToRun.jobId,
|
|
83
83
|
jobName: jobToRun.name,
|
|
84
|
-
|
|
84
|
+
type: jobToRun.type,
|
|
85
85
|
priority: jobToRun.priority,
|
|
86
86
|
tries: jobToRun.tries,
|
|
87
87
|
uniqueIdentifier: jobToRun.uniqueIdentifier,
|
|
@@ -96,6 +96,20 @@ let Executor = class Executor {
|
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
+
async afterExecutionSuccess(job, jobToRun, context) {
|
|
100
|
+
if (job.type === 'recurrent') {
|
|
101
|
+
context.logger.info(`Scheduling next run for recurrent job "${jobToRun.name}"`);
|
|
102
|
+
await this.jobsRepo.scheduleNextRun({
|
|
103
|
+
jobId: jobToRun.jobId,
|
|
104
|
+
nextRunAt: (0, getNextRunDate_1.getNextRunDate)(job),
|
|
105
|
+
addTries: false
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (job.type === 'event') {
|
|
109
|
+
context.logger.info(`Removing event job after success "${jobToRun.name}"`);
|
|
110
|
+
await this.jobsRepo.deleteEventJob(jobToRun.jobId);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
99
113
|
async executeJob(jobs, jobToRun) {
|
|
100
114
|
const job = this.getJobDefinition(jobToRun, jobs);
|
|
101
115
|
if (!job)
|
|
@@ -103,11 +117,11 @@ let Executor = class Executor {
|
|
|
103
117
|
const startedAt = new Date();
|
|
104
118
|
const onStale = () => {
|
|
105
119
|
if (job.onStale) {
|
|
106
|
-
|
|
120
|
+
context.logger.info(`Job "${jobToRun.name}" is stale`);
|
|
107
121
|
job.onStale(jobToRun.params, context);
|
|
108
122
|
}
|
|
109
123
|
else {
|
|
110
|
-
|
|
124
|
+
context.logger.error(`Job "${jobToRun.name}" is stale`);
|
|
111
125
|
}
|
|
112
126
|
this.saveExecution({
|
|
113
127
|
startedAt,
|
|
@@ -130,13 +144,7 @@ let Executor = class Executor {
|
|
|
130
144
|
job,
|
|
131
145
|
jobToRun
|
|
132
146
|
});
|
|
133
|
-
|
|
134
|
-
await this.jobsRepo.scheduleNextRun({
|
|
135
|
-
jobId: jobToRun.jobId,
|
|
136
|
-
nextRunAt: (0, getNextRunDate_1.getNextRunDate)(job),
|
|
137
|
-
addTries: false
|
|
138
|
-
});
|
|
139
|
-
}
|
|
147
|
+
await this.afterExecutionSuccess(job, jobToRun, context);
|
|
140
148
|
}
|
|
141
149
|
catch (error) {
|
|
142
150
|
context.clearStaleTimeout();
|
|
@@ -15,7 +15,7 @@ const lodash_1 = require("lodash");
|
|
|
15
15
|
const JobsRepo_1 = require("../repos/JobsRepo");
|
|
16
16
|
const helpers_1 = require("@orion-js/helpers");
|
|
17
17
|
const Executor_1 = require("./Executor");
|
|
18
|
-
const
|
|
18
|
+
const logger_1 = require("@orion-js/logger");
|
|
19
19
|
let WorkerService = class WorkerService {
|
|
20
20
|
getJobNames(jobs) {
|
|
21
21
|
return Object.keys(jobs);
|
|
@@ -30,20 +30,20 @@ let WorkerService = class WorkerService {
|
|
|
30
30
|
}
|
|
31
31
|
async runWorkerLoop(config) {
|
|
32
32
|
const names = this.getJobNames(config.jobs);
|
|
33
|
-
|
|
33
|
+
logger_1.logger.debug(`Running worker loop for jobs "${names.join(', ')}"...`);
|
|
34
34
|
const jobToRun = await this.jobsRepo.getJobAndLock(names, config.lockTime);
|
|
35
35
|
if (!jobToRun) {
|
|
36
|
-
|
|
36
|
+
logger_1.logger.debug('No job to run');
|
|
37
37
|
return false;
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
logger_1.logger.info(`Got job to run:`, jobToRun);
|
|
40
40
|
await this.executor.executeJob(config.jobs, jobToRun);
|
|
41
41
|
return true;
|
|
42
42
|
}
|
|
43
43
|
async startWorker(config, workersInstance) {
|
|
44
44
|
while (true) {
|
|
45
45
|
if (!workersInstance.running) {
|
|
46
|
-
|
|
46
|
+
logger_1.logger.info('Got signal to stop. Stopping worker...');
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
try {
|
|
@@ -54,7 +54,7 @@ let WorkerService = class WorkerService {
|
|
|
54
54
|
await (0, helpers_1.sleep)(config.cooldownPeriod);
|
|
55
55
|
}
|
|
56
56
|
catch (error) {
|
|
57
|
-
|
|
57
|
+
logger_1.logger.error(`Error in job runner. Waiting and running again`, error);
|
|
58
58
|
await (0, helpers_1.sleep)(config.pollInterval);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -65,7 +65,7 @@ let WorkerService = class WorkerService {
|
|
|
65
65
|
workersCount: config.workersCount,
|
|
66
66
|
workers: [],
|
|
67
67
|
stop: async () => {
|
|
68
|
-
|
|
68
|
+
logger_1.logger.debug('Stopping workers...', workersInstance.workers);
|
|
69
69
|
workersInstance.running = false;
|
|
70
70
|
await Promise.all(workersInstance.workers);
|
|
71
71
|
}
|
|
@@ -77,15 +77,15 @@ let WorkerService = class WorkerService {
|
|
|
77
77
|
await Promise.all(jobs
|
|
78
78
|
.filter(job => job.type === 'recurrent')
|
|
79
79
|
.map(async (job) => {
|
|
80
|
-
|
|
80
|
+
logger_1.logger.info(`Ensuring records for job "${job.name}"...`);
|
|
81
81
|
await this.jobsRepo.ensureJobRecord(job);
|
|
82
82
|
}));
|
|
83
83
|
}
|
|
84
84
|
async runWorkers(config, workersInstance) {
|
|
85
|
-
|
|
85
|
+
logger_1.logger.info('Will ensure records for recurrent jobs');
|
|
86
86
|
await this.ensureRecords(config);
|
|
87
87
|
for (const workerIndex of (0, lodash_1.range)(config.workersCount)) {
|
|
88
|
-
|
|
88
|
+
logger_1.logger.info(`Starting worker ${workerIndex}`);
|
|
89
89
|
const workerPromise = this.startWorker(config, workersInstance);
|
|
90
90
|
workersInstance.workers.push(workerPromise);
|
|
91
91
|
}
|
|
@@ -96,16 +96,14 @@ let WorkerService = class WorkerService {
|
|
|
96
96
|
cooldownPeriod: 100,
|
|
97
97
|
pollInterval: 3000,
|
|
98
98
|
workersCount: 4,
|
|
99
|
-
lockTime: 30 * 1000
|
|
100
|
-
logLevel: 'info'
|
|
99
|
+
lockTime: 30 * 1000
|
|
101
100
|
};
|
|
102
101
|
const config = {
|
|
103
102
|
...defaultConfig,
|
|
104
103
|
...userConfig
|
|
105
104
|
};
|
|
106
|
-
(0, log_1.setLogLevel)(config.logLevel);
|
|
107
105
|
const workersInstance = this.createWorkersInstanceDefinition(config);
|
|
108
|
-
|
|
106
|
+
logger_1.logger.info('Starting workers', config);
|
|
109
107
|
this.runWorkers(config, workersInstance);
|
|
110
108
|
return workersInstance;
|
|
111
109
|
}
|
|
@@ -11,6 +11,9 @@ const getNextRunDate = (options) => {
|
|
|
11
11
|
if (options.runAt) {
|
|
12
12
|
return options.runAt;
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
if (options.getNextRun) {
|
|
15
|
+
return options.getNextRun();
|
|
16
|
+
}
|
|
17
|
+
return new Date();
|
|
15
18
|
};
|
|
16
19
|
exports.getNextRunDate = getNextRunDate;
|
package/lib/types/Events.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare type ScheduleJobOptionsRunIn = ScheduleJobOptionsBase & {
|
|
|
11
11
|
export declare type ScheduleJobOptionsRunAt = ScheduleJobOptionsBase & {
|
|
12
12
|
runAt: Date;
|
|
13
13
|
};
|
|
14
|
-
export declare type ScheduleJobOptions = ScheduleJobOptionsRunIn | ScheduleJobOptionsRunAt;
|
|
14
|
+
export declare type ScheduleJobOptions = ScheduleJobOptionsRunIn | ScheduleJobOptionsRunAt | ScheduleJobOptionsBase;
|
|
15
15
|
export interface ScheduleJobRecordOptions {
|
|
16
16
|
name: string;
|
|
17
17
|
params: PlainObject;
|
|
@@ -27,8 +27,8 @@ __decorate([
|
|
|
27
27
|
], HistoryRecord.prototype, "jobName", void 0);
|
|
28
28
|
__decorate([
|
|
29
29
|
(0, typed_model_1.Prop)(),
|
|
30
|
-
__metadata("design:type",
|
|
31
|
-
], HistoryRecord.prototype, "
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], HistoryRecord.prototype, "type", void 0);
|
|
32
32
|
__decorate([
|
|
33
33
|
(0, typed_model_1.Prop)(),
|
|
34
34
|
__metadata("design:type", Number)
|
package/lib/types/JobRecord.d.ts
CHANGED
package/lib/types/JobRecord.js
CHANGED
|
@@ -23,8 +23,8 @@ __decorate([
|
|
|
23
23
|
], JobRecord.prototype, "jobName", void 0);
|
|
24
24
|
__decorate([
|
|
25
25
|
(0, typed_model_1.Prop)(),
|
|
26
|
-
__metadata("design:type",
|
|
27
|
-
], JobRecord.prototype, "
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], JobRecord.prototype, "type", void 0);
|
|
28
28
|
__decorate([
|
|
29
29
|
(0, typed_model_1.Prop)(),
|
|
30
30
|
__metadata("design:type", Number)
|
|
@@ -9,7 +9,7 @@ export declare type JobRetryResultRunIn = JobRetryResultBase & {
|
|
|
9
9
|
export declare type JobRetryResultRunAt = JobRetryResultBase & {
|
|
10
10
|
runAt: Date;
|
|
11
11
|
};
|
|
12
|
-
export declare type JobRetryResult = JobRetryResultRunIn | JobRetryResultRunAt;
|
|
12
|
+
export declare type JobRetryResult = JobRetryResultRunIn | JobRetryResultRunAt | JobRetryResultBase;
|
|
13
13
|
export interface BaseJobDefinition {
|
|
14
14
|
/**
|
|
15
15
|
* The function to execute when the job is executed.
|
package/lib/types/Worker.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { OrionLogger } from '@orion-js/logger';
|
|
1
2
|
import { PlainObject } from './HistoryRecord';
|
|
2
3
|
import { JobDefinition } from './JobsDefinition';
|
|
3
4
|
export interface JobToRun {
|
|
4
5
|
jobId: string;
|
|
5
6
|
name: string;
|
|
6
|
-
|
|
7
|
+
type: 'event' | 'recurrent';
|
|
7
8
|
params: PlainObject;
|
|
8
9
|
tries: number;
|
|
9
10
|
lockTime: number;
|
|
@@ -14,6 +15,7 @@ export interface ExecutionContext {
|
|
|
14
15
|
record: JobToRun;
|
|
15
16
|
definition: JobDefinition;
|
|
16
17
|
tries: number;
|
|
18
|
+
logger: OrionLogger;
|
|
17
19
|
extendLockTime: (extraTime: number) => Promise<void>;
|
|
18
20
|
clearStaleTimeout: () => void;
|
|
19
21
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./Events"), exports);
|
|
14
|
+
__exportStar(require("./HistoryRecord"), exports);
|
|
15
|
+
__exportStar(require("./JobRecord"), exports);
|
|
16
|
+
__exportStar(require("./JobsDefinition"), exports);
|
|
17
|
+
__exportStar(require("./StartConfig"), exports);
|
|
18
|
+
__exportStar(require("./Worker"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-js/dogs",
|
|
3
|
-
"version": "3.1.0-alpha.
|
|
3
|
+
"version": "3.1.0-alpha.13",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -22,7 +22,11 @@
|
|
|
22
22
|
"@orion-js/services": "^3.1.0-alpha.0",
|
|
23
23
|
"@orion-js/typed-model": "^3.0.38"
|
|
24
24
|
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@orion-js/logger": "3.1.0-alpha.12"
|
|
27
|
+
},
|
|
25
28
|
"devDependencies": {
|
|
29
|
+
"@orion-js/logger": "^3.1.0-alpha.13",
|
|
26
30
|
"@shelf/jest-mongodb": "^2.1.0",
|
|
27
31
|
"@types/jest": "^27.0.2",
|
|
28
32
|
"@types/lodash": "4.14.176",
|
|
@@ -35,5 +39,5 @@
|
|
|
35
39
|
"publishConfig": {
|
|
36
40
|
"access": "public"
|
|
37
41
|
},
|
|
38
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "9c815a15f5f4babc6de240e26244f09424fbc716"
|
|
39
43
|
}
|
package/lib/log/index.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { LogLevels } from '../types/StartConfig';
|
|
2
|
-
export declare let appLogLevel: LogLevels;
|
|
3
|
-
export declare const levelToInt: (level: LogLevels) => 0 | 1 | 2 | 3;
|
|
4
|
-
export declare const log: (level: LogLevels, ...args: any[]) => void;
|
|
5
|
-
export declare const setLogLevel: (level: LogLevels) => void;
|
package/lib/log/index.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setLogLevel = exports.log = exports.levelToInt = exports.appLogLevel = void 0;
|
|
4
|
-
exports.appLogLevel = 'info';
|
|
5
|
-
const levelToInt = (level) => {
|
|
6
|
-
switch (level) {
|
|
7
|
-
case 'debug':
|
|
8
|
-
return 0;
|
|
9
|
-
case 'info':
|
|
10
|
-
return 1;
|
|
11
|
-
case 'warn':
|
|
12
|
-
return 2;
|
|
13
|
-
case 'error':
|
|
14
|
-
return 3;
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
exports.levelToInt = levelToInt;
|
|
18
|
-
const log = (level, ...args) => {
|
|
19
|
-
if (exports.appLogLevel === 'none')
|
|
20
|
-
return;
|
|
21
|
-
const levelInt = (0, exports.levelToInt)(level);
|
|
22
|
-
const appLogLevelInt = (0, exports.levelToInt)(exports.appLogLevel);
|
|
23
|
-
if (levelInt < appLogLevelInt)
|
|
24
|
-
return;
|
|
25
|
-
console[level](...args);
|
|
26
|
-
};
|
|
27
|
-
exports.log = log;
|
|
28
|
-
const setLogLevel = (level) => {
|
|
29
|
-
exports.appLogLevel = level;
|
|
30
|
-
};
|
|
31
|
-
exports.setLogLevel = setLogLevel;
|