From d2d9c8516cf8e12663b93d3dfbfbc7ed14aaad2b Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Sat, 21 Oct 2017 16:47:53 -0400 Subject: [PATCH] Documents the watchdog --- TGServerService/ServerInstance/DreamDaemon.cs | 128 ++++++++++++++---- 1 file changed, 102 insertions(+), 26 deletions(-) diff --git a/TGServerService/ServerInstance/DreamDaemon.cs b/TGServerService/ServerInstance/DreamDaemon.cs index ad7ba5f673..d84400edc1 100644 --- a/TGServerService/ServerInstance/DreamDaemon.cs +++ b/TGServerService/ServerInstance/DreamDaemon.cs @@ -10,7 +10,7 @@ using TGServiceInterface.Components; namespace TGServerService { //manages the dd window. - //It's not possible to actually click it while starting it in CL mode, so in order to change visibility etc. It restarts the process when the round ends + //It's not possible to actually click it while starting it in CL mode, so in order to change visibility, security, etc. It restarts the process when the world reboots sealed partial class ServerInstance : ITGDreamDaemon { enum ShutdownRequestPhase @@ -20,29 +20,79 @@ namespace TGServerService Pinged, } + /// + /// Directory for storing DreamDaemon diagnostic files + /// const string DiagnosticsDir = "Diagnostics"; + /// + /// Directory for storing DreamDaemon ResourceUsage files + /// const string ResourceDiagnosticsDir = DiagnosticsDir + "/Resources"; + /// + /// Time until DD is considered DOA on startup + /// const int DDHangStartTime = 60; + /// + /// If DreamDaemon crashes before this time it is considered a bad startup + /// const int DDBadStartTime = 10; + /// + /// The DreamDaemon process + /// Process Proc; + /// + /// CPU performance information for + /// PerformanceCounter pcpu; + /// + /// Used for multithreading safety + /// object watchdogLock = new object(); + /// + /// The thread that monitors the status of DreamDaemon + /// Thread DDWatchdog; + /// + /// The of + /// DreamDaemonStatus currentStatus; + /// + /// Current logfile in use in + /// string CurrentDDLog; + /// + /// Current port DreamDaemon is running on + /// ushort currentPort = 0; + /// + /// Used for multithreading safety + /// object restartLock = new object(); + /// + /// Used to indicate if an intentional restart is in progress on the watchdog. Requires to access + /// bool RestartInProgress = false; + /// + /// Used to indicate if an service restart is in progress on the watchdog. Requires to access + /// bool ReattachInsteadOfRestart = false; + /// + /// Current level of DreamDaemon + /// DreamDaemonSecurity StartingSecurity; + /// + /// Indicator of progress on a or operation + /// ShutdownRequestPhase AwaitingShutdown; - //Only need 1 proc instance + /// + /// Setup or reattach the watchdog, depending on , and create the + /// void InitDreamDaemon() { Directory.CreateDirectory(DiagnosticsDir); @@ -62,8 +112,11 @@ namespace TGServerService }); //start wd - RestartInProgress = true; - ReattachInsteadOfRestart = true; + lock (restartLock) + { + RestartInProgress = true; + ReattachInsteadOfRestart = true; + } currentPort = Properties.Settings.Default.ReattachPort; serviceCommsKey = Properties.Settings.Default.ReattachCommsKey; try @@ -100,7 +153,9 @@ namespace TGServerService ThreadPool.QueueUserWorkItem( _ => { Start(); }); } - //die now k thx + /// + /// Either let go of for reattachment or terminate it, depending on + /// void DisposeDreamDaemon() { var Detach = Properties.Settings.Default.ReattachToDD; @@ -227,6 +282,10 @@ namespace TGServerService return res; } + /// + /// Write a to the . A timestamp will be prepended to it + /// + /// The message to log void WriteCurrentDDLog(string message) { lock (watchdogLock) @@ -237,7 +296,9 @@ namespace TGServerService } } - //loop that keeps the server running + /// + /// Threaded loop that keeps DreamDaemon from unintentionally stopping + /// void Watchdog() { try @@ -339,7 +400,10 @@ namespace TGServerService Properties.Settings.Default.ReattachPID = Proc.Id; Properties.Settings.Default.ReattachPort = currentPort; Properties.Settings.Default.ReattachCommsKey = serviceCommsKey; - RestartInProgress = true; + lock (restartLock) + { + RestartInProgress = true; + } } Proc.Close(); } @@ -358,18 +422,26 @@ namespace TGServerService currentStatus = DreamDaemonStatus.Offline; currentPort = 0; AwaitingShutdown = ShutdownRequestPhase.None; - if (!RestartInProgress) + lock (restartLock) { - if(!Properties.Settings.Default.ReattachToDD) - SendMessage("DD: Server stopped, watchdog exiting...", MessageType.WatchdogInfo); - Service.WriteInfo("Watch dog exited", EventID.DDWatchdogExit); + if (!RestartInProgress) + { + if (!Properties.Settings.Default.ReattachToDD) + SendMessage("DD: Server stopped, watchdog exiting...", MessageType.WatchdogInfo); + Service.WriteInfo("Watch dog exited", EventID.DDWatchdogExit); + } + else + Service.WriteInfo("Watch dog restarting...", EventID.DDWatchdogRestart); } - else - Service.WriteInfo("Watch dog restarting...", EventID.DDWatchdogRestart); } } } + /// + /// Called every five seconds while DreamDaemon is running to log it's current state to the + /// + /// The event sender, an instance of + /// The private void MemTrackTimer_Elapsed(object sender, ElapsedEventArgs e) { ulong megamem; @@ -386,14 +458,6 @@ namespace TGServerService /// public string CanStart() - { - lock (watchdogLock) - { - return CanStartImpl(); - } - } - - string CanStartImpl() { if (GetVersion(ByondVersion.Installed) == null) return "Byond is not installed!"; @@ -416,7 +480,7 @@ namespace TGServerService { if (currentStatus != DreamDaemonStatus.Offline) return "Server already running"; - var res = CanStartImpl(); + var res = CanStart(); if (res != null) return res; currentPort = 0; @@ -424,8 +488,12 @@ namespace TGServerService } return StartImpl(false); } - - //translate the configured security level into a byond param + + /// + /// Translate the configured level into a byond command line param + /// + /// If bases it's result on , uses otherwise + /// "safe", "trusted", or "ultrasafe" depending on the it checks string SecurityWord(bool starting = false) { var level = starting ? StartingSecurity : (DreamDaemonSecurity)Properties.Settings.Default.ServerSecurity; @@ -442,6 +510,10 @@ namespace TGServerService } } + /// + /// Copies from the program directory to the the directory + /// + /// If , overwrites the 's current interface .dll if it exists void UpdateInterfaceDll(bool overwrite) { if (File.Exists(InterfaceDLLName) && !overwrite) @@ -451,14 +523,18 @@ namespace TGServerService File.Copy(InterfacePath, InterfaceDLLName, overwrite); } - //used by Start and Watchdog to start a DD instance + /// + /// Clears the current , calls with a parameter, and attempts to start the DreamDaemon + /// + /// If , sets to a new pointing to and starts it + /// on success, error message on failure string StartImpl(bool watchdog) { try { lock (watchdogLock) { - var res = CanStartImpl(); + var res = CanStart(); if (res != null) return res;