diff --git a/.github/workflows/ci-suite.yml b/.github/workflows/ci-suite.yml
index ccdaa58af9..1e2b15aef8 100644
--- a/.github/workflows/ci-suite.yml
+++ b/.github/workflows/ci-suite.yml
@@ -146,7 +146,7 @@ jobs:
doxyfile-path: 'docs/Doxyfile'
- name: gh-pages push
- if: github.event_name == 'push' && github.event.ref == 'refs/heads/dev'
+ if: github.event_name == 'push' && github.event.ref == 'refs/heads/dev' && env.TGS_RELEASE_NOTES_TOKEN != ''
run: |
git clone -b gh-pages --single-branch "https://git@github.com/tgstation/tgstation-server" $HOME/tgsdox
pushd $HOME/tgsdox
diff --git a/SECURITY.md b/SECURITY.md
index 5d79c18579..1e624e68bb 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -16,6 +16,6 @@ Vulnerabilities should ideally be reported by directly messaging one of the TGS
Here is a list of their discord IDs.
-@Cyberboss - Dominion#0444 (<@133295178197893120>)
+@Cyberboss - dominion (<@133295178197893120>)
Once reported, they will handle the processing of the security advisory.
diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs
index f9ef3396c6..bfc541e6f9 100644
--- a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs
@@ -309,7 +309,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
cancellationToken);
// DCT: Always wait for the job to complete here
- await jobManager.WaitForJobCompletion(job, null, cancellationToken, default);
+ await jobManager.WaitForJobCompletion(job, null, cancellationToken, cancellationToken);
}
}
catch (OperationCanceledException e)
diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs
index 95ca246c42..0e441edb15 100644
--- a/src/Tgstation.Server.Host/Components/Instance.cs
+++ b/src/Tgstation.Server.Host/Components/Instance.cs
@@ -514,11 +514,9 @@ namespace Tgstation.Server.Host.Components
await jobManager.RegisterOperation(
repositoryUpdateJob,
RepositoryAutoUpdateJob,
- cancellationToken)
- ;
+ cancellationToken);
- // DCT: First token will cancel the job, second is for cancelling the cancellation, unwanted
- await jobManager.WaitForJobCompletion(repositoryUpdateJob, null, cancellationToken, default);
+ await jobManager.WaitForJobCompletion(repositoryUpdateJob, null, cancellationToken, cancellationToken);
Job compileProcessJob;
using (var repo = await RepositoryManager.LoadRepository(cancellationToken))
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
index 725f99fb3a..258ab9709c 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
@@ -854,7 +854,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
var heartbeatSeconds = ActiveLaunchParameters.HeartbeatSeconds.Value;
var heartbeat = heartbeatSeconds == 0
|| !controller.DMApiAvailable
- ? Extensions.TaskExtensions.InfiniteTask()
+ ? Extensions.TaskExtensions.InfiniteTask
: Task.Delay(
TimeSpan.FromSeconds(heartbeatSeconds),
cancellationToken);
diff --git a/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs b/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs
index a8ee467d1e..bd65a629d9 100644
--- a/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs
+++ b/src/Tgstation.Server.Host/Extensions/TaskExtensions.cs
@@ -14,6 +14,11 @@ namespace Tgstation.Server.Host.Extensions
///
static readonly TaskCompletionSource InfiniteTaskCompletionSource = new ();
+ ///
+ /// Gets a that never completes.
+ ///
+ public static Task InfiniteTask => InfiniteTaskCompletionSource.Task;
+
///
/// Create a that can be awaited while respecting a given .
///
@@ -53,11 +58,5 @@ namespace Tgstation.Server.Host.Extensions
return await task;
}
-
- ///
- /// Creates a that never completes.
- ///
- /// A never ending .
- public static Task InfiniteTask() => InfiniteTaskCompletionSource.Task;
}
}
diff --git a/src/Tgstation.Server.Host/Jobs/JobHandler.cs b/src/Tgstation.Server.Host/Jobs/JobHandler.cs
index 19941fbefd..98cbe88651 100644
--- a/src/Tgstation.Server.Host/Jobs/JobHandler.cs
+++ b/src/Tgstation.Server.Host/Jobs/JobHandler.cs
@@ -11,6 +11,21 @@ namespace Tgstation.Server.Host.Jobs
///
sealed class JobHandler : IDisposable
{
+ ///
+ /// If the job has started.
+ ///
+ public bool Started => task != null;
+
+ ///
+ /// The progress of the job.
+ ///
+ public int? Progress { get; set; }
+
+ ///
+ /// The stage of the job.
+ ///
+ public string Stage { get; set; }
+
///
/// The for .
///
@@ -39,16 +54,6 @@ namespace Tgstation.Server.Host.Jobs
///
public void Dispose() => cancellationTokenSource.Dispose();
- ///
- /// The progress of the job.
- ///
- public int? Progress { get; set; }
-
- ///
- /// The stage of the job.
- ///
- public string Stage { get; set; }
-
///
/// Wait for to complete.
///
diff --git a/src/Tgstation.Server.Host/Jobs/JobService.cs b/src/Tgstation.Server.Host/Jobs/JobService.cs
index c0d01f2dcf..971150061a 100644
--- a/src/Tgstation.Server.Host/Jobs/JobService.cs
+++ b/src/Tgstation.Server.Host/Jobs/JobService.cs
@@ -256,13 +256,23 @@ namespace Tgstation.Server.Host.Jobs
{
if (job == null)
throw new ArgumentNullException(nameof(job));
+
+ if (!cancellationToken.CanBeCanceled)
+ throw new ArgumentException("A cancellable CancellationToken should be provided!", nameof(cancellationToken));
+
JobHandler handler;
+ bool noMoreJobsShouldStart;
lock (synchronizationLock)
{
if (!jobs.TryGetValue(job.Id.Value, out handler))
return;
+
+ noMoreJobsShouldStart = this.noMoreJobsShouldStart;
}
+ if (noMoreJobsShouldStart && !handler.Started)
+ await Extensions.TaskExtensions.InfiniteTask.WithToken(cancellationToken);
+
Task cancelTask = null;
using (jobCancellationToken.Register(() => cancelTask = CancelJob(job, canceller, true, cancellationToken)))
await handler.Wait(cancellationToken);
diff --git a/src/Tgstation.Server.Host/Swarm/SwarmService.cs b/src/Tgstation.Server.Host/Swarm/SwarmService.cs
index d53456c8ac..8f8a5ce7a9 100644
--- a/src/Tgstation.Server.Host/Swarm/SwarmService.cs
+++ b/src/Tgstation.Server.Host/Swarm/SwarmService.cs
@@ -380,7 +380,7 @@ namespace Tgstation.Server.Host.Swarm
? asyncDelayer.Delay(
TimeSpan.FromMinutes(UpdateCommitTimeoutMinutes),
cancellationToken)
- : Extensions.TaskExtensions.InfiniteTask().WithToken(cancellationToken);
+ : Extensions.TaskExtensions.InfiniteTask.WithToken(cancellationToken);
var commitTask = Task.WhenAny(commitTcsTask, timeoutTask);
diff --git a/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs
index c35ccd70dd..05f3b90ec2 100644
--- a/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs
+++ b/tests/Tgstation.Server.Tests/Live/Instance/RepositoryTest.cs
@@ -59,8 +59,8 @@ namespace Tgstation.Server.Tests.Live.Instance
if (!targetActiveJob.Progress.HasValue)
{
- // give it 15 more seconds
- targetActiveJob = await WaitForJobProgress(targetActiveJob, 15, cancellationToken);
+ // give it a few more seconds
+ targetActiveJob = await WaitForJobProgress(targetActiveJob, 30, cancellationToken);
allJobs = await JobsClient.List(null, cancellationToken);
}
diff --git a/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs
index 3b08f87812..c97cac3308 100644
--- a/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs
+++ b/tests/Tgstation.Server.Tests/Live/Instance/WatchdogTest.cs
@@ -246,7 +246,14 @@ namespace Tgstation.Server.Tests.Live.Instance
jobTcs.SetResult();
await killTask;
}
- Assert.IsTrue(job.ErrorCode == ErrorCode.DreamDaemonOffline || job.ErrorCode == ErrorCode.GCoreFailure, $"{job.ErrorCode}: {job.ExceptionDetails}");
+
+ // these can also happen
+ if (!(new PlatformIdentifier().IsWindows
+ && (job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: E_ACCESSDENIED: Access is denied.")
+ || job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: E_HANDLE: The handle is invalid.")
+ || job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: 3489660936: Unknown error (0xd0000008)")))) // kek
+ Assert.IsTrue(job.ErrorCode == ErrorCode.DreamDaemonOffline || job.ErrorCode == ErrorCode.GCoreFailure, $"{job.ErrorCode}: {job.ExceptionDetails}");
+
await Task.Delay(TimeSpan.FromSeconds(20), cancellationToken);
var ddStatus = await instanceClient.DreamDaemon.Read(cancellationToken);
@@ -531,7 +538,7 @@ namespace Tgstation.Server.Tests.Live.Instance
TopicResponse topicRequestResult = null;
try
{
- System.Console.WriteLine($"Topic limit test S:{payloadSize}...");
+ System.Console.WriteLine($"Topic send limit test S:{currentSize}...");
topicRequestResult = await TopicClientNoLogger.SendTopic(
IPAddress.Loopback,
$"tgs_integration_test_tactics3={TopicClient.SanitizeString(JsonConvert.SerializeObject(topic, DMApiConstants.SerializerSettings))}",
@@ -563,6 +570,8 @@ namespace Tgstation.Server.Tests.Live.Instance
Assert.AreEqual(DMApiConstants.MaximumTopicRequestLength, (uint)lastSize);
+ System.Console.WriteLine("TEST: Receiving Topic tests topics...");
+
// Receive
baseSize = 1;
nextPow = 0;
@@ -570,6 +579,7 @@ namespace Tgstation.Server.Tests.Live.Instance
while (!cancellationToken.IsCancellationRequested)
{
var currentSize = baseSize + (int)Math.Pow(2, nextPow);
+ System.Console.WriteLine($"Topic recieve limit test S:{currentSize}...");
var topicRequestResult = await TopicClientNoLogger.SendTopic(
IPAddress.Loopback,
$"tgs_integration_test_tactics4={TopicClient.SanitizeString(currentSize.ToString())}",