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.
@@ -97,7 +97,7 @@ async function Initializer(services) {
97
97
  }
98
98
  exports.Initializer = Initializer;
99
99
  class APIService extends BaseService_1.BaseService {
100
- version = "4.0.79";
100
+ version = "4.0.81";
101
101
  options;
102
102
  monitor = null;
103
103
  started = new Date();
@@ -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: any;
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 tack " + req.name);
47
- this.tasks.push(req);
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 (now >= task.start && (!task.executed || task.executed < task.start)) {
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
- try {
65
- (0, LogService_1.logInfo)("Execute task ", task.name);
66
- if (task.callback.length > 0 && task.params)
67
- task.callback(task.params);
68
- else
69
- task.callback();
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "4.0.80",
3
+ "version": "4.0.81",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",