Canvas: Auto cleanup old workers
Change-Id: I046ce8dcbadd14b53e465fe0ffb60fae642c6951
diff --git a/apps/canvas/back/src/index.ts b/apps/canvas/back/src/index.ts
index 9628ef5..b6a7098 100644
--- a/apps/canvas/back/src/index.ts
+++ b/apps/canvas/back/src/index.ts
@@ -1274,4 +1274,14 @@
});
}
+function cleanupWorkers() {
+ const now = Date.now();
+ projectMonitors.forEach((monitor) => {
+ monitor.cleanupWorkers(now);
+ });
+ setTimeout(cleanupWorkers, 1000);
+}
+
+setTimeout(cleanupWorkers, 1000);
+
start();
diff --git a/apps/canvas/back/src/project_monitor.ts b/apps/canvas/back/src/project_monitor.ts
index 7dd2f3c..342a3f3 100644
--- a/apps/canvas/back/src/project_monitor.ts
+++ b/apps/canvas/back/src/project_monitor.ts
@@ -47,8 +47,8 @@
class ServiceMonitor {
private workers: Map<string, string> = new Map();
- private logs: Map<string, LogItem[]> = new Map();
private statuses: Map<string, Worker["status"]> = new Map();
+ private lastPings: Map<string, number> = new Map();
constructor(public readonly serviceName: string) {}
@@ -57,24 +57,17 @@
if (workerStatus) {
this.statuses.set(workerId, workerStatus);
}
+ this.lastPings.set(workerId, Date.now());
}
getWorkerAddress(workerId: string): string | undefined {
return this.workers.get(workerId);
}
- getWorkerLog(workerId: string): LogItem[] | undefined {
- return this.logs.get(workerId);
- }
-
getWorkerStatus(workerId: string): Worker["status"] | undefined {
return this.statuses.get(workerId);
}
- getAllLogs(): Map<string, LogItem[]> {
- return new Map(this.logs);
- }
-
getAllStatuses(): Map<string, Worker["status"]> {
return new Map(this.statuses);
}
@@ -87,10 +80,6 @@
return Array.from(this.workers.keys());
}
- hasLogs(): boolean {
- return this.logs.size > 0;
- }
-
async reloadWorker(workerId: string): Promise<void> {
const workerAddress = this.workers.get(workerId);
if (!workerAddress) {
@@ -126,6 +115,20 @@
throw error; // Re-throw to be caught by ProjectMonitor
}
}
+
+ cleanupWorkers(now: number) {
+ const toDelete: string[] = [];
+ this.workers.forEach((_, workerId) => {
+ if (now - (this.lastPings.get(workerId) ?? 0) > 1000 * 60) {
+ toDelete.push(workerId);
+ }
+ });
+ for (const workerId of toDelete) {
+ this.workers.delete(workerId);
+ this.statuses.delete(workerId);
+ this.lastPings.delete(workerId);
+ }
+ }
}
export class ProjectMonitor {
@@ -150,27 +153,10 @@
return Array.from(new Set(allAddresses));
}
- getWorkerLog(serviceName: string, workerId: string): LogItem[] | undefined {
- const serviceMonitor = this.serviceMonitors.get(serviceName);
- if (serviceMonitor) {
- return serviceMonitor.getWorkerLog(workerId);
- }
- return undefined;
- }
-
getAllServiceNames(): string[] {
return Array.from(this.serviceMonitors.keys());
}
- hasLogs(): boolean {
- for (const serviceMonitor of this.serviceMonitors.values()) {
- if (serviceMonitor.hasLogs()) {
- return true;
- }
- }
- return false;
- }
-
getServiceMonitor(serviceName: string): ServiceMonitor | undefined {
return this.serviceMonitors.get(serviceName);
}
@@ -198,4 +184,10 @@
}
await serviceMonitor.terminateWorker(workerId);
}
+
+ cleanupWorkers(now: number) {
+ this.serviceMonitors.forEach((serviceMonitor) => {
+ serviceMonitor.cleanupWorkers(now);
+ });
+ }
}