diff --git a/build/Version.props b/build/Version.props
index 2bc53dd4cc..43c4a45de6 100644
--- a/build/Version.props
+++ b/build/Version.props
@@ -3,12 +3,12 @@
- 5.12.2
+ 5.12.3
4.6.0
9.10.2
10.4.1
- 11.4.2
- 6.4.4
+ 11.4.3
+ 6.4.5
5.6.1
1.2.2
1.2.1
diff --git a/src/DMAPI/tgs.dm b/src/DMAPI/tgs.dm
index ab2d565991..d7f7deec74 100644
--- a/src/DMAPI/tgs.dm
+++ b/src/DMAPI/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "6.4.4"
+#define TGS_DMAPI_VERSION "6.4.5"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
diff --git a/src/Tgstation.Server.Client/ApiClient.cs b/src/Tgstation.Server.Client/ApiClient.cs
index 649745b609..9913a10184 100644
--- a/src/Tgstation.Server.Client/ApiClient.cs
+++ b/src/Tgstation.Server.Client/ApiClient.cs
@@ -305,18 +305,26 @@ namespace Tgstation.Server.Client
if (content != null)
request.Content = content;
- var headersToUse = tokenRefresh ? tokenRefreshHeaders! : headers;
- headersToUse.SetRequestHeaders(request.Headers, instanceId);
+ try
+ {
+ var headersToUse = tokenRefresh ? tokenRefreshHeaders! : headers;
+ headersToUse.SetRequestHeaders(request.Headers, instanceId);
- if (authless)
- request.Headers.Remove(HeaderNames.Authorization);
+ if (authless)
+ request.Headers.Remove(HeaderNames.Authorization);
- if (fileDownload)
- request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Octet));
+ if (fileDownload)
+ request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Octet));
- await Task.WhenAll(requestLoggers.Select(x => x.LogRequest(request, cancellationToken))).ConfigureAwait(false);
+ await Task.WhenAll(requestLoggers.Select(x => x.LogRequest(request, cancellationToken))).ConfigureAwait(false);
- response = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);
+ response = await httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);
+ }
+ finally
+ {
+ // prevent content param from getting disposed
+ request.Content = null;
+ }
}
try
diff --git a/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs b/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs
index 49456d01ae..157107228a 100644
--- a/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs
+++ b/src/Tgstation.Server.Host/Components/Byond/ByondManager.cs
@@ -423,10 +423,10 @@ namespace Tgstation.Server.Host.Components.Byond
{
if (customVersionStream != null)
{
- int customInstallationNumber = 1;
+ var customInstallationNumber = 1;
do
{
- version = new Version(version.Major, version.Minor, customInstallationNumber);
+ version = new Version(version.Major, version.Minor, customInstallationNumber++);
}
while (installedVersions.ContainsKey(version));
}
diff --git a/src/Tgstation.Server.Host/Jobs/JobManager.cs b/src/Tgstation.Server.Host/Jobs/JobManager.cs
index 88828baca2..cac6b4fab3 100644
--- a/src/Tgstation.Server.Host/Jobs/JobManager.cs
+++ b/src/Tgstation.Server.Host/Jobs/JobManager.cs
@@ -54,6 +54,11 @@ namespace Tgstation.Server.Host.Jobs
///
readonly object addCancelLock;
+ ///
+ /// Prevents jobs that are registered after shutdown from activating.
+ ///
+ volatile bool noMoreJobsShouldStart;
+
///
/// Initializes a new instance of the class.
///
@@ -122,10 +127,15 @@ namespace Tgstation.Server.Host.Jobs
{
lock (addCancelLock)
{
+ bool jobShouldStart;
lock (synchronizationLock)
+ {
jobs.Add(job.Id.Value, jobHandler);
+ jobShouldStart = !noMoreJobsShouldStart;
+ }
- jobHandler.Start();
+ if (jobShouldStart)
+ jobHandler.Start();
}
}
catch
@@ -145,8 +155,7 @@ namespace Tgstation.Server.Host.Jobs
.AsQueryable()
.Where(y => !y.StoppedAt.HasValue)
.Select(y => y.Id)
- .ToListAsync(cancellationToken)
- ;
+ .ToListAsync(cancellationToken);
if (badJobIds.Count > 0)
{
logger.LogTrace("Cleaning {unfinishedJobCount} unfinished jobs...", badJobIds.Count);
@@ -160,19 +169,29 @@ namespace Tgstation.Server.Host.Jobs
await databaseContext.Save(cancellationToken);
}
+
+ noMoreJobsShouldStart = false;
});
///
public async Task StopAsync(CancellationToken cancellationToken)
{
- var joinTasks = jobs.Select(x => CancelJob(
- new Job
+ List> joinTasks;
+ lock (addCancelLock)
+ lock (synchronizationLock)
{
- Id = x.Key,
- },
- null,
- true,
- cancellationToken));
+ noMoreJobsShouldStart = true;
+ joinTasks = jobs.Select(x => CancelJob(
+ new Job
+ {
+ Id = x.Key,
+ },
+ null,
+ true,
+ cancellationToken))
+ .ToList();
+ }
+
await Task.WhenAll(joinTasks);
}
diff --git a/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs
index 84faa305df..8eac19aaf9 100644
--- a/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs
+++ b/tests/Tgstation.Server.Tests/Live/Instance/ByondTest.cs
@@ -59,6 +59,12 @@ namespace Tgstation.Server.Tests.Live.Instance
async Task TestDeletes(CancellationToken cancellationToken)
{
+ var deleteThisOneBecauseItWasntPartOfTheOriginalTest = await byondClient.DeleteVersion(new ByondVersionDeleteRequest
+ {
+ Version = new(TestVersion.Major, TestVersion.Minor, 2)
+ }, cancellationToken);
+ await WaitForJob(deleteThisOneBecauseItWasntPartOfTheOriginalTest, 30, false, null, cancellationToken);
+
var nonExistentUninstallResponseTask = Assert.ThrowsExceptionAsync(() => byondClient.DeleteVersion(
new ByondVersionDeleteRequest
{
@@ -182,14 +188,27 @@ namespace Tgstation.Server.Tests.Live.Instance
UploadCustomZip = true
},
stableBytesMs,
- cancellationToken)
- ;
+ cancellationToken);
Assert.IsNotNull(test.InstallJob);
- await WaitForJob(test.InstallJob, 60, false, null, cancellationToken);
+ await WaitForJob(test.InstallJob, 30, false, null, cancellationToken);
+
+ // do it again. #1501
+ stableBytesMs.Seek(0, SeekOrigin.Begin);
+ var test2 = await byondClient.SetActiveVersion(
+ new ByondVersionRequest
+ {
+ Version = TestVersion,
+ UploadCustomZip = true
+ },
+ stableBytesMs,
+ cancellationToken);
+
+ Assert.IsNotNull(test2.InstallJob);
+ await WaitForJob(test2.InstallJob, 30, false, null, cancellationToken);
var newSettings = await byondClient.ActiveVersion(cancellationToken);
- Assert.AreEqual(new Version(TestVersion.Major, TestVersion.Minor, 1), newSettings.Version);
+ Assert.AreEqual(new Version(TestVersion.Major, TestVersion.Minor, 2), newSettings.Version);
// test a few switches
var installResponse = await byondClient.SetActiveVersion(new ByondVersionRequest
@@ -199,7 +218,7 @@ namespace Tgstation.Server.Tests.Live.Instance
Assert.IsNull(installResponse.InstallJob);
await ApiAssert.ThrowsException(() => byondClient.SetActiveVersion(new ByondVersionRequest
{
- Version = new Version(TestVersion.Major, TestVersion.Minor, 2)
+ Version = new Version(TestVersion.Major, TestVersion.Minor, 3)
}, null, cancellationToken), ErrorCode.ByondNonExistentCustomVersion);
installResponse = await byondClient.SetActiveVersion(new ByondVersionRequest
diff --git a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs
index b3a7596c5f..1ade1e1c5a 100644
--- a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs
+++ b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs
@@ -765,6 +765,8 @@ namespace Tgstation.Server.Tests.Live
}
}
}
+ else
+ await internalTask;
}
async Task TestTgsInternal(CancellationToken hardCancellationToken)
@@ -845,7 +847,7 @@ namespace Tgstation.Server.Tests.Live
}
catch (Exception ex)
{
- System.Console.WriteLine($"[{DateTimeOffset.UtcNow}] TEST ERROR: {ex}");
+ Console.WriteLine($"[{DateTimeOffset.UtcNow}] TEST ERROR: {ex}");
serverCts.Cancel();
throw;
}
@@ -855,8 +857,8 @@ namespace Tgstation.Server.Tests.Live
var adminTest = FailFast(new AdministrationTest(adminClient.Administration).Run(cancellationToken));
var usersTest = FailFast(new UsersTest(adminClient).Run(cancellationToken));
var instanceMangagerTest = new InstanceManagerTest(adminClient, server.Directory);
- var instancesTest = FailFast(instanceMangagerTest.RunPreTest(cancellationToken));
instance = await instanceMangagerTest.CreateTestInstance(cancellationToken);
+ var instancesTest = FailFast(instanceMangagerTest.RunPreTest(cancellationToken));
Assert.IsTrue(Directory.Exists(instance.Path));
var instanceClient = adminClient.Instances.CreateClient(instance);