Rewrite Factorio server shutdown logic

Rewrite shutdown logic for Factorio servers to send a /quit command via
RCON for both Linux and Windows when stopping a server to avoid having
two confusingly intermixed code paths for Windows and Unix systems.
This makes shutdown on Windows tell clients the server shut down instead
of abruptly stoping to respond.
This commit is contained in:
Hornwitser committed 2024-09-14 15:05:13 +02:00
1 parent 36fc2ac1db
commit 7ff06f2b96
6 files changed
+179 -94

No files matched your search

+12 -8
View File
@@ -211,24 +211,28 @@ describe("host/server", function() {
describe(".stop()", function() {
it("should handle server quitting on its own during stop", async function() {
server.hangTimeoutMs = 20;
server.shutdownTimeoutMs = 20;
server._server = new events.EventEmitter();
server._server.kill = () => true;
server._state = "running";
server._rconReady = true;
server._rconReady = false;
server._rconClient = {
async sendRcon() { },
async end() {
server._rconClient = null;
process.nextTick(() => {
server.emit("_quitting");
server._server.emit("exit");
});
},
};
server._watchExit();
await server.stop();
await wait(21); // Wait until after hang timeout
const stop = server.stop();
stop.catch(() => {});
process.nextTick(() => {
server.emit("rcon-ready");
server._server.emit("exit");
});
await stop;
await wait(21); // Wait until after shutdown timeout
});
});
});
+44
View File
@@ -229,7 +229,51 @@ describe("Integration of host/src/server", function() {
server.sendRcon("/c while true do end").catch(() => {});
await new Promise((resolve) => setTimeout(resolve, 300));
log(".stop() for hang detection");
server.shutdownTimeoutMs = 2000;
await server.stop();
server.shutdownTimeoutMs = 0;
});
it("should not hang if RCON fails to connect", async function() {
slowTest(this);
const origWaitForReady = server._waitForReady;
server._waitForReady = () => {
server._waitForReady = origWaitForReady;
server.rconPort -= 1; // Mangle port so it fails to connect.
return server._waitForReady();
};
try {
await server.start("test.zip");
if (server._rconReady) {
assert.fail("Test failed, RCON managed to connect");
}
await assert.rejects(
server.stop(),
{ code: "ECONNREFUSED" }
);
} finally {
if (server._state !== "init") {
await server.kill();
}
}
});
it("should work if RCON has dropped out", async function() {
slowTest(this);
try {
await server.start("test.zip");
if (!server._rconReady) {
await events.once(server, "rcon-ready");
}
await server._rconClient.end();
await server.stop();
} finally {
if (server._state !== "init") {
await server.kill();
}
}
});
});