2using System.Globalization;
 
    5using System.Threading.Tasks;
 
    7using Microsoft.Extensions.Logging;
 
   75            IMetricFactory metricFactory,
 
   77            ILogger<BasicWatchdog> logger,
 
   79            Api.Models.Instance instance,
 
   83                 sessionControllerFactory,
 
   95                 initialLaunchParameters,
 
 
  105                return base.ResetRebootState(cancellationToken);
 
  107            return Restart(
true, cancellationToken);
 
 
  111        public sealed override ValueTask 
InstanceRenamed(
string newInstanceName, CancellationToken cancellationToken)
 
  112            => 
Server?.InstanceRenamed(newInstanceName, cancellationToken) ?? ValueTask.CompletedTask;
 
  121                    var eventType = controller.TerminationWasIntentional
 
  122                        ? EventType.WorldEndProcess
 
  124                    await 
HandleEventImpl(eventType, Enumerable.Empty<
string>(), 
false, cancellationToken);
 
  126                    var exitWord = controller.TerminationWasIntentional ? 
"exited" : 
"crashed";
 
  127                    if (controller.RebootState == Session.RebootState.Shutdown)
 
  132                                CultureInfo.InvariantCulture,
 
  133                                "Server {0}! Shutting down due to graceful termination request...",
 
  140                            CultureInfo.InvariantCulture,
 
  141                            "Server {0}! Rebooting...",
 
  145                    var rebootState = controller.RebootState;
 
  148                        Logger.LogError(
"Watchdog reached normal reboot state with gracefulRebootRequired set!");
 
  149                        rebootState = Session.RebootState.Restart;
 
  153                    controller.ResetRebootState();
 
  160                            case Session.RebootState.Normal:
 
  162                            case Session.RebootState.Restart:
 
  164                            case Session.RebootState.Shutdown:
 
  167                                    "Active server rebooted! Shutting down due to graceful termination request...");
 
  170                                throw new InvalidOperationException($
"Invalid reboot state: {rebootState}");
 
  179                    await controller.SetRebootState(Session.RebootState.Restart, cancellationToken);
 
  189                    Status = Api.Models.WatchdogStatus.Online;
 
  193                    throw new InvalidOperationException($
"Invalid activation reason: {reason}");
 
 
  202            var disposeTask = 
Server?.DisposeAsync();
 
  204            if (!disposeTask.HasValue)
 
  207            await disposeTask.Value;
 
 
  218            CancellationToken cancellationToken)
 
  221            var reattachInProgress = reattachInfo != 
null;
 
  230                if (!reattachInProgress)
 
  232                    Logger.LogTrace(
"Initializing controller with CompileJob {compileJobId}...", dmbToUse!.
CompileJob.
Id);
 
  258                if (!reattachInProgress)
 
  262                    Logger.LogError(
"Server should have a session ID allocated by now but it doesn't!");
 
  264                    Logger.LogInformation(
"Watchdog starting session ID {id}", 
SessionId.Value);
 
  270                if (!reattachInProgress)
 
  275                Logger.LogTrace(ex, 
"Controller initialization failure!");
 
  278                bool serverWasActive = 
Server != 
null;
 
  284                if (dmbToUse != 
null && !serverWasActive)
 
  285                    await dmbToUse.DisposeAsync();
 
 
  307                Status = Api.Models.WatchdogStatus.Restoring;
 
 
  323                    "A new deployment has been made but cannot be applied automatically as the currently running server has no DMAPI. Please manually reboot the server to apply the update.");
 
  327            await 
Server.SetRebootState(Session.RebootState.Restart, cancellationToken);
 
 
 
virtual ? long Id
The ID of the entity.
 
Represents a deployment run.
 
virtual ? Version DMApiVersion
The DMAPI Version.
 
Launch settings for DreamDaemon.
 
IDmbProvider LockNextDmb(string reason, [CallerFilePath] string? callerFile=null, [CallerLineNumber] int callerLine=default)
Gets the next IDmbProvider. DmbAvailable is a precondition.A new IDmbProvider.
 
async ValueTask< ISessionController > LaunchNew(IDmbProvider dmbProvider, IEngineExecutableLock? currentByondLock, DreamDaemonLaunchParameters launchParameters, bool apiValidate, CancellationToken cancellationToken)
Create a ISessionController from a freshly launch DreamDaemon instance.A ValueTask<TResult> resulting...
 
async ValueTask< ISessionController?> Reattach(ReattachInformation reattachInformation, CancellationToken cancellationToken)
Create a ISessionController from an existing DreamDaemon instance.A ValueTask<TResult> resulting in a...
 
ValueTask Update(ReattachInformation reattachInformation, CancellationToken cancellationToken)
Update some reattachInformation .A ValueTask representing the running operation.
 
ValueTask Save(ReattachInformation reattachInformation, CancellationToken cancellationToken)
Save some reattachInformation .A ValueTask representing the running operation.
 
A IWatchdog that manages one server.
 
