Class DaemonOrchestrator
- Namespace
- AppHealthMonitor
- Assembly
- AppHealthMonitor.dll
Orchestrates the lifecycle of application health monitors. Owns daemon-wide state (cancellation, start signal, active monitors) and pre-validates configurations at construction time.
public sealed class DaemonOrchestrator : IAsyncDisposable
- Inheritance
-
DaemonOrchestrator
- Implements
- Inherited Members
Constructors
DaemonOrchestrator(IReadOnlyList<AppConfig>, bool)
Initializes a new instance of the DaemonOrchestrator class. Applies defaults, validates, detects duplicate names, creates health checkers, and logs configuration for each app in a single pass.
public DaemonOrchestrator(IReadOnlyList<AppConfig> appConfigs, bool headless)
Parameters
appConfigsIReadOnlyList<AppConfig>The raw application configurations from settings.
headlessboolWhether all monitored applications should be launched in headless mode.
Exceptions
- InvalidOperationException
Thrown when no application configurations are provided, a configuration entry is invalid, or duplicate application names are detected.
Properties
DaemonShutdownToken
Gets the cancellation token that is signalled when the daemon is shutting down. Used by CommandHandler for cancellable I/O operations.
public CancellationToken DaemonShutdownToken { get; }
Property Value
Headless
Gets whether all monitored applications should be launched in headless mode. Used by CommandHandler to suppress the interactive console prompt.
public bool Headless { get; }
Property Value
HeadlessCycleCompleted
Gets whether the daemon shut down automatically after a headless monitoring cycle completed. When true, all monitors exhausted their restart attempts or failed initial launch, and the daemon should exit with a non-zero exit code to prevent systemd restart loops. Backed by an int field for thread-safe reads via Volatile.
public bool HeadlessCycleCompleted { get; }
Property Value
IsDaemonShutdownRequested
Gets whether the daemon has been signalled to shut down.
public bool IsDaemonShutdownRequested { get; }
Property Value
Methods
CancelCurrentMonitoring()
Thread-safe cancellation of the current monitoring cycle. Uses Read(ref readonly bool) for lock-free access. Safely handles the case where the CTS was disposed by the monitoring cycle's finally block.
public void CancelCurrentMonitoring()
DisposeAsync()
Disposes of orchestrator resources, cleaning up any remaining active monitors, health checkers, and CTS instances.
public ValueTask DisposeAsync()
Returns
ForceKillAllAsync()
Cancels monitoring and force-kills all active monitored processes. Captures the cycle completion source before cancellation to prevent the race where the cycle's finally block nulls it before callers can await it. Returns only after all processes have been terminated. Thread-safe: takes a snapshot of active monitors under lock before killing.
public Task<Task?> ForceKillAllAsync()
Returns
GetActiveMonitorStatuses()
Returns a thread-safe snapshot of active monitor statuses for diagnostics. Takes a snapshot of the monitors list under lock, then queries status outside the lock to avoid holding the lock during process I/O (e.g., /proc reads on Linux).
public IReadOnlyList<HealthMonitorStatus> GetActiveMonitorStatuses()
Returns
- IReadOnlyList<HealthMonitorStatus>
A read-only list of HealthMonitorStatus snapshots.
IsMonitoringActive()
Checks whether monitoring is currently active and not cancelled. Uses Read(ref readonly bool) for lock-free thread safety on the CTS reference.
public bool IsMonitoringActive()
Returns
- bool
True if monitoring is active and not cancelled; otherwise, false.
RunAsync()
Runs the main orchestration loop. Waits for start signals, launches monitors, and handles stop/shutdown. Returns when the daemon token is cancelled. In headless mode, automatically initiates daemon shutdown after the monitoring cycle completes, since no interactive console is available to issue further commands.
public Task RunAsync()
Returns
- Task
A task representing the asynchronous orchestration operation.
Shutdown()
Signals the daemon to shut down by cancelling monitoring and the daemon-wide token. CancelCurrentMonitoring() is called defensively before AppHealthMonitor.DaemonOrchestrator.daemonCts. The linked CTS in RunAsync() ensures propagation either way.
public void Shutdown()
TrySignalStart()
Attempts to release the start signal semaphore to trigger a new monitoring cycle. Safely handles the case where the semaphore is already at its maximum count.
public bool TrySignalStart()
Returns
- bool
True if the signal was released; false if it was already signalled.
WaitForCycleCompletionAsync(Task?)
Waits for monitoring cycle cleanup to finish with a bounded timeout.
public Task WaitForCycleCompletionAsync(Task? cycleCompletion)
Parameters
cycleCompletionTaskThe cycle completion task captured from ForceKillAllAsync().
Returns
- Task
A task representing the wait operation.