diff --git a/lib/factorio/server.js b/lib/factorio/server.js index d2934d9f..0a765ddc 100644 --- a/lib/factorio/server.js +++ b/lib/factorio/server.js @@ -419,7 +419,7 @@ const outputHeuristics = [ * output - invoked with parsed output from Factorio * rcon-ready - invoked when the RCON client has connected * game-ready - invoked when the server is finished starting up - * stopped - invoked when the sterver has exited + * exit - invoked when the sterver has exited */ class FactorioServer extends events.EventEmitter { /** @@ -636,7 +636,7 @@ class FactorioServer extends events.EventEmitter { this._gameReady = false; this._unexpected = []; - this.emit('stopped'); + this.emit("exit"); }); } @@ -678,6 +678,7 @@ class FactorioServer extends events.EventEmitter { ); this._attachStdio(); + this._server.once("exit", () => this.emit("exit")); try { let [code, signal] = await events.once(this._server, 'exit'); diff --git a/lib/link/messages.js b/lib/link/messages.js index 9108cffb..05305053 100644 --- a/lib/link/messages.js +++ b/lib/link/messages.js @@ -484,6 +484,11 @@ class Event { } } +messages.instanceStopped = new Event({ + type: 'instance_stopped', + links: ['instance-slave'], +}); + messages.updateInstances = new Event({ type: 'update_instances', links: ['slave-master'], diff --git a/lib/plugin.js b/lib/plugin.js index 3f88d499..abd97ad6 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -72,9 +72,9 @@ class BaseInstancePlugin { async onStop() { } /** - * Called when the instance is shutting down + * Called when the Factorio server exited */ - async onExit() { } + onExit() { } /** * Called when the Factorio outputs a line diff --git a/plugins/subspace_storage/instance.js b/plugins/subspace_storage/instance.js index c4e38269..b0d40ab1 100644 --- a/plugins/subspace_storage/instance.js +++ b/plugins/subspace_storage/instance.js @@ -32,7 +32,7 @@ class InstancePlugin extends plugin.BaseInstancePlugin { await this.instance.server.sendRcon(`/sc __subspace_storage__ UpdateInvData("${itemsJson}", true)`, true); } - async onStop() { + onExit() { clearInterval(this.pingId); } diff --git a/slave.js b/slave.js index a18575be..8b748680 100644 --- a/slave.js +++ b/slave.js @@ -60,6 +60,19 @@ class Instance extends link.Link{ }); } }); + + this.server.on("error", err => { + console.log(`Error in instance ${this.name}:`, err); + }); + + this.server.on("exit", err => { + link.messages.instanceStopped.send(this); + + // Notify plugins of exit + for (let pluginInstance of this.plugins.values()) { + pluginInstance.onExit(); + } + }); } async init(pluginInfos, slave) { @@ -250,11 +263,6 @@ class Instance extends link.Link{ collector.removeAll({ instance_id: String(this.config.get("instance.id")) }); } } - - // Notify plugins of exit - for (let pluginInstance of this.plugins.values()) { - await pluginInstance.onExit(); - } } async getMetricsRequestHandler() { @@ -294,11 +302,6 @@ class Instance extends link.Link{ await this.server.create("world"); console.log("Clusterio | Successfully created save"); - - // Notify plugins of exit - for (let pluginInstance of this.plugins.values()) { - await pluginInstance.onExit(); - } } async stopInstanceRequestHandler() { @@ -373,9 +376,10 @@ async function discoverInstances(instancesDir, logger) { } class InstanceConnection extends link.Link { - constructor(connector, slave) { + constructor(connector, slave, instanceId) { super('slave', 'instance', connector); this.slave = slave; + this.instanceId = instanceId; link.attachAllMessages(this); for (let pluginInfo of slave.pluginInfos) { @@ -413,6 +417,10 @@ class InstanceConnection extends link.Link { event.send(instanceConnection, message.data); } } + + async instanceStoppedEventHandler(message) { + this.slave.instanceConnections.delete(this.instanceId); + } } class SlaveConnector extends link.WebSocketClientConnector { @@ -552,7 +560,7 @@ class Slave extends link.Link { } let [connectionClient, connectionServer] = link.VirtualConnector.makePair(); - let instanceConnection = new InstanceConnection(connectionServer, this); + let instanceConnection = new InstanceConnection(connectionServer, this, instanceId); let instance = new Instance( connectionClient, instanceInfo.path, this.config.get("slave.factorio_directory"), instanceInfo.config ); @@ -604,25 +612,12 @@ class Slave extends link.Link { async createSaveRequestHandler(message, request) { let instanceId = message.data.instance_id; let instanceConnection = await this._connectInstance(instanceId); - try { - await request.send(instanceConnection, message.data); - this.instanceConnections.delete(instanceId); - - } catch (err) { - await this.stopInstance(instanceId); - throw err; - } + await request.send(instanceConnection, message.data); } async stopInstance(instanceId) { let instanceConnection = this.instanceConnections.get(instanceId); await link.messages.stopInstance.send(instanceConnection, { instance_id: instanceId }); - this.instanceConnections.delete(instanceId); - } - - async stopInstanceRequestHandler(message, request) { - await this.forwardRequestToInstance(message, request); - this.instanceConnections.delete(message.data.instance_id); } async deleteInstanceRequestHandler(message) { diff --git a/test/lib/plugin.js b/test/lib/plugin.js index 632708b4..4072aebf 100644 --- a/test/lib/plugin.js +++ b/test/lib/plugin.js @@ -18,7 +18,7 @@ describe("lib/plugin", function() { it("should define defaults for hooks", async function() { await instancePlugin.onStart(); await instancePlugin.onStop(); - await instancePlugin.onExit(); + instancePlugin.onExit(); await instancePlugin.onOutput({}); }) });