ソースを参照

Server: Timer optimiert - gleichzeitige Jobs queuen und awaiten

Christian Kahlau 3 年 前
コミット
9daef9efd0

+ 1 - 1
server/src/ctrl/database.class.ts

@@ -310,7 +310,7 @@ export class Database extends SQLiteController {
 
         const res = await this.stmt('SELECT * FROM HealthCheckParams WHERE ConfigID = ? and Key = "check";', [conf.id]);
         updValues = [];
-        const delIDs: any[][] = [];
+        const delIDs: number[] = [];
         res.rows.forEach((row, i) => {
           if (i < conf.checks.length) {
             updValues.push([conf.checks[i], row['ID']]);

+ 1 - 1
server/src/ctrl/server-connector.class.ts

@@ -18,7 +18,7 @@ export class ServerConnector {
 
           const interval = Number(server.config['syncInterval'] ?? '300');
           Logger.info('[INFO] Starting Server Sync Connector for', server.title, 'with interval', interval, 'seconds ...');
-          const id = Timer.instance.subscribe(interval, () => this.timerTick(server, serverDB));
+          const id = Timer.instance.subscribe(interval, async () => await this.timerTick(server, serverDB));
           this.subscriptions.push({ id, interval, server });
 
           process.nextTick(async () => {

+ 28 - 12
server/src/timer.class.ts

@@ -1,13 +1,10 @@
-export class Timer {
-  private intervalHdl?: NodeJS.Timer;
-  private subscribers: {
-    [id: number]: {
-      lastTick: number;
-      seconds: number;
-      tick: () => void;
-    };
-  } = {};
+type Subscriber = {
+  lastTick: number;
+  seconds: number;
+  tick: (() => void) | Promise<void>;
+};
 
+export class Timer {
   private static INSTANCE?: Timer;
   public static get instance(): Timer {
     if (!Timer.INSTANCE) {
@@ -16,6 +13,12 @@ export class Timer {
     return Timer.INSTANCE;
   }
 
+  private intervalHdl?: NodeJS.Timer;
+  private subscribers: {
+    [id: number]: Subscriber;
+  } = {};
+  private queue: Subscriber[] = [];
+
   private constructor() {}
 
   public start() {
@@ -29,13 +32,26 @@ export class Timer {
     const now = new Date();
     Object.values(this.subscribers).forEach(sub => {
       if (now.getTime() >= sub.lastTick + sub.seconds * 1000) {
-        sub.lastTick = now.getTime();
-        sub.tick();
+        this.queue.push(sub);
       }
     });
+    this.processQueue();
+  }
+
+  private async processQueue() {
+    while (this.queue.length > 0) {
+      const now = new Date();
+      const sub = this.queue.shift() as Subscriber;
+      sub.lastTick = now.getTime();
+      if (typeof sub.tick === 'function') {
+        sub.tick();
+      } else {
+        await sub.tick;
+      }
+    }
   }
 
-  public subscribe(seconds: number, tick: () => void) {
+  public subscribe(seconds: number, tick: (() => void) | Promise<void>) {
     const lastTick = new Date().getTime();
     const id =
       Object.keys(this.subscribers)