override async ValueTask DisposeAndNullControllersImpl()
 
override ValueTask InstanceRenamed(string newInstanceName, CancellationToken cancellationToken)
Called when the owning Instance is renamed.A ValueTask representing the running operation.
 
ISessionController? Server
The single ISessionController.
 
virtual ValueTask SessionStartupPersist(CancellationToken cancellationToken)
Called to save the current Server into the WatchdogBase.SessionPersistor when initially launched.
 
override async ValueTask InitController(ValueTask eventTask, ReattachInformation? reattachInfo, CancellationToken cancellationToken)
 
override ValueTask ResetRebootState(CancellationToken cancellationToken)
Cancels pending graceful actions.A ValueTask representing the running operation.
 
virtual ValueTask< IDmbProvider > PrepServerForLaunch(IDmbProvider dmbToUse, CancellationToken cancellationToken)
Prepare the server to launch a new instance with the WatchdogBase.ActiveLaunchParameters and a given ...
 
virtual async ValueTask HandleNewDmbAvailable(CancellationToken cancellationToken)
Handler for MonitorActivationReason.NewDmbAvailable.
 
BasicWatchdog(IChatManager chat, ISessionControllerFactory sessionControllerFactory, IDmbFactory dmbFactory, ISessionPersistor sessionPersistor, IJobManager jobManager, IServerControl serverControl, IAsyncDelayer asyncDelayer, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory, IMetricFactory metricFactory, IIOManager gameIOManager, ILogger< BasicWatchdog > logger, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, bool autoStart)
Initializes a new instance of the BasicWatchdog class.
 
override bool AlphaIsActive
If the alpha server is the active server.
 
virtual ValueTask< MonitorAction > HandleNormalReboot(CancellationToken cancellationToken)
Handler for MonitorActivationReason.ActiveServerRebooted when the RebootState is RebootState....
 
override async ValueTask< MonitorAction > HandleMonitorWakeup(MonitorActivationReason reason, CancellationToken cancellationToken)
 
bool gracefulRebootRequired
If the server is set to gracefully reboot due to a pending dmb or settings change.
 
override? ISessionController GetActiveController()
 
Base class for IWatchdogs.
 
readonly IJobManager jobManager
The IJobManager for the WatchdogBase.
 
ILogger< WatchdogBase > Logger
The ILogger for the WatchdogBase.
 
async ValueTask ReattachFailure(CancellationToken cancellationToken)
Call from InitController(ValueTask, ReattachInformation, CancellationToken) when a reattach operation...
 
readonly bool autoStart
If the WatchdogBase should LaunchNoLock(bool, bool, bool, ReattachInformation, CancellationToken) in ...
 
async ValueTask CheckLaunchResult(ISessionController controller, string serverName, CancellationToken cancellationToken)
Check the LaunchResult of a given controller  for errors and throw a JobException if any are detected...
 
readonly IEventConsumer eventConsumer
The IEventConsumer that is not the WatchdogBase.
 
WatchdogStatus Status
The current WatchdogStatus.
 
readonly IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory
The IRemoteDeploymentManagerFactory for the WatchdogBase.
 
readonly IIOManager diagnosticsIOManager
The IIOManager pointing to the Diagnostics directory.
 
DreamDaemonLaunchParameters ActiveLaunchParameters
The DreamDaemonLaunchParameters to be applied.
 
async ValueTask BeforeApplyDmb(Models.CompileJob newCompileJob, CancellationToken cancellationToken)
To be called before a given newCompileJob  goes live.
 
async ValueTask DisposeAndNullControllers(CancellationToken cancellationToken)
Wrapper for DisposeAndNullControllersImpl under a locked context.
 
long? SessionId
An incrementing ID for representing current server execution.
 
IChatManager Chat
The IChatManager for the WatchdogBase.
 
async ValueTask HandleEventImpl(EventType eventType, IEnumerable< string > parameters, bool relayToSession, CancellationToken cancellationToken)
Handle a given eventType  without re-throwing errors.
 
For managing connected chat services.
 
void QueueWatchdogMessage(string message)
Queue a chat message  to configured watchdog channels.
 
Factory for IDmbProviders.
 
Provides absolute paths to the latest compiled .dmbs.
 
Factory for creating IRemoteDeploymentManagers.
 
Consumes EventTypes and takes the appropriate actions.
 
Factory for ISessionControllers.
 
Handles communication with a DreamDaemon IProcess.
 
Handles saving and loading ReattachInformation.
 
Represents a service that may take an updated Host assembly and run it, stopping the current assembly...
 
Interface for using filesystems.
 
Manages the runtime of Jobs.
 
For waiting asynchronously.
 
EventType
Types of events. Mirror in tgs.dm. Prefer last listed name for script.
 
RebootState
Represents the action to take when /world/Reboot() is called.
 
MonitorAction
The action for the monitor loop to take when control is returned to it.
 
@ Restart
The monitor should kill and restart both servers.
 
MonitorActivationReason
Reasons for the monitor to wake up.