mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-26 06:27:19 +01:00
Adds the PosixWatchdog
- Test BasicWatchdog in Sqlite travis job - Rename UseBasicWatchdogOnWindows to UseBasicWatchdog - Inline one use of DatabaseContextExtensions in DmbFactory - Rename WindowsSwappableDmbProvider to SwappableDmbProvider - Fix DreamDaemonController returning the wrong ActiveCompileJob - Re-enable disabled watchdog tests
This commit is contained in:
+2
-1
@@ -38,9 +38,10 @@ jobs:
|
||||
- DockerBuild=false
|
||||
- DMAPI=false
|
||||
- CONFIG=Release
|
||||
- General__UseBasicWatchdog=true
|
||||
- TGS4_TEST_DATABASE_TYPE=Sqlite
|
||||
- TGS4_TEST_CONNECTION_STRING="Data Source=TravisTestDB.sqlite3;Mode=ReadWriteCreate"
|
||||
name: "Sqlite Integration Test"
|
||||
name: "Sqlite & BasicWatchdog Integration Test"
|
||||
language: csharp
|
||||
mono: none
|
||||
dotnet: 3.1
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Database;
|
||||
using Tgstation.Server.Host.Extensions;
|
||||
using Tgstation.Server.Host.IO;
|
||||
using Tgstation.Server.Host.Models;
|
||||
|
||||
@@ -173,7 +172,11 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
await databaseContextFactory.UseContext(async (db) =>
|
||||
{
|
||||
cj = await db
|
||||
.MostRecentCompletedCompileJobOrDefault(instance, cancellationToken)
|
||||
.CompileJobs
|
||||
.AsQueryable()
|
||||
.Where(x => x.Job.Instance.Id == instance.Id)
|
||||
.OrderByDescending(x => x.Job.StoppedAt)
|
||||
.FirstOrDefaultAsync(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
@@ -322,7 +325,7 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
.ToList();
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
jobUidsToNotErase.Add(WindowsSwappableDmbProvider.LiveGameDirectory);
|
||||
jobUidsToNotErase.Add(SwappableDmbProvider.LiveGameDirectory);
|
||||
|
||||
logger.LogTrace("We will not clean the following directories: {0}", String.Join(", ", jobUidsToNotErase));
|
||||
|
||||
|
||||
+5
-5
@@ -7,9 +7,9 @@ using Tgstation.Server.Host.Models;
|
||||
namespace Tgstation.Server.Host.Components.Deployment
|
||||
{
|
||||
/// <summary>
|
||||
/// A windows <see cref="IDmbProvider"/> that uses symlinks.
|
||||
/// A <see cref="IDmbProvider"/> that uses symlinks.
|
||||
/// </summary>
|
||||
sealed class WindowsSwappableDmbProvider : IDmbProvider
|
||||
sealed class SwappableDmbProvider : IDmbProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The directory where the <see cref="baseProvider"/> is symlinked to.
|
||||
@@ -41,12 +41,12 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
readonly ISymlinkFactory symlinkFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WindowsSwappableDmbProvider"/> <see langword="class"/>.
|
||||
/// Initializes a new instance of the <see cref="SwappableDmbProvider"/> <see langword="class"/>.
|
||||
/// </summary>
|
||||
/// <param name="baseProvider">The value of <see cref="baseProvider"/>.</param>
|
||||
/// <param name="ioManager">The value of <see cref="ioManager"/>.</param>
|
||||
/// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/>.</param>
|
||||
public WindowsSwappableDmbProvider(IDmbProvider baseProvider, IIOManager ioManager, ISymlinkFactory symlinkFactory)
|
||||
public SwappableDmbProvider(IDmbProvider baseProvider, IIOManager ioManager, ISymlinkFactory symlinkFactory)
|
||||
{
|
||||
this.baseProvider = baseProvider ?? throw new ArgumentNullException(nameof(baseProvider));
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
@@ -60,7 +60,7 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
public void KeepAlive() => baseProvider.KeepAlive();
|
||||
|
||||
/// <summary>
|
||||
/// Make the <see cref="WindowsSwappableDmbProvider"/> active by replacing the live link with our <see cref="CompileJob"/>.
|
||||
/// Make the <see cref="SwappableDmbProvider"/> active by replacing the live link with our <see cref="CompileJob"/>.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
@@ -174,7 +174,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
protected sealed override ISessionController GetActiveController() => Server;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected sealed override async Task InitControllers(
|
||||
protected override async Task InitControllers(
|
||||
Task chatTask,
|
||||
ReattachInformation reattachInfo,
|
||||
CancellationToken cancellationToken)
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Components.Chat;
|
||||
using Tgstation.Server.Host.Components.Deployment;
|
||||
using Tgstation.Server.Host.Components.Events;
|
||||
using Tgstation.Server.Host.Components.Session;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.Database;
|
||||
using Tgstation.Server.Host.IO;
|
||||
using Tgstation.Server.Host.Jobs;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// A variant of the <see cref="WindowsWatchdog"/> that works on POSIX systems.
|
||||
/// </summary>
|
||||
sealed class PosixWatchdog : WindowsWatchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// If the swappable game directory is currently a rename of the compile job.
|
||||
/// </summary>
|
||||
bool directoryHardLinked;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PosixWatchdog"/> <see langword="class"/>.
|
||||
/// </summary>
|
||||
/// <param name="chat">The <see cref="IChatManager"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="sessionControllerFactory">The <see cref="ISessionControllerFactory"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="dmbFactory">The <see cref="IDmbFactory"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="reattachInfoHandler">The <see cref="IReattachInfoHandler"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="databaseContextFactory">The <see cref="IDatabaseContextFactory"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="serverControl">The <see cref="IServerControl"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="diagnosticsIOManager">The <see cref="IIOManager"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="eventConsumer">The <see cref="IEventConsumer"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="gameIOManager">The <see cref="IIOManager"/> pointing to the game directory for the <see cref="WindowsWatchdog"/>..</param>
|
||||
/// <param name="symlinkFactory">The <see cref="ISymlinkFactory"/> for the <see cref="WindowsWatchdog"/>.</param>
|
||||
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="initialLaunchParameters">The <see cref="DreamDaemonLaunchParameters"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="instance">The <see cref="Api.Models.Instance"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="autoStart">The autostart value for the <see cref="WatchdogBase"/>.</param>
|
||||
public PosixWatchdog(
|
||||
IChatManager chat,
|
||||
ISessionControllerFactory sessionControllerFactory,
|
||||
IDmbFactory dmbFactory,
|
||||
IReattachInfoHandler reattachInfoHandler,
|
||||
IDatabaseContextFactory databaseContextFactory,
|
||||
IJobManager jobManager,
|
||||
IServerControl serverControl,
|
||||
IAsyncDelayer asyncDelayer,
|
||||
IIOManager diagnosticsIOManager,
|
||||
IEventConsumer eventConsumer,
|
||||
IIOManager gameIOManager,
|
||||
ISymlinkFactory symlinkFactory,
|
||||
ILogger<PosixWatchdog> logger,
|
||||
DreamDaemonLaunchParameters initialLaunchParameters,
|
||||
Api.Models.Instance instance,
|
||||
bool autoStart)
|
||||
: base(
|
||||
chat,
|
||||
sessionControllerFactory,
|
||||
dmbFactory,
|
||||
reattachInfoHandler,
|
||||
databaseContextFactory,
|
||||
jobManager,
|
||||
serverControl,
|
||||
asyncDelayer,
|
||||
diagnosticsIOManager,
|
||||
eventConsumer,
|
||||
gameIOManager,
|
||||
symlinkFactory,
|
||||
logger,
|
||||
initialLaunchParameters,
|
||||
instance,
|
||||
autoStart)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task InitialLink(SwappableDmbProvider swappableDmbProvider, CancellationToken cancellationToken)
|
||||
{
|
||||
// Instead of symlinking to begin with we actually rename the directory
|
||||
Logger.LogTrace("Hard linking compile job...");
|
||||
await GameIOManager.MoveDirectory(
|
||||
swappableDmbProvider.CompileJob.DirectoryName.ToString(),
|
||||
swappableDmbProvider.Directory,
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
directoryHardLinked = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task InitControllers(Task chatTask, ReattachInformation reattachInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await base.InitControllers(chatTask, reattachInfo, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Then we move it back and apply the symlink
|
||||
if (directoryHardLinked)
|
||||
{
|
||||
Logger.LogTrace("Unhardlinking compile job...");
|
||||
Server?.Suspend();
|
||||
await GameIOManager.MoveDirectory(
|
||||
ActiveSwappable.Directory,
|
||||
ActiveSwappable.CompileJob.DirectoryName.ToString(),
|
||||
default)
|
||||
.ConfigureAwait(false);
|
||||
directoryHardLinked = false;
|
||||
}
|
||||
}
|
||||
|
||||
await ActiveSwappable.MakeActive(cancellationToken).ConfigureAwait(false);
|
||||
Server.Resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Tgstation.Server.Api.Models.Internal;
|
||||
using Tgstation.Server.Host.Components.Chat;
|
||||
using Tgstation.Server.Host.Components.Deployment;
|
||||
using Tgstation.Server.Host.Components.Events;
|
||||
using Tgstation.Server.Host.Components.Session;
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.Database;
|
||||
using Tgstation.Server.Host.IO;
|
||||
using Tgstation.Server.Host.Jobs;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="IWatchdogFactory"/> for creating <see cref="PosixWatchdog"/>s.
|
||||
/// </summary>
|
||||
sealed class PosixWatchdogFactory : WindowsWatchdogFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PosixWatchdogFactory"/> <see langword="class"/>.
|
||||
/// </summary>
|
||||
/// <param name="serverControl">The <see cref="IServerControl"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
/// <param name="databaseContextFactory">The <see cref="IDatabaseContextFactory"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
/// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
/// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
/// <param name="symlinkFactory">The <see cref="ISymlinkFactory"/> for the <see cref="WindowsWatchdogFactory"/>.</param>
|
||||
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> for <see cref="GeneralConfiguration"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
public PosixWatchdogFactory(
|
||||
IServerControl serverControl,
|
||||
ILoggerFactory loggerFactory,
|
||||
IDatabaseContextFactory databaseContextFactory,
|
||||
IJobManager jobManager,
|
||||
IAsyncDelayer asyncDelayer,
|
||||
ISymlinkFactory symlinkFactory,
|
||||
IOptions<GeneralConfiguration> generalConfigurationOptions)
|
||||
: base(
|
||||
serverControl,
|
||||
loggerFactory,
|
||||
databaseContextFactory,
|
||||
jobManager,
|
||||
asyncDelayer,
|
||||
symlinkFactory,
|
||||
generalConfigurationOptions)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IWatchdog CreateWatchdog(
|
||||
IChatManager chat,
|
||||
IDmbFactory dmbFactory,
|
||||
IReattachInfoHandler reattachInfoHandler,
|
||||
ISessionControllerFactory sessionControllerFactory,
|
||||
IIOManager gameIOManager,
|
||||
IIOManager diagnosticsIOManager,
|
||||
IEventConsumer eventConsumer,
|
||||
Api.Models.Instance instance,
|
||||
DreamDaemonSettings settings)
|
||||
=> new PosixWatchdog(
|
||||
chat,
|
||||
sessionControllerFactory,
|
||||
dmbFactory,
|
||||
reattachInfoHandler,
|
||||
DatabaseContextFactory,
|
||||
JobManager,
|
||||
ServerControl,
|
||||
AsyncDelayer,
|
||||
diagnosticsIOManager,
|
||||
eventConsumer,
|
||||
gameIOManager,
|
||||
SymlinkFactory,
|
||||
LoggerFactory.CreateLogger<PosixWatchdog>(),
|
||||
settings,
|
||||
instance,
|
||||
settings.AutoStart.Value);
|
||||
}
|
||||
}
|
||||
@@ -236,6 +236,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
restartRegistration.Dispose();
|
||||
throw;
|
||||
}
|
||||
|
||||
Logger.LogTrace("Created watchdog");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -15,14 +15,19 @@ using Tgstation.Server.Host.Jobs;
|
||||
namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// A version of the <see cref="BasicWatchdog"/> that, instead of killing servers for updates, uses the wonders of symlinks to swap out changes without killing DreamDaemon.
|
||||
/// A <see cref="IWatchdog"/> that, instead of killing servers for updates, uses the wonders of symlinks to swap out changes without killing DreamDaemon.
|
||||
/// </summary>
|
||||
sealed class WindowsWatchdog : BasicWatchdog
|
||||
class WindowsWatchdog : BasicWatchdog
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="SwappableDmbProvider"/> for <see cref="WatchdogBase.LastLaunchParameters"/>.
|
||||
/// </summary>
|
||||
protected SwappableDmbProvider ActiveSwappable { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IIOManager"/> for the <see cref="WindowsWatchdog"/> pointing to the Game directory.
|
||||
/// </summary>
|
||||
readonly IIOManager gameIOManager;
|
||||
protected IIOManager GameIOManager { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ISymlinkFactory"/> for the <see cref="WindowsWatchdog"/>.
|
||||
@@ -30,14 +35,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
readonly ISymlinkFactory symlinkFactory;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="WindowsSwappableDmbProvider"/> for <see cref="WatchdogBase.LastLaunchParameters"/>.
|
||||
/// The active <see cref="SwappableDmbProvider"/> for <see cref="WatchdogBase.ActiveLaunchParameters"/>.
|
||||
/// </summary>
|
||||
WindowsSwappableDmbProvider activeSwappable;
|
||||
|
||||
/// <summary>
|
||||
/// The active <see cref="WindowsSwappableDmbProvider"/> for <see cref="WatchdogBase.ActiveLaunchParameters"/>.
|
||||
/// </summary>
|
||||
WindowsSwappableDmbProvider pendingSwappable;
|
||||
SwappableDmbProvider pendingSwappable;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IDmbProvider"/> the <see cref="WindowsWatchdog"/> was started with.
|
||||
@@ -57,7 +57,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="diagnosticsIOManager">The <see cref="IIOManager"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="eventConsumer">The <see cref="IEventConsumer"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="gameIOManager">The value of <see cref="gameIOManager"/>.</param>
|
||||
/// <param name="gameIOManager">The value of <see cref="GameIOManager"/>.</param>
|
||||
/// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/>.</param>
|
||||
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
/// <param name="initialLaunchParameters">The <see cref="DreamDaemonLaunchParameters"/> for the <see cref="WatchdogBase"/>.</param>
|
||||
@@ -97,7 +97,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
try
|
||||
{
|
||||
this.gameIOManager = gameIOManager ?? throw new ArgumentNullException(nameof(gameIOManager));
|
||||
GameIOManager = gameIOManager ?? throw new ArgumentNullException(nameof(gameIOManager));
|
||||
this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory));
|
||||
}
|
||||
catch
|
||||
@@ -113,7 +113,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
base.DisposeAndNullControllersImpl();
|
||||
|
||||
// If we reach this point, we can guarantee PrepServerForLaunch will be called before starting again.
|
||||
activeSwappable = null;
|
||||
ActiveSwappable = null;
|
||||
pendingSwappable?.Dispose();
|
||||
pendingSwappable = null;
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
{
|
||||
Logger.LogTrace("Replacing activeSwappable with pendingSwappable...");
|
||||
Server.ReplaceDmbProvider(pendingSwappable);
|
||||
activeSwappable = pendingSwappable;
|
||||
ActiveSwappable = pendingSwappable;
|
||||
pendingSwappable = null;
|
||||
}
|
||||
else
|
||||
@@ -154,11 +154,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
return;
|
||||
}
|
||||
|
||||
WindowsSwappableDmbProvider windowsProvider = null;
|
||||
SwappableDmbProvider windowsProvider = null;
|
||||
bool suspended = false;
|
||||
try
|
||||
{
|
||||
windowsProvider = new WindowsSwappableDmbProvider(compileJobProvider, gameIOManager, symlinkFactory);
|
||||
windowsProvider = new SwappableDmbProvider(compileJobProvider, GameIOManager, symlinkFactory);
|
||||
|
||||
Logger.LogDebug("Swapping to compile job {0}...", windowsProvider.CompileJob.Id);
|
||||
try
|
||||
@@ -190,9 +190,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task<IDmbProvider> PrepServerForLaunch(IDmbProvider dmbToUse, CancellationToken cancellationToken)
|
||||
protected sealed override async Task<IDmbProvider> PrepServerForLaunch(IDmbProvider dmbToUse, CancellationToken cancellationToken)
|
||||
{
|
||||
if(activeSwappable != null)
|
||||
if(ActiveSwappable != null)
|
||||
throw new InvalidOperationException("Expected activeSwappable to be null!");
|
||||
if(startupDmbProvider != null)
|
||||
throw new InvalidOperationException("Expected startupDmbProvider to be null!");
|
||||
@@ -202,21 +202,30 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
// Add another lock to the startup DMB because it'll be used throughout the lifetime of the watchdog
|
||||
startupDmbProvider = await DmbFactory.FromCompileJob(dmbToUse.CompileJob, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
activeSwappable = pendingSwappable ?? new WindowsSwappableDmbProvider(dmbToUse, gameIOManager, symlinkFactory);
|
||||
ActiveSwappable = pendingSwappable ?? new SwappableDmbProvider(dmbToUse, GameIOManager, symlinkFactory);
|
||||
pendingSwappable = null;
|
||||
|
||||
try
|
||||
{
|
||||
await activeSwappable.MakeActive(cancellationToken).ConfigureAwait(false);
|
||||
await InitialLink(ActiveSwappable, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// We won't worry about disposing activeSwappable here as we can't dispose dmbToUse here.
|
||||
activeSwappable = null;
|
||||
ActiveSwappable = null;
|
||||
throw;
|
||||
}
|
||||
|
||||
return activeSwappable;
|
||||
return ActiveSwappable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the initial link to the live game directory.
|
||||
/// </summary>
|
||||
/// <param name="swappableDmbProvider">The <see cref="SwappableDmbProvider"/> in use.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
protected virtual Task InitialLink(SwappableDmbProvider swappableDmbProvider, CancellationToken cancellationToken)
|
||||
=> swappableDmbProvider.MakeActive(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <summary>
|
||||
/// <see cref="IWatchdogFactory"/> for creating <see cref="WindowsWatchdog"/>s.
|
||||
/// </summary>
|
||||
sealed class WindowsWatchdogFactory : WatchdogFactory
|
||||
class WindowsWatchdogFactory : WatchdogFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="ISymlinkFactory"/> for the <see cref="WindowsWatchdogFactory"/>.
|
||||
/// </summary>
|
||||
readonly ISymlinkFactory symlinkFactory;
|
||||
protected ISymlinkFactory SymlinkFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WindowsWatchdogFactory"/> <see langword="class"/>.
|
||||
@@ -32,7 +32,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <param name="databaseContextFactory">The <see cref="IDatabaseContextFactory"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
/// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
/// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
/// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/>.</param>
|
||||
/// <param name="symlinkFactory">The value of <see cref="SymlinkFactory"/>.</param>
|
||||
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> for <see cref="GeneralConfiguration"/> for the <see cref="WatchdogFactory"/>.</param>
|
||||
public WindowsWatchdogFactory(
|
||||
IServerControl serverControl,
|
||||
@@ -50,7 +50,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
asyncDelayer,
|
||||
generalConfigurationOptions)
|
||||
{
|
||||
this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory));
|
||||
SymlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -76,7 +76,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
diagnosticsIOManager,
|
||||
eventConsumer,
|
||||
gameIOManager,
|
||||
symlinkFactory,
|
||||
SymlinkFactory,
|
||||
LoggerFactory.CreateLogger<WindowsWatchdog>(),
|
||||
settings,
|
||||
instance,
|
||||
|
||||
@@ -83,9 +83,9 @@ namespace Tgstation.Server.Host.Configuration
|
||||
public uint RestartTimeout { get; set; } = DefaultRestartTimeout;
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="Components.Watchdog.WindowsWatchdog"/> should not be used if it is available.
|
||||
/// If the <see cref="Components.Watchdog.BasicWatchdog"/> should be preferred.
|
||||
/// </summary>
|
||||
public bool UseBasicWatchdogOnWindows { get; set; }
|
||||
public bool UseBasicWatchdog { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GeneralConfiguration"/> <see langword="class"/>.
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
if (revision)
|
||||
{
|
||||
var latestCompileJob = instance.LatestCompileJob();
|
||||
result.ActiveCompileJob = ((instance.Watchdog.Status == WatchdogStatus.Offline
|
||||
result.ActiveCompileJob = ((instance.Watchdog.Status != WatchdogStatus.Offline
|
||||
? dd.ActiveCompileJob
|
||||
: latestCompileJob) ?? latestCompileJob)
|
||||
?.ToApi();
|
||||
|
||||
@@ -251,11 +251,7 @@ namespace Tgstation.Server.Host.Core
|
||||
// configure platform specific services
|
||||
if (postSetupServices.PlatformIdentifier.IsWindows)
|
||||
{
|
||||
if (postSetupServices.GeneralConfiguration.UseBasicWatchdogOnWindows)
|
||||
services.AddSingleton<IWatchdogFactory, WatchdogFactory>();
|
||||
else
|
||||
services.AddSingleton<IWatchdogFactory, WindowsWatchdogFactory>();
|
||||
|
||||
AddWatchdog<WindowsWatchdogFactory>(services, postSetupServices);
|
||||
services.AddSingleton<ISystemIdentityFactory, WindowsSystemIdentityFactory>();
|
||||
services.AddSingleton<ISymlinkFactory, WindowsSymlinkFactory>();
|
||||
services.AddSingleton<IByondInstaller, WindowsByondInstaller>();
|
||||
@@ -268,7 +264,7 @@ namespace Tgstation.Server.Host.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddSingleton<IWatchdogFactory, WatchdogFactory>();
|
||||
AddWatchdog<PosixWatchdogFactory>(services, postSetupServices);
|
||||
services.AddSingleton<ISystemIdentityFactory, PosixSystemIdentityFactory>();
|
||||
services.AddSingleton<ISymlinkFactory, PosixSymlinkFactory>();
|
||||
services.AddSingleton<IByondInstaller, PosixByondInstaller>();
|
||||
@@ -303,6 +299,21 @@ namespace Tgstation.Server.Host.Core
|
||||
services.AddSingleton<IInstanceManager>(x => x.GetRequiredService<InstanceManager>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="IWatchdogFactory"/> implementation.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSystemWatchdogFactory">The <see cref="WatchdogFactory"/> child <see langword="class"/> for the current system.</typeparam>
|
||||
/// <param name="services">The <see cref="IServiceCollection"/> to configure.</param>
|
||||
/// <param name="postSetupServices">The <see cref="IPostSetupServices"/> to use.</param>
|
||||
static void AddWatchdog<TSystemWatchdogFactory>(IServiceCollection services, IPostSetupServices postSetupServices)
|
||||
where TSystemWatchdogFactory : class, IWatchdogFactory
|
||||
{
|
||||
if (postSetupServices.GeneralConfiguration.UseBasicWatchdog)
|
||||
services.AddSingleton<IWatchdogFactory, WatchdogFactory>();
|
||||
else
|
||||
services.AddSingleton<IWatchdogFactory, TSystemWatchdogFactory>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void ConfigureHostedService(IServiceCollection services)
|
||||
=> services.AddSingleton<IHostedService>(x => x.GetRequiredService<InstanceManager>());
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Database;
|
||||
using Tgstation.Server.Host.Models;
|
||||
|
||||
namespace Tgstation.Server.Host.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions for the <see cref="IDatabaseContext"/> <see langword="class"/>.
|
||||
/// </summary>
|
||||
static class DatabaseContextExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the most recent <see cref="CompileJob"/> for a given <paramref name="instance"/> from a given <paramref name="databaseContext"/>.
|
||||
/// </summary>
|
||||
/// <param name="databaseContext">The <see cref="IDatabaseContext"/>.</param>
|
||||
/// <param name="instance">The <see cref="Instance"/> to search for <see cref="CompileJob"/>s.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the most recent <see cref="CompileJob"/> associated with the given <paramref name="instance"/> from the <paramref name="databaseContext"/>.</returns>
|
||||
public static Task<CompileJob> MostRecentCompletedCompileJobOrDefault(
|
||||
this IDatabaseContext databaseContext,
|
||||
Api.Models.Instance instance,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (databaseContext == null)
|
||||
throw new ArgumentNullException(nameof(databaseContext));
|
||||
|
||||
return databaseContext
|
||||
.CompileJobs
|
||||
.AsQueryable()
|
||||
.Where(x => x.Job.Instance.Id == instance.Id)
|
||||
.OrderByDescending(x => x.Job.StoppedAt)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"ByondTopicTimeout": 5000,
|
||||
"RestartTimeout": 60000,
|
||||
"ApiPort": 5000,
|
||||
"UseBasicWatchdogOnWindows": false,
|
||||
"UseBasicWatchdog": false,
|
||||
"UserLimit": 100,
|
||||
"InstanceLimit": 10,
|
||||
"ValidInstancePaths": null
|
||||
|
||||
@@ -59,10 +59,8 @@ namespace Tgstation.Server.Tests.Instance
|
||||
Version = ByondTest.TestVersion
|
||||
}, cancellationToken);
|
||||
|
||||
// await RunLongRunningTestThenUpdate(cancellationToken);
|
||||
// await RunLongRunningTestThenUpdateWithByondVersionSwitch(cancellationToken);
|
||||
// Remove this deploy when the above tests are reenabled
|
||||
await DeployTestDme("LongRunning/long_running_test", DreamDaemonSecurity.Trusted, cancellationToken);
|
||||
await RunLongRunningTestThenUpdate(cancellationToken);
|
||||
await RunLongRunningTestThenUpdateWithByondVersionSwitch(cancellationToken);
|
||||
|
||||
await RunHeartbeatTest(cancellationToken);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user