diff --git a/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs b/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs index 3ab6670c..bc12f5d0 100644 --- a/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs +++ b/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs @@ -143,7 +143,9 @@ public static partial class Operations } // Shoot out the total children count, wasteful - var count = (await ClosureParser.GetClosuresAsync(objString).ConfigureAwait(false)).Count; + var count = ( + await ClosureParser.GetClosuresAsync(objString, localTransport.CancellationToken).ConfigureAwait(false) + ).Count; onTotalChildrenCountKnown?.Invoke(count); diff --git a/src/Speckle.Sdk/Serialisation/Utilities/ClosureParser.cs b/src/Speckle.Sdk/Serialisation/Utilities/ClosureParser.cs index 3fb4b37b..70598054 100644 --- a/src/Speckle.Sdk/Serialisation/Utilities/ClosureParser.cs +++ b/src/Speckle.Sdk/Serialisation/Utilities/ClosureParser.cs @@ -5,24 +5,27 @@ namespace Speckle.Sdk.Serialisation.Utilities; public static class ClosureParser { - public static async Task> GetClosuresAsync(string rootObjectJson) + public static async Task> GetClosuresAsync( + string rootObjectJson, + CancellationToken cancellationToken = default + ) { try { using JsonTextReader reader = new(new StringReader(rootObjectJson)); - reader.Read(); + await reader.ReadAsync(cancellationToken).ConfigureAwait(false); while (reader.TokenType != JsonToken.EndObject) { switch (reader.TokenType) { case JsonToken.StartObject: { - var closureList = await ReadObjectAsync(reader).ConfigureAwait(false); + var closureList = await ReadObjectAsync(reader, cancellationToken).ConfigureAwait(false); return closureList; } default: - reader.Read(); - reader.Skip(); + await reader.ReadAsync(cancellationToken).ConfigureAwait(false); + await reader.SkipAsync(cancellationToken).ConfigureAwait(false); break; } } @@ -31,12 +34,17 @@ public static class ClosureParser return []; } - public static async Task> GetChildrenIdsAsync(string rootObjectJson) => - (await GetClosuresAsync(rootObjectJson).ConfigureAwait(false)).Select(x => x.Item1); + public static async Task> GetChildrenIdsAsync( + string rootObjectJson, + CancellationToken cancellationToken = default + ) => (await GetClosuresAsync(rootObjectJson, cancellationToken).ConfigureAwait(false)).Select(x => x.Item1); - private static async Task> ReadObjectAsync(JsonTextReader reader) + private static async Task> ReadObjectAsync( + JsonTextReader reader, + CancellationToken cancellationToken + ) { - await reader.ReadAsync().ConfigureAwait(false); + await reader.ReadAsync(cancellationToken).ConfigureAwait(false); while (reader.TokenType != JsonToken.EndObject) { switch (reader.TokenType) @@ -45,19 +53,19 @@ public static class ClosureParser { if (reader.Value as string == "__closure") { - await reader.ReadAsync().ConfigureAwait(false); //goes to prop vale + await reader.ReadAsync(cancellationToken).ConfigureAwait(false); //goes to prop vale var closureList = await ReadClosureEnumerableAsync(reader).ConfigureAwait(false); return closureList; } - await reader.ReadAsync().ConfigureAwait(false); //goes to prop vale - await reader.SkipAsync().ConfigureAwait(false); - await reader.ReadAsync().ConfigureAwait(false); //goes to next + await reader.ReadAsync(cancellationToken).ConfigureAwait(false); //goes to prop vale + await reader.SkipAsync(cancellationToken).ConfigureAwait(false); + await reader.ReadAsync(cancellationToken).ConfigureAwait(false); //goes to next } break; default: - await reader.ReadAsync().ConfigureAwait(false); - await reader.SkipAsync().ConfigureAwait(false); - await reader.ReadAsync().ConfigureAwait(false); + await reader.ReadAsync(cancellationToken).ConfigureAwait(false); + await reader.SkipAsync(cancellationToken).ConfigureAwait(false); + await reader.ReadAsync(cancellationToken).ConfigureAwait(false); break; } } diff --git a/src/Speckle.Sdk/Transports/ServerTransport.cs b/src/Speckle.Sdk/Transports/ServerTransport.cs index c544087f..517e8bad 100644 --- a/src/Speckle.Sdk/Transports/ServerTransport.cs +++ b/src/Speckle.Sdk/Transports/ServerTransport.cs @@ -126,7 +126,9 @@ public sealed class ServerTransport : IServerTransport api.CancellationToken = CancellationToken; string? rootObjectJson = await api.DownloadSingleObject(StreamId, id, OnProgressAction).ConfigureAwait(false); - var allIds = (await ClosureParser.GetChildrenIdsAsync(rootObjectJson.NotNull()).ConfigureAwait(false)).ToList(); + var allIds = ( + await ClosureParser.GetChildrenIdsAsync(rootObjectJson.NotNull(), CancellationToken).ConfigureAwait(false) + ).ToList(); var childrenIds = allIds.Where(x => !x.Contains("blob:")); var blobIds = allIds.Where(x => x.Contains("blob:")).Select(x => x.Remove(0, 5)); diff --git a/src/Speckle.Sdk/Transports/TransportHelpers.cs b/src/Speckle.Sdk/Transports/TransportHelpers.cs index 5c239140..7111d193 100644 --- a/src/Speckle.Sdk/Transports/TransportHelpers.cs +++ b/src/Speckle.Sdk/Transports/TransportHelpers.cs @@ -30,7 +30,7 @@ public static class TransportHelpers targetTransport.SaveObject(id, parent); - var closures = (await ClosureParser.GetChildrenIdsAsync(parent).ConfigureAwait(false)).ToList(); + var closures = (await ClosureParser.GetChildrenIdsAsync(parent, cancellationToken).ConfigureAwait(false)).ToList(); onTotalChildrenCountKnown?.Invoke(closures.Count);