diff --git a/packages/controller/src/Controller.ts b/packages/controller/src/Controller.ts index 4c767d9c..20e5148d 100644 --- a/packages/controller/src/Controller.ts +++ b/packages/controller/src/Controller.ts @@ -198,6 +198,7 @@ export default class Controller { this.subscriptions.handle(lib.UserUpdatesEvent, this.handleUserSubscription.bind(this)); // Handle updates for datastores + this.systems.on("update", this.systemsUpdated.bind(this)); this.hosts.on("update", this.hostsUpdated.bind(this)); this.instances.on("update", this.instanceDetailsUpdated.bind(this)); this.saves.on("update", this.savesUpdated.bind(this)); @@ -520,7 +521,6 @@ export default class Controller { for (const metric of newMetrics) { this.systems.set(metric); } - this.subscriptions.broadcast(new lib.SystemInfoUpdateEvent(newMetrics)); } catch (err: any) { logger.error(`Unexpected error updating system infos:\n${err.stack ?? err.message}`); } @@ -561,16 +561,16 @@ export default class Controller { await lib.safeOutputFile(this.configPath, JSON.stringify(this.config, null, "\t")); } - let databaseDirectory = this.config.get("controller.database_directory"); - - await this.systems.save(); - await this.hosts.save(); - await this.instances.save(); - await this.saves.save(); - await this.modPacks.save(); + await Promise.all([ + this.systems.save(), + this.hosts.save(), + this.instances.save(), + this.saves.save(), + this.modPacks.save(), + ]); if (this.userManager.dirty) { - await this.userManager.save(path.join(databaseDirectory, "users.json")); + await this.userManager.save(path.join(this.config.get("controller.database_directory"), "users.json")); } await lib.invokeHook(this.plugins, "onSaveData"); @@ -708,6 +708,10 @@ export default class Controller { } } + systemsUpdated(systems: lib.SystemInfo[]) { + this.subscriptions.broadcast(new lib.SystemInfoUpdateEvent(systems)); + } + async handleSystemInfoSubscription(request: lib.SubscriptionRequest) { const systems = [...this.systems.values()].filter( metric => metric.updatedAtMs > request.lastRequestTimeMs, diff --git a/packages/controller/src/HostConnection.ts b/packages/controller/src/HostConnection.ts index 7d31d979..71c72e2a 100644 --- a/packages/controller/src/HostConnection.ts +++ b/packages/controller/src/HostConnection.ts @@ -288,13 +288,9 @@ export default class HostConnection extends BaseConnection { } } // Hosts eagerly send updates, which means we may get an update - // where nothing actualy changed. - if (updates.length) { - this._controller.saves.setMany(updates); - } - if (deletes.length) { - this._controller.saves.deleteMany(deletes); - } + // where nothing actually changed. + this._controller.saves.setMany(updates); + this._controller.saves.deleteMany(deletes); } async handleLogMessageEvent(event: lib.LogMessageEvent) { diff --git a/packages/lib/src/datastore.ts b/packages/lib/src/datastore.ts index 3624efee..d03b85ac 100644 --- a/packages/lib/src/datastore.ts +++ b/packages/lib/src/datastore.ts @@ -3,6 +3,8 @@ import fs from "fs-extra"; import { safeOutputFile } from "./file_ops"; import { SubscribableValue } from "./subscriptions"; import { EventEmitter } from "stream"; +import { ControllerConfig } from "./config"; +import path from "path"; type DatastoreKey = string | number; type DatastoreValue = string | number | boolean | object; @@ -133,6 +135,11 @@ export abstract class BaseDatastore< super(); } + // Get the file path based on the controller config + static getFilePath(config: ControllerConfig, file: string) { + return path.resolve(config.get("controller.database_directory"), file); + } + // Save the datastore to the provider async save() { if (this.dirty) { @@ -220,7 +227,6 @@ export class Datastore< } // A special implementation of the datastore to work directly with subscribable values -// TODO broadcast value changes to subscribers export class SubscribableDatastore< V extends SubscribableValue, > extends BaseDatastore {