/// <summary> /// Supervises your application and if it exits or crashes it will be automatically restarted. /// NB! This method _MUST_ be invoked after <see cref="ProcessEvents"/>. You can stop the supervisor /// process by invoking <see cref="StopSupervisor"/> before exiting the application. /// </summary> /// <param name="restartArguments"></param> public static bool StartSupervisor(List <string> restartArguments = null) { StopSupervisor(); if (!SnapOs.Filesystem.FileExists(SuperVisorProcessExeDirectory)) { Logger.Error($"Unable to find supervisor executable: {SuperVisorProcessExeDirectory}"); return(false); } var superVisorId = Current.SuperVisorId; var coreRunArgument = $"--corerun-supervise-pid={SnapOs.ProcessManager.Current.Id} --corerun-supervise-id={superVisorId}"; SuperVisorProcess = SnapOs.ProcessManager.StartNonBlocking(new ProcessStartInfoBuilder(SuperVisorProcessExeDirectory) .AddRange(restartArguments ?? new List <string>()) .Add(coreRunArgument) ); SupervisorProcessRestartArguments = restartArguments ?? new List <string>(); Logger.Debug($"Enabled supervision of process with id: {SnapOs.ProcessManager.Current.Id}. Supervisor id: {superVisorId}. " + $"Restart arguments({SupervisorProcessRestartArguments.Count}): {string.Join(",", SupervisorProcessRestartArguments)}. "); SuperVisorProcess.Refresh(); return(!SuperVisorProcess.HasExited); }
public static bool StopSupervisor() { try { if (SuperVisorProcess == null) { return(false); } SuperVisorProcess.Refresh(); var supervisorRunning = !SuperVisorProcess.HasExited; if (!supervisorRunning) { return(false); } if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // ReSharper disable once InconsistentNaming const int SIGTERM = 15; // We have to signal the supervisor so we can release the machine wide semaphore. var killResult = CoreRunLib.NativeMethodsUnix.kill(SuperVisorProcess.Id, SIGTERM); var killSuccess = killResult == 0; if (!killSuccess) { Logger.Warn($"Failed to signal ({nameof(SIGTERM)}) supervisor. Return code: {killResult}."); return(false); } Logger.Info($"Successfully signaled ({nameof(SIGTERM)}) supervisor."); var attempts = 3; while (attempts-- >= 0) { SuperVisorProcess.Refresh(); supervisorRunning = !SuperVisorProcess.HasExited; if (!supervisorRunning) { break; } Thread.Sleep(100); } return(!supervisorRunning); } SuperVisorProcess.Kill(); SuperVisorProcess.Refresh(); supervisorRunning = !SuperVisorProcess.HasExited; return(!supervisorRunning); } catch (Exception e) { Logger.ErrorException($"Exception thrown when killing supervisor process with pid: {SuperVisorProcess?.Id}", e); } SuperVisorProcess = null; return(false); }