Merge pull request #1200 from tgstation/MoreScripts

Adds more events
This commit is contained in:
Jordan Brown
2021-01-14 16:33:54 -05:00
committed by GitHub
7 changed files with 91 additions and 20 deletions
+6 -4
View File
@@ -95,10 +95,13 @@
#define TGS_EVENT_WATCHDOG_SHUTDOWN 15
/// Before the watchdog detaches for a TGS update/restart. No parameters.
#define TGS_EVENT_WATCHDOG_DETACH 16
// We don't actually implement this value as the DMAPI can never receive it
// We don't actually implement these 3 events as the DMAPI can never receive them.
// #define TGS_EVENT_WATCHDOG_LAUNCH 17
// Same here. We don't actually implement this value as the DMAPI can never receive it
// #define TGS_EVENT_WORLD_END_PROCESS 18
// #define TGS_EVENT_WATCHDOG_CRASH 18
// #define TGS_EVENT_WORLD_END_PROCESS 19
// #define TGS_EVENT_WORLD_REBOOT 20
/// Watchdog event when TgsInitializationComplete() is called. No parameters.
#define TGS_EVENT_WORLD_PRIME 21
// OTHER ENUMS
@@ -132,7 +135,6 @@
*
* This may use [/world/var/sleep_offline] to make this happen so ensure no changes are made to it while this call is running.
* Afterwards, consider explicitly setting it to what you want to avoid this BYOND bug: http://www.byond.com/forum/post/2575184
* Before this point, note that any static files or directories may be in use by another server. Your code should account for this.
* This function should not be called before ..() in [/world/proc/New].
*/
/world/proc/TgsInitializationComplete()
@@ -96,7 +96,7 @@ namespace Tgstation.Server.Host.Components.Events
DeploymentComplete,
/// <summary>
/// Before the watchdog shutsdown. Not sent for graceful shutdowns. No parameters.
/// Before the watchdog shuts down. Not sent for graceful shutdowns. No parameters.
/// </summary>
[EventScript("WatchdogShutdown")]
WatchdogShutdown,
@@ -114,9 +114,27 @@ namespace Tgstation.Server.Host.Components.Events
WatchdogLaunch,
/// <summary>
/// In between DD restarts if the process has been force-ended by the DMAPI (TgsEndProcess())
/// Watchdog event when DreamDaemon exits unexpectedly. No parameters.
/// </summary>
[EventScript("WatchdogCrash")]
WatchdogCrash,
/// <summary>
/// In between watchdog DreamDaemon restarts if the process has been force-ended by the DMAPI (TgsEndProcess()). No parameters.
/// </summary>
[EventScript("WorldEndProcess")]
WorldEndProcess,
/// <summary>
/// Watchdog event when TgsReboot() is called. Not synchronous. Called after <see cref="WorldEndProcess"/>. No parameters.
/// </summary>
[EventScript("WorldReboot")]
WorldReboot,
/// <summary>
/// Watchdog event when TgsInitializationsComplete() is called. No parameters.
/// </summary>
[EventScript("WorldPrime")]
WorldPrime,
}
}
@@ -49,12 +49,12 @@ namespace Tgstation.Server.Host.Components.Session
RebootState RebootState { get; }
/// <summary>
/// A <see cref="Task"/> that completes when the server calls /world/Reboot()
/// A <see cref="Task"/> that completes when the server calls /world/TgsReboot().
/// </summary>
Task OnReboot { get; }
/// <summary>
/// A <see cref="Task"/> that completes when the server calls /world/TgsInitializationsComplete()
/// A <see cref="Task"/> that completes when the server calls /world/TgsInitializationComplete()
/// </summary>
Task OnPrime { get; }
@@ -92,10 +92,12 @@ namespace Tgstation.Server.Host.Components.Watchdog
switch (reason)
{
case MonitorActivationReason.ActiveServerCrashed:
if (Server.TerminationWasRequested)
await EventConsumer.HandleEvent(EventType.WorldEndProcess, Enumerable.Empty<string>(), cancellationToken).ConfigureAwait(false);
var eventType = Server.TerminationWasRequested
? EventType.WorldEndProcess
: EventType.WatchdogCrash;
await EventConsumer.HandleEvent(eventType, Enumerable.Empty<string>(), cancellationToken).ConfigureAwait(false);
string exitWord = Server.TerminationWasRequested ? "exited" : "crashed";
var exitWord = Server.TerminationWasRequested ? "exited" : "crashed";
if (Server.RebootState == Session.RebootState.Shutdown)
{
// the time for graceful shutdown is now
@@ -128,6 +130,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
gracefulRebootRequired = false;
Server.ResetRebootState();
await EventConsumer.HandleEvent(EventType.WorldReboot, Enumerable.Empty<string>(), cancellationToken).ConfigureAwait(false);
switch (rebootState)
{
case Session.RebootState.Normal:
@@ -144,7 +148,6 @@ namespace Tgstation.Server.Host.Components.Watchdog
default:
throw new InvalidOperationException($"Invalid reboot state: {rebootState}");
}
case MonitorActivationReason.ActiveLaunchParametersUpdated:
await Server.SetRebootState(Session.RebootState.Restart, cancellationToken).ConfigureAwait(false);
gracefulRebootRequired = true;
@@ -152,6 +155,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
case MonitorActivationReason.NewDmbAvailable:
await HandleNewDmbAvailable(cancellationToken).ConfigureAwait(false);
break;
case MonitorActivationReason.ActiveServerPrimed:
await EventConsumer.HandleEvent(EventType.WorldPrime, Enumerable.Empty<string>(), cancellationToken).ConfigureAwait(false);
break;
case MonitorActivationReason.Heartbeat:
default:
throw new InvalidOperationException($"Invalid activation reason: {reason}");
@@ -1,4 +1,4 @@
namespace Tgstation.Server.Host.Components.Watchdog
namespace Tgstation.Server.Host.Components.Watchdog
{
/// <summary>
/// Reasons for the monitor to wake up
@@ -29,5 +29,10 @@
/// A heartbeat is required.
/// </summary>
Heartbeat,
/// <summary>
/// Server primed.
/// </summary>
ActiveServerPrimed,
}
}
@@ -609,6 +609,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
#pragma warning disable CA1502
private async Task MonitorLifetimes(CancellationToken cancellationToken)
{
Logger.LogTrace("Entered MonitorLifetimes");
@@ -619,6 +620,12 @@ namespace Tgstation.Server.Host.Components.Watchdog
try
{
MonitorAction nextAction = MonitorAction.Continue;
Task activeServerLifetime = null,
activeServerReboot = null,
serverPrimed = null,
activeLaunchParametersChanged = null,
newDmbAvailable = null;
ISessionController lastController = null;
for (ulong iteration = 1; nextAction != MonitorAction.Exit; ++iteration)
using (LogContext.PushProperty("Monitor", iteration))
try
@@ -627,17 +634,44 @@ namespace Tgstation.Server.Host.Components.Watchdog
nextAction = MonitorAction.Continue;
var controller = GetActiveController();
Task activeServerLifetime = controller.Lifetime;
var activeServerReboot = controller.OnReboot;
Task activeLaunchParametersChanged = ActiveParametersUpdated.Task;
var newDmbAvailable = DmbFactory.OnNewerDmb;
void UpdateMonitoredTasks()
{
static void TryUpdateTask(ref Task oldTask, Task newTask)
{
if (oldTask?.IsCompleted == true)
return;
oldTask = newTask;
}
if (lastController == controller)
{
TryUpdateTask(ref activeServerLifetime, controller.Lifetime);
TryUpdateTask(ref activeServerReboot, controller.OnReboot);
TryUpdateTask(ref serverPrimed, controller.OnPrime);
}
else
{
activeServerLifetime = controller.Lifetime;
activeServerReboot = controller.OnReboot;
serverPrimed = controller.OnPrime;
lastController = controller;
}
TryUpdateTask(ref activeLaunchParametersChanged, ActiveParametersUpdated.Task);
TryUpdateTask(ref newDmbAvailable, DmbFactory.OnNewerDmb);
}
UpdateMonitoredTasks();
var heartbeatSeconds = ActiveLaunchParameters.HeartbeatSeconds.Value;
var heartbeat = heartbeatSeconds == 0
|| !controller.DMApiAvailable
? Extensions.TaskExtensions.InfiniteTask()
: Task.Delay(TimeSpan.FromSeconds(heartbeatSeconds), cancellationToken);
: Task.Delay(
TimeSpan.FromSeconds(heartbeatSeconds),
cancellationToken);
// cancel waiting if requested
var cancelTcs = new TaskCompletionSource<object>();
@@ -647,7 +681,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
heartbeat,
newDmbAvailable,
cancelTcs.Task,
activeLaunchParametersChanged);
activeLaunchParametersChanged,
serverPrimed);
// wait for something to happen
using (cancellationToken.Register(() => cancelTcs.SetCanceled()))
@@ -688,7 +723,10 @@ namespace Tgstation.Server.Host.Components.Watchdog
|| CheckActivationReason(ref activeServerReboot, MonitorActivationReason.ActiveServerRebooted)
|| CheckActivationReason(ref newDmbAvailable, MonitorActivationReason.NewDmbAvailable)
|| CheckActivationReason(ref activeLaunchParametersChanged, MonitorActivationReason.ActiveLaunchParametersUpdated)
|| CheckActivationReason(ref heartbeat, MonitorActivationReason.Heartbeat);
|| CheckActivationReason(ref heartbeat, MonitorActivationReason.Heartbeat)
|| CheckActivationReason(ref serverPrimed, MonitorActivationReason.ActiveServerPrimed);
UpdateMonitoredTasks();
if (!anyActivation)
moreActivationsToProcess = false;
@@ -769,6 +807,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
Logger.LogTrace("Monitor exiting...");
}
#pragma warning restore CA1502
/// <summary>
/// Starts all <see cref="ISessionController"/>s.
+1
View File
@@ -65,6 +65,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tgs", "tgs", "{F7765A4B-021
src\DMAPI\tgs\includes.dm = src\DMAPI\tgs\includes.dm
src\DMAPI\tgs\LICENSE = src\DMAPI\tgs\LICENSE
src\DMAPI\tgs\README.md = src\DMAPI\tgs\README.md
src\DMAPI\tgs.dm = src\DMAPI\tgs.dm
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{DCCBA9DA-47BA-4C70-823B-E99A3ACA0377}"