diff --git a/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs b/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs index 392f1195..a05ba4c3 100644 --- a/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs +++ b/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs @@ -24,7 +24,7 @@ public partial class Operations try { - var process = serializeProcessFactory.CreateDeserializeProcess( + using var process = serializeProcessFactory.CreateDeserializeProcess( url, streamId, authorizationToken, diff --git a/src/Speckle.Sdk/Serialisation/V2/Send/PriorityScheduler.cs b/src/Speckle.Sdk/Serialisation/V2/Send/PriorityScheduler.cs index 924da3c1..a35a5b54 100644 --- a/src/Speckle.Sdk/Serialisation/V2/Send/PriorityScheduler.cs +++ b/src/Speckle.Sdk/Serialisation/V2/Send/PriorityScheduler.cs @@ -11,6 +11,7 @@ public sealed class PriorityScheduler( ) : TaskScheduler, IDisposable { #pragma warning disable CA2213 + //intentionally not disposing this because syncing to when all the threads are done AFTER the BC is done/disposed is hard. BC will still be cleaned up by the finalizer private readonly BlockingCollection _tasks = new(); #pragma warning restore CA2213 private Thread[]? _threads; @@ -37,23 +38,30 @@ public sealed class PriorityScheduler( { try { - foreach (Task t in _tasks.GetConsumingEnumerable(cancellationToken)) + while (true) { + //we're done so leave + if (_tasks.IsCompleted || cancellationToken.IsCancellationRequested) + { + break; + } + var success = _tasks.TryTake(out var t, TimeSpan.FromSeconds(1)); + //no task and we're done so leave + if (success && _tasks.IsCompleted) + { + break; + } + //cancelled just leave if (cancellationToken.IsCancellationRequested) { break; } - - TryExecuteTask(t); - if (cancellationToken.IsCancellationRequested) + //didn't get a task but just timed out so continue + if (!success) { - break; + continue; } - } - - if (_tasks.IsCompleted) - { - _tasks.Dispose(); + TryExecuteTask(t ?? throw new InvalidOperationException("Task was null")); } } catch (OperationCanceledException) diff --git a/tests/Speckle.Sdk.Tests.Integration/Api/GraphQL/Resources/CommentResourceTests.cs b/tests/Speckle.Sdk.Tests.Integration/Api/GraphQL/Resources/CommentResourceTests.cs index b7071c27..80611b01 100644 --- a/tests/Speckle.Sdk.Tests.Integration/Api/GraphQL/Resources/CommentResourceTests.cs +++ b/tests/Speckle.Sdk.Tests.Integration/Api/GraphQL/Resources/CommentResourceTests.cs @@ -9,27 +9,33 @@ using Version = Speckle.Sdk.Api.GraphQL.Models.Version; namespace Speckle.Sdk.Tests.Integration.API.GraphQL.Resources; -public class CommentResourceTests +public class CommentResourceTests : IAsyncLifetime { - private readonly Client _testUser; - private readonly CommentResource Sut; - private readonly Project _project; - private readonly Model _model; - private readonly Version _version; - private readonly Comment _comment; + private Client _testUser; + private CommentResource Sut; + private Project _project; + private Model _model; + private Version _version; + private Comment _comment; // Constructor for setup - public CommentResourceTests() + public async Task InitializeAsync() { // Synchronous operations converted to async Task.Run for constructor - _testUser = Task.Run(async () => await Fixtures.SeedUserWithClient()).Result; - _project = Task.Run(async () => await _testUser.Project.Create(new("Test project", "", null))).Result; - _model = Task.Run(async () => await _testUser.Model.Create(new("Test Model 1", "", _project.id))).Result; - _version = Task.Run(async () => await Fixtures.CreateVersion(_testUser, _project.id, _model.id)).Result; - _comment = Task.Run(CreateComment).Result!; + _testUser = await Fixtures.SeedUserWithClient(); + _project = await _testUser.Project.Create(new("Test project", "", null)); + _model = await _testUser.Model.Create(new("Test Model 1", "", _project.id)); + _version = await Fixtures.CreateVersion(_testUser, _project.id, _model.id); + _comment = await CreateComment(); Sut = _testUser.Comment; } + public Task DisposeAsync() + { + // No resources to dispose + return Task.CompletedTask; + } + [Fact] public async Task Get() {