-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJob.js
133 lines (131 loc) · 3.66 KB
/
Job.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
const EventEmitter = require("events");
const parseTimeToInt = require("./Parser").parseTimeToInt;
const MAX_TIME_INTERVAL = 2147483647;
class Job extends EventEmitter {
constructor(name, time, execution, options = {}) {
super();
if (typeof execution !== "function") {
throw new Error("execution parameter must be a function!");
}
this._name = name;
this._time = time;
this._execution = execution;
this._once = options.once !== undefined ? options.once : false;
this._interval = Math.min(parseTimeToInt(time), MAX_TIME_INTERVAL);
this._intervalId = null;
this._isExecuting = false;
this.on("start-running", () => {
console.log(
`[${new Date().toLocaleString()}]: Job {${
this._name
}} started running with interval: ${this._interval}`
);
});
this.on("job-failed", (error) => {
console.log(
`[${new Date().toLocaleString()}]: Job {${
this._name
}} has failed with the following error`
);
throw error;
});
this.on("stop-job", () => {
clearInterval(this._intervalId);
clearTimeout(this._intervalId);
this._intervalId = null;
});
this.on("start-executing", () => {
console.log(
`[${new Date().toLocaleString()}] Job {${this.getName()}}: started executing `
);
this._isExecuting = true;
});
this.on("finished-executing", () => {
console.log(
`[${new Date().toLocaleString()}] Job {${this.getName()}}: finished executing `
);
this._isExecuting = false;
});
}
/**
* @description executes the Job and returns the result
* and emits an event when job finishes or fails.
* If the job is a single run job (once=true), then add its execution
* as a callback to a setTimeout. Else, add it as a callback in a
* setInterval, and pass the job's interval as an argument to the setInterval.
*/
execute() {
this.emit("start-running");
let exec;
try {
if (!this.getOnce()) {
let intervalId = setInterval(() => {
this.emit("start-executing");
exec = this._execution();
if (exec instanceof Promise) {
exec
.then(() => {
this.emit("finished-executing");
})
.catch((error) => {
throw error;
});
} else {
this.emit("finished-executing");
}
}, this._interval);
this.setIntervalId(intervalId);
} else {
this._executeOnce(exec);
}
} catch (error) {
this.emit("job failed", error);
}
}
/**
* @description Auxiliary method for running a single-run job
*/
_executeOnce(exec) {
let timeoutId = setTimeout(() => {
this.emit("start-executing");
exec = this._execution();
if (exec instanceof Promise) {
exec
.then(() => {
this.emit("finished-executing");
})
.catch((error) => {
throw error;
});
} else {
this.emit("finished-executing");
}
}, this._interval);
this.setIntervalId(timeoutId);
}
/**
* Setters and Getters
*/
getName() {
return this._name;
}
getInterval() {
return this._interval;
}
getOnce() {
return this._once;
}
getIntervalId() {
return this._intervalId;
}
setIntervalId(intervalId) {
this._intervalId = intervalId;
}
/**
* @description Sends an event to stop the job.
*/
stopJob() {
this.emit("stop-job");
}
}
module.exports = Job;