2using System.Globalization;
5using System.Threading.Tasks;
7using Microsoft.Extensions.Logging;
73 ILogger<BasicWatchdog> logger,
75 Api.Models.Instance instance,
79 sessionControllerFactory,
90 initialLaunchParameters,
100 return base.ResetRebootState(cancellationToken);
102 return Restart(
true, cancellationToken);
106 public sealed override ValueTask
InstanceRenamed(
string newInstanceName, CancellationToken cancellationToken)
107 =>
Server?.InstanceRenamed(newInstanceName, cancellationToken) ?? ValueTask.CompletedTask;
116 var eventType = controller.TerminationWasIntentional
117 ? EventType.WorldEndProcess
119 await
HandleEventImpl(eventType, Enumerable.Empty<
string>(),
false, cancellationToken);
121 var exitWord = controller.TerminationWasIntentional ?
"exited" :
"crashed";
122 if (controller.RebootState == Session.RebootState.Shutdown)
127 CultureInfo.InvariantCulture,
128 "Server {0}! Shutting down due to graceful termination request...",
135 CultureInfo.InvariantCulture,
136 "Server {0}! Rebooting...",
140 var rebootState = controller.RebootState;
143 Logger.LogError(
"Watchdog reached normal reboot state with gracefulRebootRequired set!");
144 rebootState = Session.RebootState.Restart;
148 controller.ResetRebootState();
155 case Session.RebootState.Normal:
157 case Session.RebootState.Restart:
159 case Session.RebootState.Shutdown:
162 "Active server rebooted! Shutting down due to graceful termination request...");
165 throw new InvalidOperationException($
"Invalid reboot state: {rebootState}");
174 await controller.SetRebootState(Session.RebootState.Restart, cancellationToken);
184 Status = Api.Models.WatchdogStatus.Online;
188 throw new InvalidOperationException($
"Invalid activation reason: {reason}");
197 var disposeTask =
Server?.DisposeAsync();
199 if (!disposeTask.HasValue)
202 await disposeTask.Value;
213 CancellationToken cancellationToken)
216 var reattachInProgress = reattachInfo !=
null;
225 if (!reattachInProgress)
227 Logger.LogTrace(
"Initializing controller with CompileJob {compileJobId}...", dmbToUse!.
CompileJob.
Id);
253 if (!reattachInProgress)
257 Logger.LogError(
"Server should have a session ID allocated by now but it doesn't!");
259 Logger.LogInformation(
"Watchdog starting session ID {id}",
SessionId.Value);
265 if (!reattachInProgress)
270 Logger.LogTrace(ex,
"Controller initialization failure!");
273 bool serverWasActive =
Server !=
null;
279 if (dmbToUse !=
null && !serverWasActive)
280 await dmbToUse.DisposeAsync();
302 Status = Api.Models.WatchdogStatus.Restoring;
318 "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.");
322 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.
BasicWatchdog(IChatManager chat, ISessionControllerFactory sessionControllerFactory, IDmbFactory dmbFactory, ISessionPersistor sessionPersistor, IJobManager jobManager, IServerControl serverControl, IAsyncDelayer asyncDelayer, IIOManager diagnosticsIOManager, IEventConsumer eventConsumer, IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory, IIOManager gameIOManager, ILogger< BasicWatchdog > logger, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, bool autoStart)
Initializes a new instance of the BasicWatchdog class.
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.
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.