feat: optional restart exit code so a supervisor owns the relaunch (#2705)
Fixes #2700 (with #2704) A restart (`restart` console command, `AutoRestart`, `CrashGuard`) launches a copy of the server and exits. That copy is detached from the console it was started from: the shell takes the terminal back and console commands stop working. Under systemd or in a container it's killed as soon as the original process exits. - New setting `server.restartExitCode` (off by default). When it's set, a restart saves and shuts down as usual and then exits with that code, so a shell loop, systemd unit or container restart policy can start the server again on the same console. Values outside 1–255 log a warning and fall back to the current behaviour. - Fixes `CrashGuard` crash recovery never restarting the server. Since #1809, `Kill()` only records the request, and the unhandled-exception path called `DoKill()` without it. - Documents systemd, Docker and shell-loop setups in `dev-docs/server-requirements.md`.
This commit is contained in:
parent
577a4da60c
commit
eff9de0281
3 changed files with 55 additions and 2 deletions
|
|
@ -45,6 +45,10 @@ public static class Core
|
|||
private static volatile bool _performSnapshot;
|
||||
private static string _snapshotPath;
|
||||
|
||||
// 0 = relaunch in-process. Otherwise a restart exits with this code and leaves the relaunch to a
|
||||
// supervisor; a spawned child loses the console and dies with a systemd unit or container.
|
||||
private static int _restartExitCode;
|
||||
|
||||
// A backstop, not a latency control: the wheel's tick rate already bounds the sleep.
|
||||
// Measured across 1/2/4/8ms; 2 is optimal.
|
||||
private static int _eventLoopIdleWaitMs = 2;
|
||||
|
|
@ -434,7 +438,7 @@ public static class Core
|
|||
ConsoleInputHandler.ReadLine();
|
||||
}
|
||||
|
||||
DoKill();
|
||||
DoKill(_restartOnKill);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -468,6 +472,12 @@ public static class Core
|
|||
|
||||
HandleClosed();
|
||||
|
||||
if (restart && _restartExitCode != 0)
|
||||
{
|
||||
logger.Information("Restarting (exiting with code {ExitCode} for the supervisor)", _restartExitCode);
|
||||
Environment.Exit(_restartExitCode);
|
||||
}
|
||||
|
||||
if (restart)
|
||||
{
|
||||
try
|
||||
|
|
@ -625,6 +635,19 @@ public static class Core
|
|||
|
||||
_lateWakePercent = Math.Clamp(lateWakePercent, 0, 100);
|
||||
|
||||
// Unix truncates exit codes to a byte, so anything outside 1-255 cannot be told apart reliably.
|
||||
var restartExitCode = ServerConfiguration.GetSetting("server.restartExitCode", 0);
|
||||
if (restartExitCode is < 0 or > 255)
|
||||
{
|
||||
logger.Warning(
|
||||
"server.restartExitCode {Value} is outside 1-255; restarts will relaunch the server directly",
|
||||
restartExitCode
|
||||
);
|
||||
restartExitCode = 0;
|
||||
}
|
||||
|
||||
_restartExitCode = restartExitCode;
|
||||
|
||||
var assemblyPath = Path.Join(BaseDirectory, AssembliesConfiguration);
|
||||
|
||||
// Load UOContent.dll
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace Server.Misc
|
|||
|
||||
private static bool Enabled;
|
||||
private static bool SaveBackup;
|
||||
private static bool RestartServer; // Disable this if using a daemon/service
|
||||
private static bool RestartServer; // Under a daemon/service, set server.restartExitCode rather than disabling this
|
||||
private static bool GenerateReport;
|
||||
|
||||
public static void Configure()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue