badmfck-api-server 4.0.80 → 4.0.81
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;
|