badmfck-api-server 4.0.80 → 4.0.82
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.
|
@@ -11,16 +11,18 @@ export interface ITimeframeTask<T = any> {
|
|
|
11
11
|
executed: number;
|
|
12
12
|
retries?: number;
|
|
13
13
|
maxRetries?: number;
|
|
14
|
+
processing?: boolean;
|
|
14
15
|
}
|
|
15
16
|
export declare class TimeframeService extends BaseService {
|
|
16
17
|
TICK_INTERVAL_MS: number;
|
|
17
18
|
RETRY_DELAY_MS: number;
|
|
18
19
|
GRACE_WINDOW_MS: number;
|
|
19
20
|
tasks: ITimeframeTask<any>[];
|
|
20
|
-
intervalId
|
|
21
|
+
private intervalId;
|
|
21
22
|
static wait(ms: number): Promise<void>;
|
|
22
23
|
constructor();
|
|
23
24
|
init(): Promise<void>;
|
|
24
|
-
finishService(): Promise<void>;
|
|
25
25
|
loop(): Promise<void>;
|
|
26
|
+
private runTask;
|
|
27
|
+
finishService(): Promise<void>;
|
|
26
28
|
}
|
|
@@ -43,55 +43,78 @@ class TimeframeService extends BaseService_1.BaseService {
|
|
|
43
43
|
}
|
|
44
44
|
async init() {
|
|
45
45
|
exports.REQ_TIMEFRAME_TASK_ADD.listener = async (req) => {
|
|
46
|
-
(0, LogService_1.logInfo)("Add
|
|
47
|
-
this.tasks.push(
|
|
46
|
+
(0, LogService_1.logInfo)("Add task " + req.name);
|
|
47
|
+
this.tasks.push({
|
|
48
|
+
...req,
|
|
49
|
+
executed: 0,
|
|
50
|
+
retries: 0,
|
|
51
|
+
processing: false
|
|
52
|
+
});
|
|
48
53
|
};
|
|
49
54
|
this.intervalId = setInterval(() => {
|
|
50
|
-
this.loop();
|
|
55
|
+
this.loop().catch(console.error);
|
|
51
56
|
}, this.TICK_INTERVAL_MS);
|
|
52
57
|
}
|
|
53
|
-
async finishService() {
|
|
54
|
-
clearInterval(this.intervalId);
|
|
55
|
-
}
|
|
56
58
|
async loop() {
|
|
57
59
|
const now = Date.now();
|
|
58
60
|
for (let i = 0; i < this.tasks.length; i++) {
|
|
59
61
|
const task = this.tasks[i];
|
|
60
62
|
if (!task)
|
|
61
63
|
continue;
|
|
62
|
-
if (
|
|
64
|
+
if (task.repeat && !task.processing && now > (task.start + this.GRACE_WINDOW_MS)) {
|
|
65
|
+
const diff = now - task.start;
|
|
66
|
+
const missedIntervals = Math.ceil(diff / task.repeat);
|
|
67
|
+
task.start += missedIntervals * task.repeat;
|
|
68
|
+
(0, LogService_1.logInfo)(`Task ${task.name} skipped and rescheduled to ${new Date(task.start).toLocaleTimeString()}`);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const isReady = now >= task.start;
|
|
72
|
+
const isNotExecutedYet = !task.executed || task.executed < task.start;
|
|
73
|
+
if (isReady && isNotExecutedYet && !task.processing) {
|
|
63
74
|
if (now - task.start <= this.GRACE_WINDOW_MS) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
task.executed = Date.now();
|
|
71
|
-
task.retries = 0;
|
|
72
|
-
(0, LogService_1.logInfo)("Executed task ", task.name);
|
|
73
|
-
if (task.repeat) {
|
|
74
|
-
task.start += task.repeat;
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
this.tasks.splice(i, 1);
|
|
78
|
-
i--;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (e) {
|
|
82
|
-
task.retries = (task.retries || 0) + 1;
|
|
83
|
-
if (task.retries > (task.maxRetries ?? 0)) {
|
|
84
|
-
console.warn(`Task ${task.name} failed too many times`);
|
|
85
|
-
this.tasks.splice(i, 1);
|
|
86
|
-
i--;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
task.start = now + 10_000;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
75
|
+
this.runTask(task);
|
|
76
|
+
}
|
|
77
|
+
else if (!task.repeat) {
|
|
78
|
+
(0, LogService_1.logInfo)(`One-off task ${task.name} missed grace window. Dropping.`);
|
|
79
|
+
task.executed = now;
|
|
80
|
+
this.tasks = this.tasks.filter(t => t !== task);
|
|
92
81
|
}
|
|
93
82
|
}
|
|
94
83
|
}
|
|
95
84
|
}
|
|
85
|
+
async runTask(task) {
|
|
86
|
+
task.processing = true;
|
|
87
|
+
try {
|
|
88
|
+
(0, LogService_1.logInfo)("Execute task ", task.name);
|
|
89
|
+
await task.callback(task.params);
|
|
90
|
+
task.executed = Date.now();
|
|
91
|
+
task.retries = 0;
|
|
92
|
+
(0, LogService_1.logInfo)("Executed task ", task.name);
|
|
93
|
+
if (task.repeat) {
|
|
94
|
+
task.start += task.repeat;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this.tasks = this.tasks.filter(t => t !== task);
|
|
98
|
+
}
|
|
99
|
+
exports.S_TIMEFRAME_TASK_EXECUTED.invoke(task);
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
console.error(`Task ${task.name} error:`, e);
|
|
103
|
+
task.retries = (task.retries || 0) + 1;
|
|
104
|
+
if (task.retries > (task.maxRetries ?? 0)) {
|
|
105
|
+
console.warn(`Task ${task.name} failed too many times. Dropping.`);
|
|
106
|
+
this.tasks = this.tasks.filter(t => t !== task);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
task.start = Date.now() + this.RETRY_DELAY_MS;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
task.processing = false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async finishService() {
|
|
117
|
+
clearInterval(this.intervalId);
|
|
118
|
+
}
|
|
96
119
|
}
|
|
97
120
|
exports.TimeframeService = TimeframeService;
|
|
@@ -157,6 +157,8 @@ class Validator {
|
|
|
157
157
|
let num = parseInt(object[i]);
|
|
158
158
|
if (object[i].includes("."))
|
|
159
159
|
num = parseFloat(object[i]);
|
|
160
|
+
if (isNaN(num))
|
|
161
|
+
num = structureOptions.default !== undefined ? structureOptions.default : NaN;
|
|
160
162
|
if (isNaN(num))
|
|
161
163
|
errors.push("wrong value for field '" + parentPath + i + "', expected number got " + object[i]);
|
|
162
164
|
else
|
|
@@ -209,6 +211,10 @@ class Validator {
|
|
|
209
211
|
structureOptions.values = structure['$__' + i + "_values"];
|
|
210
212
|
if (Array.isArray(structureOptions.values) && structureOptions.values.length) {
|
|
211
213
|
if (!structureOptions.values.includes(object[i])) {
|
|
214
|
+
if (structureOptions.default && structureOptions.values.includes(structureOptions.default)) {
|
|
215
|
+
object[i] = structureOptions.default;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
212
218
|
let caseValue = null;
|
|
213
219
|
for (let i of structureOptions.values) {
|
|
214
220
|
if (i === null || i === undefined)
|