From 707d69d2e658caaba3272f309649e9e32be2ae04 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Fri, 22 Dec 2023 09:48:24 -0500 Subject: [PATCH] Nullify `DmbFactory` --- .../Components/Deployment/DmbFactory.cs | 93 ++++++++++--------- .../Components/Deployment/IDmbFactory.cs | 4 +- .../Deployment/ILatestCompileJobProvider.cs | 4 +- .../Components/Instance.cs | 2 +- .../Components/InstanceWrapper.cs | 2 +- 5 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs index d5dd1f13bd..aebfcda51a 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; @@ -16,8 +17,6 @@ using Tgstation.Server.Host.Database; using Tgstation.Server.Host.IO; using Tgstation.Server.Host.Models; -#nullable disable - namespace Tgstation.Server.Host.Components.Deployment { /// @@ -36,6 +35,7 @@ namespace Tgstation.Server.Host.Components.Deployment } /// + [MemberNotNullWhen(true, nameof(nextDmbProvider))] public bool DmbAvailable => nextDmbProvider != null; /// @@ -91,7 +91,7 @@ namespace Tgstation.Server.Host.Components.Deployment /// /// The latest . /// - IDmbProvider nextDmbProvider; + IDmbProvider? nextDmbProvider; /// /// If the is "started" via . @@ -132,7 +132,7 @@ namespace Tgstation.Server.Host.Components.Deployment public void Dispose() => cleanupCts.Dispose(); // we don't dispose nextDmbProvider here, since it might be the only thing we have /// - public async ValueTask LoadCompileJob(CompileJob job, Action activationAction, CancellationToken cancellationToken) + public async ValueTask LoadCompileJob(CompileJob job, Action? activationAction, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(job); @@ -175,8 +175,8 @@ namespace Tgstation.Server.Host.Components.Deployment throw new ArgumentOutOfRangeException(nameof(lockCount), lockCount, "lockCount must be greater than or equal to 0!"); lock (jobLockCounts) { - var jobId = nextDmbProvider.CompileJob.Id; - var incremented = jobLockCounts[jobId.Value] += lockCount; + var jobId = nextDmbProvider.CompileJob.Require(x => x.Id); + var incremented = jobLockCounts[jobId] += lockCount; logger.LogTrace("Compile job {jobId} lock count now: {lockCount}", jobId, incremented); return nextDmbProvider; } @@ -185,16 +185,15 @@ namespace Tgstation.Server.Host.Components.Deployment /// public async Task StartAsync(CancellationToken cancellationToken) { - CompileJob cj = null; - await databaseContextFactory.UseContext(async (db) => - { - cj = await db - .CompileJobs - .AsQueryable() - .Where(x => x.Job.Instance.Id == metadata.Id) - .OrderByDescending(x => x.Job.StoppedAt) - .FirstOrDefaultAsync(cancellationToken); - }); + CompileJob? cj = null; + await databaseContextFactory.UseContext( + async (db) => + cj = await db + .CompileJobs + .AsQueryable() + .Where(x => x.Job.Instance!.Id == metadata.Id) + .OrderByDescending(x => x.Job.StoppedAt) + .FirstOrDefaultAsync(cancellationToken)); try { @@ -229,28 +228,29 @@ namespace Tgstation.Server.Host.Components.Deployment /// #pragma warning disable CA1506 // TODO: Decomplexify - public async ValueTask FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken) + public async ValueTask FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken) { ArgumentNullException.ThrowIfNull(compileJob); // ensure we have the entire metadata tree - logger.LogTrace("Loading compile job {id}...", compileJob.Id); + var compileJobId = compileJob.Require(x => x.Id); + logger.LogTrace("Loading compile job {id}...", compileJobId); await databaseContextFactory.UseContext( async db => compileJob = await db .CompileJobs .AsQueryable() - .Where(x => x.Id == compileJob.Id) - .Include(x => x.Job) + .Where(x => x!.Id == compileJobId) + .Include(x => x.Job!) .ThenInclude(x => x.StartedBy) - .Include(x => x.Job) + .Include(x => x.Job!) .ThenInclude(x => x.Instance) - .Include(x => x.RevisionInformation) - .ThenInclude(x => x.PrimaryTestMerge) - .ThenInclude(x => x.MergedBy) - .Include(x => x.RevisionInformation) - .ThenInclude(x => x.ActiveTestMerges) - .ThenInclude(x => x.TestMerge) - .ThenInclude(x => x.MergedBy) + .Include(x => x.RevisionInformation!) + .ThenInclude(x => x.PrimaryTestMerge!) + .ThenInclude(x => x.MergedBy) + .Include(x => x.RevisionInformation!) + .ThenInclude(x => x.ActiveTestMerges!) + .ThenInclude(x => x.TestMerge!) + .ThenInclude(x => x.MergedBy) .FirstAsync(cancellationToken)); // can't wait to see that query if (!EngineVersion.TryParse(compileJob.EngineVersion, out var engineVersion)) @@ -318,17 +318,17 @@ namespace Tgstation.Server.Host.Components.Deployment lock (jobLockCounts) { - if (!jobLockCounts.TryGetValue(compileJob.Id.Value, out int value)) + if (!jobLockCounts.TryGetValue(compileJobId, out int value)) { value = 1; - jobLockCounts.Add(compileJob.Id.Value, 1); + jobLockCounts.Add(compileJobId, 1); } else - jobLockCounts[compileJob.Id.Value] = ++value; + jobLockCounts[compileJobId] = ++value; providerSubmitted = true; - logger.LogTrace("Compile job {id} lock count now: {lockCount}", compileJob.Id, value); + logger.LogTrace("Compile job {id} lock count now: {lockCount}", compileJobId, value); return newProvider; } } @@ -350,7 +350,7 @@ namespace Tgstation.Server.Host.Components.Deployment lock (jobLockCounts) jobIdsToSkip = jobLockCounts.Keys.ToList(); - List jobUidsToNotErase = null; + List? jobUidsToNotErase = null; // find the uids of locked directories if (jobIdsToSkip.Count > 0) @@ -361,9 +361,9 @@ namespace Tgstation.Server.Host.Components.Deployment .CompileJobs .AsQueryable() .Where( - x => x.Job.Instance.Id == metadata.Id - && jobIdsToSkip.Contains(x.Id.Value)) - .Select(x => x.DirectoryName.Value) + x => x.Job.Instance!.Id == metadata.Id + && jobIdsToSkip.Contains(x.Id!.Value)) + .Select(x => x.DirectoryName!.Value) .ToListAsync(cancellationToken)) .Select(x => x.ToString()) .ToList(); @@ -372,7 +372,7 @@ namespace Tgstation.Server.Host.Components.Deployment else jobUidsToNotErase = new List(); - jobUidsToNotErase.Add(SwappableDmbProvider.LiveGameDirectory); + jobUidsToNotErase!.Add(SwappableDmbProvider.LiveGameDirectory); logger.LogTrace("We will not clean the following directories: {directoriesToNotClean}", String.Join(", ", jobUidsToNotErase)); @@ -407,7 +407,7 @@ namespace Tgstation.Server.Host.Components.Deployment #pragma warning restore CA1506 /// - public CompileJob LatestCompileJob() + public CompileJob? LatestCompileJob() { if (!DmbAvailable) return null; @@ -428,7 +428,7 @@ namespace Tgstation.Server.Host.Components.Deployment // DCT: None available var deploymentJob = remoteDeploymentManager.MarkInactive(job, CancellationToken.None); - var deleteTask = DeleteCompileJobContent(job.DirectoryName.ToString(), cleanupCts.Token); + var deleteTask = DeleteCompileJobContent(job.DirectoryName!.Value.ToString(), cleanupCts.Token); var otherTask = cleanupTask; async Task WrapThrowableTasks() @@ -447,20 +447,23 @@ namespace Tgstation.Server.Host.Components.Deployment } lock (jobLockCounts) - if (jobLockCounts.TryGetValue(job.Id.Value, out var currentVal)) + { + var jobId = job.Require(x => x.Id); + if (jobLockCounts.TryGetValue(jobId, out var currentVal)) if (currentVal == 1) { - jobLockCounts.Remove(job.Id.Value); - logger.LogDebug("Cleaning lock-free compile job {id} => {dirName}", job.Id, job.DirectoryName); + jobLockCounts.Remove(jobId); + logger.LogDebug("Cleaning lock-free compile job {id} => {dirName}", jobId, job.DirectoryName); cleanupTask = HandleCleanup(); } else { - var decremented = --jobLockCounts[job.Id.Value]; - logger.LogTrace("Compile job {id} lock count now: {lockCount}", job.Id, decremented); + var decremented = --jobLockCounts[jobId]; + logger.LogTrace("Compile job {id} lock count now: {lockCount}", jobId, decremented); } else - logger.LogError("Extra Dispose of DmbProvider for CompileJob {compileJobId}!", job.Id); + logger.LogError("Extra Dispose of DmbProvider for CompileJob {compileJobId}!", jobId); + } } /// diff --git a/src/Tgstation.Server.Host/Components/Deployment/IDmbFactory.cs b/src/Tgstation.Server.Host/Components/Deployment/IDmbFactory.cs index 6ff04b0a00..08d1a782b5 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/IDmbFactory.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/IDmbFactory.cs @@ -23,7 +23,7 @@ namespace Tgstation.Server.Host.Components.Deployment bool DmbAvailable { get; } /// - /// Gets the next . + /// Gets the next . is a precondition. /// /// The amount of locks to give the resulting . It's must be called this many times to properly clean the job. /// A new . @@ -35,7 +35,7 @@ namespace Tgstation.Server.Host.Components.Deployment /// The to make the for. /// The for the operation. /// A resulting in a new representing the on success, on failure. - ValueTask FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken); + ValueTask FromCompileJob(CompileJob compileJob, CancellationToken cancellationToken); /// /// Deletes all compile jobs that are inactive in the Game folder. diff --git a/src/Tgstation.Server.Host/Components/Deployment/ILatestCompileJobProvider.cs b/src/Tgstation.Server.Host/Components/Deployment/ILatestCompileJobProvider.cs index 38a90c8dc6..021f62602d 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/ILatestCompileJobProvider.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/ILatestCompileJobProvider.cs @@ -10,7 +10,7 @@ namespace Tgstation.Server.Host.Components.Deployment /// /// Gets the latest . /// - /// The latest . - CompileJob LatestCompileJob(); + /// The latest or if none are available. + CompileJob? LatestCompileJob(); } } diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs index 9e6b2de4a5..38932c5277 100644 --- a/src/Tgstation.Server.Host/Components/Instance.cs +++ b/src/Tgstation.Server.Host/Components/Instance.cs @@ -253,7 +253,7 @@ namespace Tgstation.Server.Host.Components } /// - public CompileJob LatestCompileJob() => dmbFactory.LatestCompileJob(); + public CompileJob? LatestCompileJob() => dmbFactory.LatestCompileJob(); /// /// The for updating the repository. diff --git a/src/Tgstation.Server.Host/Components/InstanceWrapper.cs b/src/Tgstation.Server.Host/Components/InstanceWrapper.cs index 5c525d9869..ba2c84d688 100644 --- a/src/Tgstation.Server.Host/Components/InstanceWrapper.cs +++ b/src/Tgstation.Server.Host/Components/InstanceWrapper.cs @@ -58,6 +58,6 @@ namespace Tgstation.Server.Host.Components public ValueTask SetAutoUpdateInterval(uint newInterval) => Instance.SetAutoUpdateInterval(newInterval); /// - public CompileJob LatestCompileJob() => Instance.LatestCompileJob(); + public CompileJob? LatestCompileJob() => Instance.LatestCompileJob(); } }