namespace Dada.Supervisor; internal enum SupervisorState { Starting, Ready, StartupFailed, PortInUse, ApiDegraded, WorkerDegraded, StorageFull, StorageUnavailable, DiagnosticsRunning, DiagnosticsReady, } internal enum SupervisorAction { OpenProduct, OpenChrome, OpenEdge, OpenDiagnostics, CheckExistingInstance, Retry, RestartServices, Exit, } internal static class SupervisorActions { internal static IReadOnlyList For(SupervisorState state) => state switch { SupervisorState.Starting => [SupervisorAction.OpenDiagnostics, SupervisorAction.Exit], SupervisorState.Ready => [SupervisorAction.OpenProduct, SupervisorAction.OpenChrome, SupervisorAction.OpenEdge, SupervisorAction.OpenDiagnostics, SupervisorAction.RestartServices, SupervisorAction.Exit], SupervisorState.StartupFailed => [SupervisorAction.Retry, SupervisorAction.OpenDiagnostics, SupervisorAction.Exit], SupervisorState.PortInUse => [SupervisorAction.CheckExistingInstance, SupervisorAction.Retry, SupervisorAction.OpenDiagnostics, SupervisorAction.Exit], SupervisorState.ApiDegraded => [SupervisorAction.OpenDiagnostics, SupervisorAction.RestartServices, SupervisorAction.Exit], SupervisorState.WorkerDegraded => [SupervisorAction.OpenProduct, SupervisorAction.OpenChrome, SupervisorAction.OpenEdge, SupervisorAction.OpenDiagnostics, SupervisorAction.RestartServices, SupervisorAction.Exit], SupervisorState.StorageFull => [SupervisorAction.OpenProduct, SupervisorAction.OpenChrome, SupervisorAction.OpenEdge, SupervisorAction.OpenDiagnostics, SupervisorAction.Exit], SupervisorState.StorageUnavailable => [SupervisorAction.Retry, SupervisorAction.OpenDiagnostics, SupervisorAction.Exit], SupervisorState.DiagnosticsRunning => [SupervisorAction.Exit], SupervisorState.DiagnosticsReady => [SupervisorAction.OpenDiagnostics, SupervisorAction.Exit], _ => throw new ArgumentOutOfRangeException(nameof(state)), }; } internal static class RestartPolicy { internal const int MaximumRestarts = 3; internal static readonly IReadOnlyList Delays = [TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15)]; internal static bool CanRestart(int completedRestarts, TimeSpan failureWindow) => completedRestarts < MaximumRestarts && failureWindow <= TimeSpan.FromMinutes(5); }