From 9c9adf7c8e01055ee1af8870262711cfe227a867 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 15 Aug 2023 17:58:33 +0200 Subject: [PATCH 1/4] Use return type deduction for timers Fix updates to Node.js timers types breaking the TypeScript build by deducing the correct type from the return type of the setTimeout/setInterval functions. --- packages/controller/src/Controller.ts | 2 +- packages/controller/src/WsServerConnector.ts | 2 +- packages/controller/src/routes.ts | 2 +- packages/lib/src/RateLimiter.ts | 2 +- packages/lib/src/helpers.ts | 2 +- packages/lib/src/link/connectors.ts | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/controller/src/Controller.ts b/packages/controller/src/Controller.ts index 09f79563..c3ee42a0 100644 --- a/packages/controller/src/Controller.ts +++ b/packages/controller/src/Controller.ts @@ -87,7 +87,7 @@ export default class Controller { logDirectory: string = ""; clusterLogIndex: lib.LogIndex | null = null; - clusterLogBuildInterval: NodeJS.Timer | null = null; + clusterLogBuildInterval: ReturnType | null = null; constructor( clusterLogger: winston.Logger, diff --git a/packages/controller/src/WsServerConnector.ts b/packages/controller/src/WsServerConnector.ts index 5776f93a..578e7568 100644 --- a/packages/controller/src/WsServerConnector.ts +++ b/packages/controller/src/WsServerConnector.ts @@ -17,7 +17,7 @@ export interface WebSocketClusterio extends WebSocket { * @alias module:controller/src/WsServerConnector */ export default class WsServerConnector extends lib.WebSocketBaseConnector { - _timeoutId: NodeJS.Timeout | null = null; + _timeoutId: ReturnType | null = null; declare _socket: WebSocketClusterio | null; constructor( diff --git a/packages/controller/src/routes.ts b/packages/controller/src/routes.ts index 5a1de286..084b0817 100644 --- a/packages/controller/src/routes.ts +++ b/packages/controller/src/routes.ts @@ -255,7 +255,7 @@ interface ProxyStream { mime: string | null; filename: string | null; events: events.EventEmitter; - timeout: NodeJS.Timeout; + timeout: ReturnType; } export async function createProxyStream(app: Application): Promise { diff --git a/packages/lib/src/RateLimiter.ts b/packages/lib/src/RateLimiter.ts index 24390c6b..16271d0f 100644 --- a/packages/lib/src/RateLimiter.ts +++ b/packages/lib/src/RateLimiter.ts @@ -30,7 +30,7 @@ export default class RateLimiter { action?: Function; private _lastRun = 0; - private _runTimeout?: NodeJS.Timeout; + private _runTimeout?: ReturnType; /** * Construct RateLimiter helper diff --git a/packages/lib/src/helpers.ts b/packages/lib/src/helpers.ts index 31afdabc..37c41e51 100644 --- a/packages/lib/src/helpers.ts +++ b/packages/lib/src/helpers.ts @@ -37,7 +37,7 @@ export async function wait(duration: number) { * @param {*=} timeoutResult - Value to return if the operation timed out. */ export async function timeout(promise: Promise, time: number, timeoutResult: T) { - let timer: NodeJS.Timer | undefined; + let timer: ReturnType | undefined; try { return await Promise.race([ promise, diff --git a/packages/lib/src/link/connectors.ts b/packages/lib/src/link/connectors.ts index 203f9c48..742b5c30 100644 --- a/packages/lib/src/link/connectors.ts +++ b/packages/lib/src/link/connectors.ts @@ -99,7 +99,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector { _closing = false; _socket: WebSocket | null = null; _lastHeartbeat: number | null = null; - _heartbeatId: NodeJS.Timer | null = null; + _heartbeatId: ReturnType | null = null; _heartbeatInterval: number | null = null; _lastReceivedSeq = undefined; _sendBuffer: (ReliableMessages)[] = []; @@ -287,7 +287,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector { this.setClosing(); this._sendInternal(new libData.MessageDisconnect("prepare")); - let timeout: NodeJS.Timeout | undefined; + let timeout: ReturnType | undefined; let waitTimeout = new Promise(resolve => { timeout = setTimeout(resolve, 10000); }); // Make Configurable? try { await Promise.race([ @@ -331,7 +331,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector { * @extends module:lib.WebSocketBaseConnector */ export abstract class WebSocketClientConnector extends WebSocketBaseConnector { - _reconnectId?: NodeJS.Timeout; + _reconnectId?: ReturnType; _sessionToken: string | null = null; _sessionTimeout: number | null = null; _startedResuming: number | null = null; From 8bf5296fe6f0fd8679c6ed971749cb1f9b1b4034 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 15 Aug 2023 18:00:43 +0200 Subject: [PATCH 2/4] Gracefully handle error linking mods on Windows --- packages/host/src/Instance.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/host/src/Instance.js b/packages/host/src/Instance.js index 132873fc..add7aceb 100644 --- a/packages/host/src/Instance.js +++ b/packages/host/src/Instance.js @@ -662,7 +662,11 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " "); // not something we want to have. For this reason the mods // are hard linked instead. } else { - await fs.link(target, link); + try { + await fs.link(target, link); + } catch (err) { + this.logger.warn(`Failed to link mod ${modFile}.`); + } } } From 115cb3fd5d5c2c1ebab762d33f128fbb43d7c1ea Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 15 Aug 2023 18:15:10 +0200 Subject: [PATCH 3/4] Fix path slash issue in plugin loader test On Windows require paths use a mix of forward and backward slashes due to require path possibly being a package path which can't have backward slashes, or a Windows file path which can have have either. Fix plugin loader test failing on Windows due to not using the same combination of forward and backward slashes for require file paths. --- test/lib/plugin_loader.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/lib/plugin_loader.js b/test/lib/plugin_loader.js index 6e2e1348..5632e17d 100644 --- a/test/lib/plugin_loader.js +++ b/test/lib/plugin_loader.js @@ -79,30 +79,32 @@ describe("lib/plugin_loader", function() { ); }); it("should throw if class is missing from entrypoint", async function() { + const requirePath = path.resolve(missingClass); await assert.rejects( lib.loadControllerPluginClass({ name: "test", controllerEntrypoint: "controller", - requirePath: path.resolve(missingClass), + requirePath, }), { message: - `PluginError: Expected ${path.resolve(missingClass, "controller")} ` + + `PluginError: Expected ${path.posix.join(requirePath, "controller")} ` + "to export a class named ControllerPlugin", } ); }); it("should throw if class is not a subclass of BaseControllerPlugin", async function() { + const requirePath = path.resolve(wrongParentClass); await assert.rejects( lib.loadControllerPluginClass({ name: "test", controllerEntrypoint: "controller", - requirePath: path.resolve(wrongParentClass), + requirePath, }), { message: "PluginError: Expected ControllerPlugin exported from " + - `${path.resolve(wrongParentClass, "controller")} to be a subclass of BaseControllerPlugin`, + `${path.posix.join(requirePath, "controller")} to be a subclass of BaseControllerPlugin`, } ); }); From 47375ec07597addcbc32f48ec9a08679a896fe1c Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 15 Aug 2023 18:35:23 +0200 Subject: [PATCH 4/4] Skip unknown instance status check on Windows The unknown status happens when an instance is on a host that has disconnected, but since alt-host is not spawned in the tests on Windows this status is not observed. --- test/integration/clusterio.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/integration/clusterio.js b/test/integration/clusterio.js index 864a432f..6ac2a57d 100644 --- a/test/integration/clusterio.js +++ b/test/integration/clusterio.js @@ -788,9 +788,13 @@ describe("Integration of Clusterio", function() { it("should have triggered for the previous instance status updates", function() { slowTest(this); let statusesToCheck = new Set([ - "unassigned", "unknown", "stopped", "creating_save", "exporting_data", + "unassigned", "stopped", "creating_save", "exporting_data", "starting", "running", "stopping", "deleted", ]); + // Windows does not see the unknown status because alt-host is not spawned. + if (process.platform !== "win32") { + statusesToCheck.add("unknown"); + } let statusesNotSeen = new Set(statusesToCheck); for (let update of getControl().instanceUpdates) {