diff --git a/build/Version.props b/build/Version.props
index 18219375ac..a6146fedf0 100644
--- a/build/Version.props
+++ b/build/Version.props
@@ -3,7 +3,7 @@
- 6.11.3
+ 6.11.4
5.3.0
10.10.0
0.2.0
diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs
index eff31ebb25..f0edb6fc09 100644
--- a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs
+++ b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs
@@ -140,9 +140,9 @@ sealed class Configuration : IConfiguration
readonly SemaphoreSlim semaphore;
///
- /// The that is triggered when is called.
+ /// The that is triggered when is called.
///
- readonly CancellationTokenSource disposeCts;
+ readonly CancellationTokenSource stoppingCts;
///
/// The culmination of all upload file transfer callbacks.
@@ -186,7 +186,7 @@ public Configuration(
this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration));
semaphore = new SemaphoreSlim(1, 1);
- disposeCts = new CancellationTokenSource();
+ stoppingCts = new CancellationTokenSource();
uploadTasks = Task.CompletedTask;
}
@@ -194,8 +194,7 @@ public Configuration(
public void Dispose()
{
semaphore.Dispose();
- disposeCts.Cancel();
- disposeCts.Dispose();
+ stoppingCts.Dispose();
}
///
@@ -310,7 +309,7 @@ string GetFileSha()
var originalSha = GetFileSha();
- var disposeToken = disposeCts.Token;
+ var disposeToken = stoppingCts.Token;
var fileTicket = fileTransferService.CreateDownload(
new FileDownloadProvider(
() =>
@@ -472,7 +471,7 @@ void WriteImpl()
try
{
var fileTicket = fileTransferService.CreateUpload(FileUploadStreamKind.ForSynchronousIO);
- var uploadCancellationToken = disposeCts.Token;
+ var uploadCancellationToken = stoppingCts.Token;
async Task UploadHandler()
{
await using (fileTicket)
@@ -491,7 +490,7 @@ async Task UploadHandler()
void WriteCallback()
{
logger.LogTrace("Running synchronous write...");
- success = synchronousIOManager.WriteFileChecked(path, uploadStream, ref fileHash, cancellationToken);
+ success = synchronousIOManager.WriteFileChecked(path, uploadStream, ref fileHash, uploadCancellationToken);
logger.LogTrace("Finished write {un}successfully!", success ? String.Empty : "un");
}
@@ -511,9 +510,9 @@ void WriteCallback()
logger.LogTrace("Kicking off write callback");
if (systemIdentity == null)
- await Task.Factory.StartNew(WriteCallback, cancellationToken, DefaultIOManager.BlockingTaskCreationOptions, TaskScheduler.Current);
+ await Task.Factory.StartNew(WriteCallback, uploadCancellationToken, DefaultIOManager.BlockingTaskCreationOptions, TaskScheduler.Current);
else
- await systemIdentity.RunImpersonated(WriteCallback, cancellationToken);
+ await systemIdentity.RunImpersonated(WriteCallback, uploadCancellationToken);
}
if (!success)
@@ -534,8 +533,24 @@ void WriteCallback()
Path = configurationRelativePath,
};
- lock (disposeCts)
- uploadTasks = Task.WhenAll(uploadTasks, UploadHandler());
+ lock (stoppingCts)
+ {
+ async Task ChainUploadTasks()
+ {
+ var oldUploadTask = uploadTasks;
+ var newUploadTask = UploadHandler();
+ try
+ {
+ await oldUploadTask;
+ }
+ finally
+ {
+ await newUploadTask;
+ }
+ }
+
+ uploadTasks = ChainUploadTasks();
+ }
}
catch (UnauthorizedAccessException)
{
@@ -609,7 +624,24 @@ void WriteCallback()
public Task StartAsync(CancellationToken cancellationToken) => EnsureDirectories(cancellationToken);
///
- public Task StopAsync(CancellationToken cancellationToken) => EnsureDirectories(cancellationToken);
+ public async Task StopAsync(CancellationToken cancellationToken)
+ {
+ await EnsureDirectories(cancellationToken);
+
+ stoppingCts.Cancel();
+ try
+ {
+ await uploadTasks;
+ }
+ catch (OperationCanceledException ex)
+ {
+ logger.LogDebug(ex, "One or more uploads/downloads were aborted!");
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "Error awaiting upload tasks!");
+ }
+ }
///
public ValueTask HandleEvent(EventType eventType, IEnumerable parameters, bool deploymentPipeline, CancellationToken cancellationToken)