diff --git a/Directory.Packages.props b/Directory.Packages.props index 6aec7d26..b442fb0c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -9,27 +9,27 @@ - + - - - - - + + + + + - + - + - + diff --git a/Speckle.Sdk.sln b/Speckle.Sdk.sln index 747037dc..2aea6658 100644 --- a/Speckle.Sdk.sln +++ b/Speckle.Sdk.sln @@ -46,7 +46,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Sdk.Serialization.T EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Sdk.Dependencies", "src\Speckle.Sdk.Dependencies\Speckle.Sdk.Dependencies.csproj", "{27584AB4-8ACD-4850-8CC2-7E5BC739FB78}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Sdk.Testing", "Speckle.Sdk.Testing\Speckle.Sdk.Testing.csproj", "{7B617C0D-2354-415C-993C-5071D4113E27}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Sdk.Testing", "tests\Speckle.Sdk.Testing\Speckle.Sdk.Testing.csproj", "{7B617C0D-2354-415C-993C-5071D4113E27}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "performance", "performance", "{FFB07238-87E8-463A-AA39-3B38AAAA94C1}" EndProject diff --git a/src/Speckle.Objects/Geometry/Mesh.cs b/src/Speckle.Objects/Geometry/Mesh.cs index 27f2e60a..e28df42d 100644 --- a/src/Speckle.Objects/Geometry/Mesh.cs +++ b/src/Speckle.Objects/Geometry/Mesh.cs @@ -44,6 +44,13 @@ public class Mesh : Base, IHasBoundingBox, IHasVolume, IHasArea, ITransformable< [DetachProperty, Chunkable(31250)] public List textureCoordinates { get; set; } = new(); + /// + /// Flat list of vertex normal data (flat x,y,z,x,y,z... list) + /// Expected that there are either 1 texture coordinate per vertex, or an empty + /// + [DetachProperty, Chunkable(31250)] + public List vertexNormals { get; set; } = new(); + /// /// The unit's this is in. /// This should be one of diff --git a/src/Speckle.Objects/packages.lock.json b/src/Speckle.Objects/packages.lock.json index ca407eef..8a87b684 100644 --- a/src/Speckle.Objects/packages.lock.json +++ b/src/Speckle.Objects/packages.lock.json @@ -228,12 +228,12 @@ "type": "Project", "dependencies": { "GraphQL.Client": "[6.0.0, )", - "Microsoft.Bcl.AsyncInterfaces": "[5.0.0, 5.0.0]", + "Microsoft.Bcl.AsyncInterfaces": "[5.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -254,7 +254,7 @@ }, "Microsoft.Bcl.AsyncInterfaces": { "type": "CentralTransitive", - "requested": "[5.0.0, 5.0.0]", + "requested": "[5.0.0, )", "resolved": "5.0.0", "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==", "dependencies": { @@ -269,7 +269,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -279,13 +279,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -297,9 +297,9 @@ }, "Speckle.DoubleNumerics": { "type": "CentralTransitive", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.Newtonsoft.Json": { "type": "CentralTransitive", @@ -473,10 +473,10 @@ "dependencies": { "GraphQL.Client": "[6.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -503,7 +503,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -513,13 +513,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -531,9 +531,9 @@ }, "Speckle.DoubleNumerics": { "type": "CentralTransitive", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.Newtonsoft.Json": { "type": "CentralTransitive", diff --git a/src/Speckle.Sdk.Dependencies/Collections.cs b/src/Speckle.Sdk.Dependencies/Collections.cs index 8dcd778e..aa622c83 100644 --- a/src/Speckle.Sdk.Dependencies/Collections.cs +++ b/src/Speckle.Sdk.Dependencies/Collections.cs @@ -4,7 +4,14 @@ namespace Speckle.Sdk.Dependencies; public static class Collections { - public static IReadOnlyCollection Freeze(this IEnumerable source) => source.ToFrozenSet(); +#if NET5_0_OR_GREATER + public static IReadOnlySet Freeze(this IEnumerable source) +#else + public static IReadOnlyCollection Freeze(this IEnumerable source) +#endif + { + return source.ToFrozenSet(); + } public static IReadOnlyDictionary Freeze( this IEnumerable> source diff --git a/src/Speckle.Sdk.Dependencies/Serialization/Batch.cs b/src/Speckle.Sdk.Dependencies/Serialization/Batch.cs index fb6bb14c..b65a406b 100644 --- a/src/Speckle.Sdk.Dependencies/Serialization/Batch.cs +++ b/src/Speckle.Sdk.Dependencies/Serialization/Batch.cs @@ -3,28 +3,28 @@ using Speckle.Sdk.Dependencies; namespace Speckle.Sdk.Serialisation.V2.Send; -public sealed class Batch : IHasSize, IMemoryOwner - where T : IHasSize +public sealed class Batch : IMemoryOwner + where T : IHasByteSize { private static readonly Pool> _pool = Pools.CreateListPool(); #pragma warning disable IDE0032 private readonly List _items = _pool.Get(); - private int _batchSize; + private int _batchByteSize; #pragma warning restore IDE0032 public void Add(T item) { _items.Add(item); - _batchSize += item.Size; + _batchByteSize += item.ByteSize; } public void TrimExcess() { _items.TrimExcess(); - _batchSize = _items.Sum(x => x.Size); + _batchByteSize = _items.Sum(x => x.ByteSize); } - public int Size => _batchSize; + public int BatchByteSize => _batchByteSize; public List Items => _items; public void Dispose() => _pool.Return(_items); diff --git a/src/Speckle.Sdk.Dependencies/Serialization/BatchExtensions.cs b/src/Speckle.Sdk.Dependencies/Serialization/BatchExtensions.cs new file mode 100644 index 00000000..db388b9a --- /dev/null +++ b/src/Speckle.Sdk.Dependencies/Serialization/BatchExtensions.cs @@ -0,0 +1,33 @@ +using System.Buffers; + +namespace Speckle.Sdk.Serialisation.V2.Send; + +public static class BatchExtensions +{ + public static Batch CreateBatch() + where T : IHasByteSize => new(); + + public static void TrimBatch(ref IMemoryOwner batch, bool isVerifiedFull) + where T : IHasByteSize + { + if (!isVerifiedFull) + { + ((Batch)batch).TrimExcess(); + } + } + + public static void AddBatchItem(this IMemoryOwner batch, T item) + where T : IHasByteSize => ((Batch)batch).Add(item); + + public static int GetBatchSize(this IMemoryOwner batch, int maxBatchSize) + where T : IHasByteSize + { + var currentSize = ((Batch)batch).BatchByteSize; + if (currentSize > maxBatchSize) + { + return maxBatchSize; + } + + return currentSize; + } +} diff --git a/src/Speckle.Sdk.Dependencies/Serialization/ChannelExtensions.cs b/src/Speckle.Sdk.Dependencies/Serialization/ChannelExtensions.cs index e420a235..4133f2eb 100644 --- a/src/Speckle.Sdk.Dependencies/Serialization/ChannelExtensions.cs +++ b/src/Speckle.Sdk.Dependencies/Serialization/ChannelExtensions.cs @@ -6,13 +6,13 @@ namespace Speckle.Sdk.Serialisation.V2.Send; public static class ChannelExtensions { - public static BatchingChannelReader> BatchBySize( + public static BatchingChannelReader> BatchByByteSize( this ChannelReader source, int batchSize, bool singleReader = false, bool allowSynchronousContinuations = false ) - where T : IHasSize => + where T : IHasByteSize => new SizeBatchingChannelReader( source ?? throw new ArgumentNullException(nameof(source)), batchSize, diff --git a/src/Speckle.Sdk.Dependencies/Serialization/ChannelSaver.cs b/src/Speckle.Sdk.Dependencies/Serialization/ChannelSaver.cs index b2e09329..886f703c 100644 --- a/src/Speckle.Sdk.Dependencies/Serialization/ChannelSaver.cs +++ b/src/Speckle.Sdk.Dependencies/Serialization/ChannelSaver.cs @@ -6,7 +6,7 @@ using Speckle.Sdk.Serialisation.V2.Send; namespace Speckle.Sdk.Dependencies.Serialization; public abstract class ChannelSaver - where T : IHasSize + where T : IHasByteSize { private const int SEND_CAPACITY = 500; private const int HTTP_SEND_CHUNK_SIZE = 25_000_000; //bytes @@ -31,7 +31,7 @@ public abstract class ChannelSaver public Task Start(CancellationToken cancellationToken) => _checkCacheChannel - .Reader.BatchBySize(HTTP_SEND_CHUNK_SIZE) + .Reader.BatchByByteSize(HTTP_SEND_CHUNK_SIZE) .WithTimeout(HTTP_BATCH_TIMEOUT) .PipeAsync( MAX_PARALLELISM_HTTP, @@ -68,9 +68,9 @@ public abstract class ChannelSaver ); public async ValueTask Save(T item, CancellationToken cancellationToken) => - await _checkCacheChannel.Writer.WriteAsync(item, cancellationToken).ConfigureAwait(true); + await _checkCacheChannel.Writer.WriteAsync(item, cancellationToken).ConfigureAwait(false); - public async Task> SendToServer(IMemoryOwner batch) + private async Task> SendToServer(IMemoryOwner batch) { await SendToServer((Batch)batch).ConfigureAwait(false); return batch; @@ -78,11 +78,17 @@ public abstract class ChannelSaver public abstract Task SendToServer(Batch batch); - public void DoneTraversing() => _checkCacheChannel.Writer.TryComplete(); + public abstract void SaveToCache(List item); + + public Task DoneTraversing() + { + _checkCacheChannel.Writer.TryComplete(); + return Task.CompletedTask; + } public async Task DoneSaving() { - await _checkCacheChannel.Reader.Completion.ConfigureAwait(true); + await _checkCacheChannel.Reader.Completion.ConfigureAwait(false); lock (_exceptions) { if (_exceptions.Count > 0) @@ -103,6 +109,4 @@ public abstract class ChannelSaver } } } - - public abstract void SaveToCache(List item); } diff --git a/src/Speckle.Sdk.Dependencies/Serialization/SizeBatchingChannelReader.cs b/src/Speckle.Sdk.Dependencies/Serialization/SizeBatchingChannelReader.cs index e979aba9..bf09e65d 100644 --- a/src/Speckle.Sdk.Dependencies/Serialization/SizeBatchingChannelReader.cs +++ b/src/Speckle.Sdk.Dependencies/Serialization/SizeBatchingChannelReader.cs @@ -4,30 +4,34 @@ using Open.ChannelExtensions; namespace Speckle.Sdk.Serialisation.V2.Send; -public interface IHasSize +public interface IHasByteSize { - int Size { get; } + int ByteSize { get; } } -public class SizeBatchingChannelReader( +public sealed class SizeBatchingChannelReader( ChannelReader source, int batchSize, bool singleReader, bool syncCont = false -) : BatchingChannelReader>(x => new Batch(), source, batchSize, singleReader, syncCont) - where T : IHasSize +) + : BatchingChannelReader>( + _ => BatchExtensions.CreateBatch(), + source, + batchSize, + singleReader, + syncCont + ) + where T : IHasByteSize { - protected override IMemoryOwner CreateBatch(int capacity) => new Batch(); + private readonly int _batchSize = batchSize; - protected override void TrimBatch(ref IMemoryOwner batch, bool isVerifiedFull) - { - if (!isVerifiedFull) - { - ((Batch)batch).TrimExcess(); - } - } + protected override IMemoryOwner CreateBatch(int capacity) => BatchExtensions.CreateBatch(); - protected override void AddBatchItem(IMemoryOwner batch, T item) => ((Batch)batch).Add(item); + protected override void TrimBatch(ref IMemoryOwner batch, bool isVerifiedFull) => + BatchExtensions.TrimBatch(ref batch, isVerifiedFull); - protected override int GetBatchSize(IMemoryOwner batch) => ((Batch)batch).Size; + protected override void AddBatchItem(IMemoryOwner batch, T item) => batch.AddBatchItem(item); + + protected override int GetBatchSize(IMemoryOwner batch) => batch.GetBatchSize(_batchSize); } diff --git a/src/Speckle.Sdk.Dependencies/packages.lock.json b/src/Speckle.Sdk.Dependencies/packages.lock.json index daf4f593..c0197ff7 100644 --- a/src/Speckle.Sdk.Dependencies/packages.lock.json +++ b/src/Speckle.Sdk.Dependencies/packages.lock.json @@ -82,11 +82,11 @@ }, "System.Threading.Channels": { "type": "Direct", - "requested": "[9.0.1, )", - "resolved": "9.0.1", - "contentHash": "vpp0a6Prnrqza30863qzNXtb2TonmnJVdfGpIU99+wYyDyLJG3IyoxmjTxhInywqJ6G2HEV4yjZ6/Eo802qGpw==", + "requested": "[9.0.2, )", + "resolved": "9.0.2", + "contentHash": "pUmqkuBS9OxWHOlfNad09Oxc8gRbxgN9UQtsqHPst4jfcgZRxQetNcsT2oe+VnUpEFAtBy1FZcJZiOscrBmA7g==", "dependencies": { - "Microsoft.Bcl.AsyncInterfaces": "9.0.1", + "Microsoft.Bcl.AsyncInterfaces": "9.0.2", "System.Threading.Tasks.Extensions": "4.5.4" } }, @@ -154,9 +154,9 @@ }, "Microsoft.Bcl.AsyncInterfaces": { "type": "CentralTransitive", - "requested": "[5.0.0, 5.0.0]", - "resolved": "9.0.1", - "contentHash": "IVkmUqf+KzbuXKrxi2tyQlg11RArYk26t2eU5cHekff+7Ao09vH8vt8idC0BJSMnpiRV2OK66zM2EwJU6Tm5Cw==", + "requested": "[5.0.0, )", + "resolved": "9.0.2", + "contentHash": "1CED0BGD7dCKsbe7tDhzpPB2Qdi9x35QChu6zkBEI4s0T5bDkkttGReqQnOeOfRNSxtP2WvpX6Ik/0O93XDuMw==", "dependencies": { "System.Threading.Tasks.Extensions": "4.5.4" } @@ -229,9 +229,9 @@ }, "System.Threading.Channels": { "type": "Direct", - "requested": "[9.0.1, )", - "resolved": "9.0.1", - "contentHash": "vpp0a6Prnrqza30863qzNXtb2TonmnJVdfGpIU99+wYyDyLJG3IyoxmjTxhInywqJ6G2HEV4yjZ6/Eo802qGpw==" + "requested": "[9.0.2, )", + "resolved": "9.0.2", + "contentHash": "pUmqkuBS9OxWHOlfNad09Oxc8gRbxgN9UQtsqHPst4jfcgZRxQetNcsT2oe+VnUpEFAtBy1FZcJZiOscrBmA7g==" }, "ILRepack": { "type": "Transitive", diff --git a/src/Speckle.Sdk/Api/GraphQL/Models/Comment.cs b/src/Speckle.Sdk/Api/GraphQL/Models/Comment.cs index 5637f57c..01da6610 100644 --- a/src/Speckle.Sdk/Api/GraphQL/Models/Comment.cs +++ b/src/Speckle.Sdk/Api/GraphQL/Models/Comment.cs @@ -1,4 +1,6 @@ -namespace Speckle.Sdk.Api.GraphQL.Models; +using Speckle.Newtonsoft.Json; + +namespace Speckle.Sdk.Api.GraphQL.Models; public sealed class Comment { @@ -17,4 +19,33 @@ public sealed class Comment public DateTime updatedAt { get; init; } public DateTime? viewedAt { get; init; } public List viewerResources { get; init; } + public SerializedViewerState viewerState { get; init; } +} + +/// +/// See SerializedViewerState in /shared/src/viewer/helpers/state.ts +/// +/// +/// Note, there are many FE/Viewer specific properties on this object that are not reflected here (hence the override) +/// We can add them as needed, keeping in mind flexiblity for breaking changes (these classes are intentionally not documented in our schema!) +/// +[JsonObject(MissingMemberHandling = MissingMemberHandling.Ignore)] +public sealed class SerializedViewerState +{ + public ViewerStateUI ui { get; init; } +} + +[JsonObject(MissingMemberHandling = MissingMemberHandling.Ignore)] +public sealed class ViewerStateUI +{ + public ViewerStateCamera camera { get; init; } +} + +[JsonObject(MissingMemberHandling = MissingMemberHandling.Ignore)] +public sealed class ViewerStateCamera +{ + public List position { get; init; } + public List target { get; init; } + public bool isOrthoProjection { get; init; } + public double zoom { get; init; } } diff --git a/src/Speckle.Sdk/Api/GraphQL/Models/SubscriptionMessages.cs b/src/Speckle.Sdk/Api/GraphQL/Models/SubscriptionMessages.cs index 9d4fe88a..327bac77 100644 --- a/src/Speckle.Sdk/Api/GraphQL/Models/SubscriptionMessages.cs +++ b/src/Speckle.Sdk/Api/GraphQL/Models/SubscriptionMessages.cs @@ -77,7 +77,8 @@ public sealed class ProjectVersionsUpdatedMessage : EventArgs [JsonRequired] public ProjectVersionsUpdatedMessageType type { get; init; } - public string? modelId { get; init; } + [JsonRequired] + public string modelId { get; init; } public Version? version { get; init; } } diff --git a/src/Speckle.Sdk/Api/GraphQL/Resources/CommentResource.cs b/src/Speckle.Sdk/Api/GraphQL/Resources/CommentResource.cs index 7f173ca9..30aed5e9 100644 --- a/src/Speckle.Sdk/Api/GraphQL/Resources/CommentResource.cs +++ b/src/Speckle.Sdk/Api/GraphQL/Resources/CommentResource.cs @@ -150,6 +150,7 @@ public sealed class CommentResource objectId versionId } + viewerState } } } diff --git a/src/Speckle.Sdk/Api/GraphQL/Resources/VersionResource.cs b/src/Speckle.Sdk/Api/GraphQL/Resources/VersionResource.cs index 76f499bb..08aad4a9 100644 --- a/src/Speckle.Sdk/Api/GraphQL/Resources/VersionResource.cs +++ b/src/Speckle.Sdk/Api/GraphQL/Resources/VersionResource.cs @@ -125,7 +125,7 @@ public sealed class VersionResource /// /// - /// id of the created + /// The created /// public async Task Create(CreateVersionInput input, CancellationToken cancellationToken = default) { diff --git a/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs b/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs index a05ba4c3..0c1ba2d7 100644 --- a/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs +++ b/src/Speckle.Sdk/Api/Operations/Operations.Receive.cs @@ -21,16 +21,15 @@ public partial class Operations metricsFactory.CreateCounter("Receive").Add(1); receiveActivity?.SetTag("objectId", objectId); - + var process = serializeProcessFactory.CreateDeserializeProcess( + url, + streamId, + authorizationToken, + onProgressAction, + cancellationToken + ); try { - using var process = serializeProcessFactory.CreateDeserializeProcess( - url, - streamId, - authorizationToken, - onProgressAction, - cancellationToken - ); var result = await process.Deserialize(objectId).ConfigureAwait(false); receiveActivity?.SetStatus(SdkActivityStatusCode.Ok); return result; @@ -41,6 +40,10 @@ public partial class Operations receiveActivity?.RecordException(ex); throw; } + finally + { + await process.DisposeAsync().ConfigureAwait(false); + } } /// diff --git a/src/Speckle.Sdk/Api/Operations/Operations.Send.cs b/src/Speckle.Sdk/Api/Operations/Operations.Send.cs index 68ee9438..785f20a6 100644 --- a/src/Speckle.Sdk/Api/Operations/Operations.Send.cs +++ b/src/Speckle.Sdk/Api/Operations/Operations.Send.cs @@ -23,15 +23,15 @@ public partial class Operations using var receiveActivity = activityFactory.Start("Operations.Send"); metricsFactory.CreateCounter("Send").Add(1); + var process = serializeProcessFactory.CreateSerializeProcess( + url, + streamId, + authorizationToken, + onProgressAction, + cancellationToken + ); try { - using var process = serializeProcessFactory.CreateSerializeProcess( - url, - streamId, - authorizationToken, - onProgressAction, - cancellationToken - ); var results = await process.Serialize(value).ConfigureAwait(false); receiveActivity?.SetStatus(SdkActivityStatusCode.Ok); @@ -43,6 +43,10 @@ public partial class Operations receiveActivity?.RecordException(ex); throw; } + finally + { + await process.DisposeAsync().ConfigureAwait(false); + } } /// diff --git a/src/Speckle.Sdk/Serialisation/V2/PriorityScheduler.cs b/src/Speckle.Sdk/Serialisation/V2/PriorityScheduler.cs index 6e3b0167..7741cfbc 100644 --- a/src/Speckle.Sdk/Serialisation/V2/PriorityScheduler.cs +++ b/src/Speckle.Sdk/Serialisation/V2/PriorityScheduler.cs @@ -85,4 +85,23 @@ public sealed class PriorityScheduler( } protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) => false; // we might not want to execute task that should schedule as high or low priority inline + + public Task WaitForCompletion() + { + _tasks.CompleteAdding(); + return Task + .Factory.StartNew( + async () => + { + while (_threads != null && _threads.Any(x => x.IsAlive)) + { + await Task.Delay(TimeSpan.FromMilliseconds(500)).ConfigureAwait(false); + } + }, + CancellationToken.None, + TaskCreationOptions.AttachedToParent, + TaskScheduler.Default + ) + .Unwrap(); + } } diff --git a/src/Speckle.Sdk/Serialisation/V2/Receive/DeserializeProcess.cs b/src/Speckle.Sdk/Serialisation/V2/Receive/DeserializeProcess.cs index 48a19ddf..cbe8feac 100644 --- a/src/Speckle.Sdk/Serialisation/V2/Receive/DeserializeProcess.cs +++ b/src/Speckle.Sdk/Serialisation/V2/Receive/DeserializeProcess.cs @@ -4,6 +4,7 @@ using Speckle.InterfaceGenerator; using Speckle.Sdk.Dependencies; using Speckle.Sdk.Models; using Speckle.Sdk.Serialisation.Utilities; +using Speckle.Sdk.SQLite; using Speckle.Sdk.Transports; namespace Speckle.Sdk.Serialisation.V2.Receive; @@ -12,27 +13,51 @@ public record DeserializeProcessOptions( bool SkipCache = false, bool ThrowOnMissingReferences = true, bool SkipInvalidConverts = false, - int? MaxParallelism = null + int? MaxParallelism = null, + bool SkipServer = false ); -public partial interface IDeserializeProcess : IDisposable; +public partial interface IDeserializeProcess : IAsyncDisposable; [GenerateAutoInterface] public sealed class DeserializeProcess( - IProgress? progress, IObjectLoader objectLoader, + IProgress? progress, IBaseDeserializer baseDeserializer, ILoggerFactory loggerFactory, CancellationToken cancellationToken, DeserializeProcessOptions? options = null ) : IDeserializeProcess { + public DeserializeProcess( + ISqLiteJsonCacheManager sqLiteJsonCacheManager, + IServerObjectManager serverObjectManager, + IProgress? progress, + IBaseDeserializer baseDeserializer, + ILoggerFactory loggerFactory, + CancellationToken cancellationToken, + DeserializeProcessOptions? options = null + ) + : +#pragma warning disable CA2000 + this( + new ObjectLoader(sqLiteJsonCacheManager, serverObjectManager, progress, cancellationToken), + progress, + baseDeserializer, + loggerFactory, + cancellationToken, + options + ) +#pragma warning restore CA2000 + { } + private readonly PriorityScheduler _belowNormal = new( loggerFactory.CreateLogger(), ThreadPriority.BelowNormal, Environment.ProcessorCount * 2, cancellationToken ); + private readonly DeserializeProcessOptions _options = options ?? new(); private readonly ConcurrentDictionary)> _closures = new(); @@ -43,10 +68,11 @@ public sealed class DeserializeProcess( public long Total { get; private set; } [AutoInterfaceIgnore] - public void Dispose() + public async ValueTask DisposeAsync() { objectLoader.Dispose(); _belowNormal.Dispose(); + await _belowNormal.WaitForCompletion().ConfigureAwait(false); } /// @@ -56,9 +82,7 @@ public sealed class DeserializeProcess( public async Task Deserialize(string rootId) { - var (rootJson, childrenIds) = await objectLoader - .GetAndCache(rootId, _options, cancellationToken) - .ConfigureAwait(false); + var (rootJson, childrenIds) = await objectLoader.GetAndCache(rootId, _options).ConfigureAwait(false); var root = new Id(rootId); //childrenIds is already frozen but need to just add root? _allIds = childrenIds.Concat([root]).Freeze(); @@ -67,6 +91,7 @@ public sealed class DeserializeProcess( _closures.TryAdd(root, (rootJson, childrenIds)); progress?.Report(new(ProgressEvent.DeserializeObject, _baseCache.Count, childrenIds.Count)); await Traverse(root).ConfigureAwait(false); + await _belowNormal.WaitForCompletion().ConfigureAwait(false); return _baseCache[root]; } diff --git a/src/Speckle.Sdk/Serialisation/V2/Receive/ObjectLoader.cs b/src/Speckle.Sdk/Serialisation/V2/Receive/ObjectLoader.cs index 62f28c94..a2de245c 100644 --- a/src/Speckle.Sdk/Serialisation/V2/Receive/ObjectLoader.cs +++ b/src/Speckle.Sdk/Serialisation/V2/Receive/ObjectLoader.cs @@ -15,7 +15,8 @@ public partial interface IObjectLoader : IDisposable; public sealed class ObjectLoader( ISqLiteJsonCacheManager sqLiteJsonCacheManager, IServerObjectManager serverObjectManager, - IProgress? progress + IProgress? progress, + CancellationToken cancellationToken ) : ChannelLoader, IObjectLoader { private int? _allChildrenCount; @@ -28,11 +29,7 @@ public sealed class ObjectLoader( [AutoInterfaceIgnore] public void Dispose() => sqLiteJsonCacheManager.Dispose(); - public async Task<(Json, IReadOnlyCollection)> GetAndCache( - string rootId, - DeserializeProcessOptions options, - CancellationToken cancellationToken - ) + public async Task<(Json, IReadOnlyCollection)> GetAndCache(string rootId, DeserializeProcessOptions options) { _options = options; string? rootJson; @@ -49,28 +46,33 @@ public sealed class ObjectLoader( return (new(rootJson), allChildren); } } - rootJson = await serverObjectManager - .DownloadSingleObject(rootId, progress, cancellationToken) - .NotNull() - .ConfigureAwait(false); - IReadOnlyCollection allChildrenIds = ClosureParser - .GetClosures(rootJson, cancellationToken) - .OrderByDescending(x => x.Item2) - .Select(x => new Id(x.Item1)) - .Where(x => !x.Value.StartsWith("blob", StringComparison.Ordinal)) - .Freeze(); - _allChildrenCount = allChildrenIds.Count; - await GetAndCache(allChildrenIds.Select(x => x.Value), cancellationToken, _options.MaxParallelism) - .ConfigureAwait(false); - - CheckForExceptions(); - cancellationToken.ThrowIfCancellationRequested(); - //save the root last to shortcut later - if (!options.SkipCache) + if (!options.SkipServer) { - sqLiteJsonCacheManager.SaveObject(rootId, rootJson); + rootJson = await serverObjectManager + .DownloadSingleObject(rootId, progress, cancellationToken) + .NotNull() + .ConfigureAwait(false); + IReadOnlyCollection allChildrenIds = ClosureParser + .GetClosures(rootJson, cancellationToken) + .OrderByDescending(x => x.Item2) + .Select(x => new Id(x.Item1)) + .Where(x => !x.Value.StartsWith("blob", StringComparison.Ordinal)) + .Freeze(); + _allChildrenCount = allChildrenIds.Count; + await GetAndCache(allChildrenIds.Select(x => x.Value), cancellationToken, _options.MaxParallelism) + .ConfigureAwait(false); + + CheckForExceptions(); + cancellationToken.ThrowIfCancellationRequested(); + //save the root last to shortcut later + if (!options.SkipCache) + { + sqLiteJsonCacheManager.SaveObject(rootId, rootJson); + } + + return (new(rootJson), allChildrenIds); } - return (new(rootJson), allChildrenIds); + throw new SpeckleException("Cannot skip server and cache. Please choose one."); } [AutoInterfaceIgnore] @@ -92,9 +94,14 @@ public sealed class ObjectLoader( { var toCache = new List(); await foreach ( - var (id, json) in serverObjectManager.DownloadObjects(ids.Select(x => x.NotNull()).ToList(), progress, default) + var (id, json) in serverObjectManager.DownloadObjects( + ids.Select(x => x.NotNull()).ToList(), + progress, + cancellationToken + ) ) { + cancellationToken.ThrowIfCancellationRequested(); Interlocked.Increment(ref _downloaded); progress?.Report(new(ProgressEvent.DownloadObjects, _downloaded, _totalToDownload)); toCache.Add(new(new(id), new(json), true, null)); @@ -114,6 +121,7 @@ public sealed class ObjectLoader( { if (!_options.SkipCache) { + cancellationToken.ThrowIfCancellationRequested(); sqLiteJsonCacheManager.SaveObjects(batch.Select(x => (x.Id.Value, x.Json.Value))); Interlocked.Exchange(ref _cached, _cached + batch.Count); progress?.Report(new(ProgressEvent.CachedToLocal, _cached, _allChildrenCount)); diff --git a/src/Speckle.Sdk/Serialisation/V2/Send/BaseItem.cs b/src/Speckle.Sdk/Serialisation/V2/Send/BaseItem.cs index 38f2922f..f5c39f4b 100644 --- a/src/Speckle.Sdk/Serialisation/V2/Send/BaseItem.cs +++ b/src/Speckle.Sdk/Serialisation/V2/Send/BaseItem.cs @@ -2,9 +2,10 @@ using System.Text; namespace Speckle.Sdk.Serialisation.V2.Send; -public readonly record struct BaseItem(Id Id, Json Json, bool NeedsStorage, Dictionary? Closures) : IHasSize +public readonly record struct BaseItem(Id Id, Json Json, bool NeedsStorage, Dictionary? Closures) + : IHasByteSize { - public int Size { get; } = Encoding.UTF8.GetByteCount(Json.Value); + public int ByteSize { get; } = Encoding.UTF8.GetByteCount(Json.Value); public bool Equals(BaseItem? other) { diff --git a/src/Speckle.Sdk/Serialisation/V2/Send/SerializeProcess.cs b/src/Speckle.Sdk/Serialisation/V2/Send/SerializeProcess.cs index 08d0808e..21a2b10d 100644 --- a/src/Speckle.Sdk/Serialisation/V2/Send/SerializeProcess.cs +++ b/src/Speckle.Sdk/Serialisation/V2/Send/SerializeProcess.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Logging; using Speckle.InterfaceGenerator; using Speckle.Sdk.Common; @@ -22,7 +23,7 @@ public readonly record struct SerializeProcessResults( IReadOnlyDictionary ConvertedReferences ); -public partial interface ISerializeProcess : IDisposable; +public partial interface ISerializeProcess : IAsyncDisposable; [GenerateAutoInterface] public sealed class SerializeProcess( @@ -36,12 +37,17 @@ public sealed class SerializeProcess( SerializeProcessOptions? options = null ) : ChannelSaver, ISerializeProcess { + //async dispose + [SuppressMessage("Usage", "CA2213:Disposable fields should be disposed")] private readonly PriorityScheduler _highest = new( loggerFactory.CreateLogger(), ThreadPriority.Highest, 2, cancellationToken ); + + //async dispose + [SuppressMessage("Usage", "CA2213:Disposable fields should be disposed")] private readonly PriorityScheduler _belowNormal = new( loggerFactory.CreateLogger(), ThreadPriority.BelowNormal, @@ -67,11 +73,18 @@ public sealed class SerializeProcess( private long _cached; [AutoInterfaceIgnore] - public void Dispose() + public async ValueTask DisposeAsync() { _highest.Dispose(); _belowNormal.Dispose(); sqLiteJsonCacheManager.Dispose(); + await WaitForSchedulerCompletion().ConfigureAwait(false); + } + + private async Task WaitForSchedulerCompletion() + { + await _highest.WaitForCompletion().ConfigureAwait(false); + await _belowNormal.WaitForCompletion().ConfigureAwait(false); } public async Task Serialize(Base root) @@ -88,10 +101,13 @@ public sealed class SerializeProcess( _highest ); } - await Traverse(root).ConfigureAwait(true); - DoneTraversing(); - await Task.WhenAll(findTotalObjectsTask, channelTask).ConfigureAwait(true); - await DoneSaving().ConfigureAwait(true); + await Traverse(root).ConfigureAwait(false); + await DoneTraversing().ConfigureAwait(false); + await Task.WhenAll(findTotalObjectsTask, channelTask).ConfigureAwait(false); + cancellationToken.ThrowIfCancellationRequested(); + await DoneSaving().ConfigureAwait(false); + cancellationToken.ThrowIfCancellationRequested(); + await WaitForSchedulerCompletion().ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); return new(root.id.NotNull(), baseSerializer.ObjectReferences.Freeze()); } @@ -116,7 +132,7 @@ public sealed class SerializeProcess( cancellationToken.ThrowIfCancellationRequested(); var t = Task .Factory.StartNew( - async () => await Traverse(tmp).ConfigureAwait(true), + async () => await Traverse(tmp).ConfigureAwait(false), cancellationToken, TaskCreationOptions.AttachedToParent | TaskCreationOptions.PreferFairness, _belowNormal @@ -128,7 +144,7 @@ public sealed class SerializeProcess( Dictionary[] taskClosures = []; if (tasks.Count > 0) { - taskClosures = await Task.WhenAll(tasks).ConfigureAwait(true); + taskClosures = await Task.WhenAll(tasks).ConfigureAwait(false); } var childClosures = _childClosurePool.Get(); foreach (var childClosure in taskClosures) @@ -150,7 +166,7 @@ public sealed class SerializeProcess( if (item.NeedsStorage) { Interlocked.Increment(ref _objectsSerialized); - await Save(item, cancellationToken).ConfigureAwait(true); + await Save(item, cancellationToken).ConfigureAwait(false); } if (!currentClosures.ContainsKey(item.Id)) diff --git a/src/Speckle.Sdk/Serialisation/V2/SerializeProcessFactory.cs b/src/Speckle.Sdk/Serialisation/V2/SerializeProcessFactory.cs index debf914e..863d7026 100644 --- a/src/Speckle.Sdk/Serialisation/V2/SerializeProcessFactory.cs +++ b/src/Speckle.Sdk/Serialisation/V2/SerializeProcessFactory.cs @@ -69,11 +69,14 @@ public class SerializeProcessFactory( { var sqLiteJsonCacheManager = sqLiteJsonCacheManagerFactory.CreateFromStream(streamId); var serverObjectManager = serverObjectManagerFactory.Create(url, streamId, authorizationToken); - -#pragma warning disable CA2000 - //owned by process, refactor later - var objectLoader = new ObjectLoader(sqLiteJsonCacheManager, serverObjectManager, progress); -#pragma warning restore CA2000 - return new DeserializeProcess(progress, objectLoader, baseDeserializer, loggerFactory, cancellationToken, options); + return new DeserializeProcess( + sqLiteJsonCacheManager, + serverObjectManager, + progress, + baseDeserializer, + loggerFactory, + cancellationToken, + options + ); } } diff --git a/src/Speckle.Sdk/Serialisation/V2/ServerObjectManager.cs b/src/Speckle.Sdk/Serialisation/V2/ServerObjectManager.cs index c957087f..895a4a6f 100644 --- a/src/Speckle.Sdk/Serialisation/V2/ServerObjectManager.cs +++ b/src/Speckle.Sdk/Serialisation/V2/ServerObjectManager.cs @@ -50,11 +50,9 @@ public class ServerObjectManager : IServerObjectManager using var _ = _activityFactory.Start(); cancellationToken.ThrowIfCancellationRequested(); - using var childrenHttpMessage = new HttpRequestMessage - { - RequestUri = new Uri($"/api/getobjects/{_streamId}", UriKind.Relative), - Method = HttpMethod.Post, - }; + using var childrenHttpMessage = new HttpRequestMessage(); + childrenHttpMessage.RequestUri = new Uri($"/api/getobjects/{_streamId}", UriKind.Relative); + childrenHttpMessage.Method = HttpMethod.Post; Dictionary postParameters = new() { { "objects", JsonConvert.SerializeObject(objectIds) } }; string serializedPayload = JsonConvert.SerializeObject(postParameters); @@ -62,7 +60,7 @@ public class ServerObjectManager : IServerObjectManager childrenHttpMessage.Headers.Add("Accept", "text/plain"); HttpResponseMessage childrenHttpResponse = await _client - .SendAsync(childrenHttpMessage, cancellationToken) + .SendAsync(childrenHttpMessage, HttpCompletionOption.ResponseContentRead, cancellationToken) .ConfigureAwait(false); await foreach (var (id, json) in ResponseProgress(childrenHttpResponse, progress, false, cancellationToken)) @@ -84,11 +82,9 @@ public class ServerObjectManager : IServerObjectManager cancellationToken.ThrowIfCancellationRequested(); // Get root object - using var rootHttpMessage = new HttpRequestMessage - { - RequestUri = new Uri($"/objects/{_streamId}/{objectId}/single", UriKind.Relative), - Method = HttpMethod.Get, - }; + using var rootHttpMessage = new HttpRequestMessage(); + rootHttpMessage.RequestUri = new Uri($"/objects/{_streamId}/{objectId}/single", UriKind.Relative); + rootHttpMessage.Method = HttpMethod.Get; HttpResponseMessage rootHttpResponse = await _client .SendAsync(rootHttpMessage, HttpCompletionOption.ResponseContentRead, cancellationToken) diff --git a/src/Speckle.Sdk/packages.lock.json b/src/Speckle.Sdk/packages.lock.json index 587a9b17..919f5109 100644 --- a/src/Speckle.Sdk/packages.lock.json +++ b/src/Speckle.Sdk/packages.lock.json @@ -15,7 +15,7 @@ }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Direct", - "requested": "[5.0.0, 5.0.0]", + "requested": "[5.0.0, )", "resolved": "5.0.0", "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==", "dependencies": { @@ -30,7 +30,7 @@ }, "Microsoft.Data.Sqlite": { "type": "Direct", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -40,13 +40,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Direct", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "Direct", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -83,9 +83,9 @@ }, "Speckle.DoubleNumerics": { "type": "Direct", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.InterfaceGenerator": { "type": "Direct", @@ -314,7 +314,7 @@ }, "Microsoft.Data.Sqlite": { "type": "Direct", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -324,13 +324,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "Direct", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "Direct", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -358,9 +358,9 @@ }, "Speckle.DoubleNumerics": { "type": "Direct", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.InterfaceGenerator": { "type": "Direct", diff --git a/tests/Speckle.Objects.Tests.Unit/Speckle.Objects.Tests.Unit.csproj b/tests/Speckle.Objects.Tests.Unit/Speckle.Objects.Tests.Unit.csproj index a307c540..15eb3455 100644 --- a/tests/Speckle.Objects.Tests.Unit/Speckle.Objects.Tests.Unit.csproj +++ b/tests/Speckle.Objects.Tests.Unit/Speckle.Objects.Tests.Unit.csproj @@ -15,7 +15,7 @@ - + diff --git a/tests/Speckle.Objects.Tests.Unit/packages.lock.json b/tests/Speckle.Objects.Tests.Unit/packages.lock.json index 89088e95..3eb30310 100644 --- a/tests/Speckle.Objects.Tests.Unit/packages.lock.json +++ b/tests/Speckle.Objects.Tests.Unit/packages.lock.json @@ -16,12 +16,12 @@ }, "Microsoft.NET.Test.Sdk": { "type": "Direct", - "requested": "[17.12.0, )", - "resolved": "17.12.0", - "contentHash": "kt/PKBZ91rFCWxVIJZSgVLk+YR+4KxTuHf799ho8WNiK5ZQpJNAEZCAWX86vcKrs+DiYjiibpYKdGZP6+/N17w==", + "requested": "[17.13.0, )", + "resolved": "17.13.0", + "contentHash": "W19wCPizaIC9Zh47w8wWI/yxuqR7/dtABwOrc8r2jX/8mUNxM2vw4fXDh+DJTeogxV+KzKwg5jNNGQVwf3LXyA==", "dependencies": { - "Microsoft.CodeCoverage": "17.12.0", - "Microsoft.TestPlatform.TestHost": "17.12.0" + "Microsoft.CodeCoverage": "17.13.0", + "Microsoft.TestPlatform.TestHost": "17.13.0" } }, "Microsoft.SourceLink.GitHub": { @@ -54,9 +54,9 @@ }, "xunit.runner.visualstudio": { "type": "Direct", - "requested": "[3.0.1, )", - "resolved": "3.0.1", - "contentHash": "lbyYtsBxA8Pz8kaf5Xn/Mj1mL9z2nlBWdZhqFaj66nxXBa4JwiTDm4eGcpSMet6du9TOWI6bfha+gQR6+IHawg==" + "requested": "[3.0.2, )", + "resolved": "3.0.2", + "contentHash": "oXbusR6iPq0xlqoikjdLvzh+wQDkMv9If58myz9MEzldS4nIcp442Btgs2sWbYWV+caEluMe2pQCZ0hUZgPiow==" }, "Argon": { "type": "Transitive", @@ -110,8 +110,8 @@ }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA==" + "resolved": "17.13.0", + "contentHash": "9LIUy0y+DvUmEPtbRDw6Bay3rzwqFV8P4efTrK4CZhQle3M/QwLPjISghfcolmEGAPWxuJi6m98ZEfk4VR4Lfg==" }, "Microsoft.Data.Sqlite.Core": { "type": "Transitive", @@ -176,18 +176,18 @@ }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==", + "resolved": "17.13.0", + "contentHash": "bt0E0Dx+iqW97o4A59RCmUmz/5NarJ7LRL+jXbSHod72ibL5XdNm1Ke+UO5tFhBG4VwHLcSjqq9BUSblGNWamw==", "dependencies": { "System.Reflection.Metadata": "1.6.0" } }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "MiPEJQNyADfwZ4pJNpQex+t9/jOClBGMiCiVVFuELCMSX2nmNfvUor3uFVxNNCg30uxDP8JDYfPnMXQzsfzYyg==", + "resolved": "17.13.0", + "contentHash": "9GGw08Dc3AXspjekdyTdZ/wYWFlxbgcF0s7BKxzVX+hzAwpifDOdxM+ceVaaJSQOwqt3jtuNlHn3XTpKUS9x9Q==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "17.12.0", + "Microsoft.TestPlatform.ObjectModel": "17.13.0", "Newtonsoft.Json": "13.0.1" } }, @@ -339,10 +339,10 @@ "dependencies": { "GraphQL.Client": "[6.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -353,11 +353,11 @@ "speckle.sdk.testing": { "type": "Project", "dependencies": { - "Microsoft.NET.Test.Sdk": "[17.12.0, )", + "Microsoft.NET.Test.Sdk": "[17.13.0, )", "Speckle.Sdk": "[1.0.0, )", "Verify.Quibble": "[2.1.1, )", "Verify.Xunit": "[28.10.1, )", - "xunit.runner.visualstudio": "[3.0.1, )" + "xunit.runner.visualstudio": "[3.0.2, )" } }, "GraphQL.Client": { @@ -379,7 +379,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -389,13 +389,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -407,9 +407,9 @@ }, "Speckle.DoubleNumerics": { "type": "CentralTransitive", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.Newtonsoft.Json": { "type": "CentralTransitive", diff --git a/tests/Speckle.Sdk.Serialization.Testing/Program.cs b/tests/Speckle.Sdk.Serialization.Testing/Program.cs index 5493bb61..51b285eb 100644 --- a/tests/Speckle.Sdk.Serialization.Testing/Program.cs +++ b/tests/Speckle.Sdk.Serialization.Testing/Program.cs @@ -55,7 +55,7 @@ Console.WriteLine("Deserialized"); Console.ReadLine(); Console.WriteLine("Executing"); -using var process2 = factory.CreateSerializeProcess( +var process2 = factory.CreateSerializeProcess( new Uri(url), streamId, token, @@ -66,4 +66,5 @@ using var process2 = factory.CreateSerializeProcess( await process2.Serialize(@base).ConfigureAwait(false); Console.WriteLine("Detach"); Console.ReadLine(); +await process2.DisposeAsync().ConfigureAwait(false); #pragma warning restore CA1506 diff --git a/tests/Speckle.Sdk.Serialization.Testing/packages.lock.json b/tests/Speckle.Sdk.Serialization.Testing/packages.lock.json index 2b5906e3..34e09e80 100644 --- a/tests/Speckle.Sdk.Serialization.Testing/packages.lock.json +++ b/tests/Speckle.Sdk.Serialization.Testing/packages.lock.json @@ -4,7 +4,7 @@ "net8.0": { "Microsoft.Extensions.DependencyInjection": { "type": "Direct", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==", "dependencies": { @@ -333,10 +333,10 @@ "dependencies": { "GraphQL.Client": "[6.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -348,7 +348,7 @@ "type": "Project", "dependencies": { "BenchmarkDotNet": "[0.14.0, )", - "Microsoft.Extensions.DependencyInjection": "[2.2.0, 2.2.0]", + "Microsoft.Extensions.DependencyInjection": "[2.2.0, )", "Speckle.Objects": "[1.0.0, )" } }, @@ -383,7 +383,7 @@ }, "Microsoft.Bcl.AsyncInterfaces": { "type": "CentralTransitive", - "requested": "[5.0.0, 5.0.0]", + "requested": "[5.0.0, )", "resolved": "1.1.0", "contentHash": "1Am6l4Vpn3/K32daEqZI+FFr96OlZkgwK2LcT3pZ2zWubR5zTPW3/FkO1Rat9kb7oQOa4rxgl9LJHc5tspCWfg==" }, @@ -395,7 +395,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -405,13 +405,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -423,9 +423,9 @@ }, "Speckle.DoubleNumerics": { "type": "CentralTransitive", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.Newtonsoft.Json": { "type": "CentralTransitive", diff --git a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.cs b/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.cs index d0ce9d8e..5e2995a0 100644 --- a/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.cs +++ b/tests/Speckle.Sdk.Serialization.Tests/CancellationTests.cs @@ -26,7 +26,7 @@ public class CancellationTests var testClass = new TestClass() { RegularProperty = "Hello" }; using var cancellationSource = new CancellationTokenSource(); - using var serializeProcess = new SerializeProcess( + await using var serializeProcess = new SerializeProcess( null, new DummySqLiteSendManager(), new DummyServerObjectManager(), @@ -50,7 +50,7 @@ public class CancellationTests var testClass = new TestClass() { RegularProperty = "Hello" }; using var cancellationSource = new CancellationTokenSource(); - using var serializeProcess = new SerializeProcess( + await using var serializeProcess = new SerializeProcess( null, new DummySqLiteSendManager(), new CancellationServerObjectManager(cancellationSource), @@ -73,7 +73,7 @@ public class CancellationTests var testClass = new TestClass() { RegularProperty = "Hello" }; using var cancellationSource = new CancellationTokenSource(); - using var serializeProcess = new SerializeProcess( + await using var serializeProcess = new SerializeProcess( null, new CancellationSqLiteSendManager(cancellationSource), new DummyServerObjectManager(), @@ -98,14 +98,10 @@ public class CancellationTests closures.Count.Should().Be(oldCount); using var cancellationSource = new CancellationTokenSource(); - var o = new ObjectLoader( + await using var process = new DeserializeProcess( new CancellationSqLiteJsonCacheManager(cancellationSource), new DummyReceiveServerObjectManager(closures), - null - ); - using var process = new DeserializeProcess( null, - o, new BaseDeserializer(new ObjectDeserializerFactory()), new NullLoggerFactory(), cancellationSource.Token, @@ -129,14 +125,10 @@ public class CancellationTests closures.Count.Should().Be(oldCount); using var cancellationSource = new CancellationTokenSource(); - var o = new ObjectLoader( + await using var process = new DeserializeProcess( new DummyCancellationSqLiteSendManager(), new CancellationServerObjectManager(cancellationSource), - null - ); - using var process = new DeserializeProcess( null, - o, new BaseDeserializer(new ObjectDeserializerFactory()), new NullLoggerFactory(), cancellationSource.Token, @@ -160,14 +152,10 @@ public class CancellationTests closures.Count.Should().Be(oldCount); using var cancellationSource = new CancellationTokenSource(); - var o = new ObjectLoader( + await using var process = new DeserializeProcess( new DummySqLiteReceiveManager(closures), new DummyReceiveServerObjectManager(closures), - null - ); - using var process = new DeserializeProcess( null, - o, new CancellationBaseDeserializer(cancellationSource), new NullLoggerFactory(), cancellationSource.Token, diff --git a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.cs b/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.cs index 284223c8..add4126d 100644 --- a/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.cs +++ b/tests/Speckle.Sdk.Serialization.Tests/DetachedTests.cs @@ -32,7 +32,7 @@ public class DetachedTests var objects = new Dictionary(); - using var process2 = new SerializeProcess( + await using var process2 = new SerializeProcess( null, new DummySendCacheManager(objects), new DummyServerObjectManager(), @@ -117,7 +117,7 @@ public class DetachedTests var objects = new Dictionary(); - using var process2 = new SerializeProcess( + await using var process2 = new SerializeProcess( null, new DummySendCacheManager(objects), new DummyServerObjectManager(), @@ -187,7 +187,7 @@ public class DetachedTests var objects = new Dictionary(); - using var process2 = new SerializeProcess( + await using var process2 = new SerializeProcess( null, new DummySendCacheManager(objects), new DummyServerObjectManager(), @@ -222,7 +222,7 @@ public class DetachedTests var objects = new Dictionary(); - using var process2 = new SerializeProcess( + await using var process2 = new SerializeProcess( null, new DummySendCacheManager(objects), new DummyServerObjectManager(), diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Server_Skip_Both.verified.json b/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Server_Skip_Both.verified.json new file mode 100644 index 00000000..ec4502d8 --- /dev/null +++ b/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.Test_Exceptions_Receive_Server_Skip_Both.verified.json @@ -0,0 +1,5 @@ +{ + "Type": "Speckle.Sdk.SpeckleException", + "Message": "Cannot skip server and cache. Please choose one.", + "Source": "Speckle.Sdk" +} diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.cs b/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.cs index 4b14b5b7..b4f13242 100644 --- a/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.cs +++ b/tests/Speckle.Sdk.Serialization.Tests/ExceptionTests.cs @@ -24,7 +24,7 @@ public class ExceptionTests var testClass = new TestClass() { RegularProperty = "Hello" }; var objects = new Dictionary(); - using var process2 = new SerializeProcess( + await using var process2 = new SerializeProcess( null, new DummySendCacheManager(objects), new ExceptionServerObjectManager(), @@ -45,7 +45,7 @@ public class ExceptionTests { var testClass = new TestClass() { RegularProperty = "Hello" }; - using var process2 = new SerializeProcess( + await using var process2 = new SerializeProcess( null, new ExceptionSendCacheManager(), new DummyServerObjectManager(), @@ -60,6 +60,31 @@ public class ExceptionTests await Verify(ex); } + [Fact] + public async Task Test_Exceptions_Receive_Server_Skip_Both() + { + var o = new ObjectLoader( + new DummySqLiteReceiveManager(new Dictionary()), + new ExceptionServerObjectManager(), + null, + default + ); + await using var process = new DeserializeProcess( + o, + null, + new BaseDeserializer(new ObjectDeserializerFactory()), + new NullLoggerFactory(), + default, + new(SkipCache: true, MaxParallelism: 1, SkipServer: true) + ); + + var ex = await Assert.ThrowsAsync(async () => + { + var root = await process.Deserialize(Guid.NewGuid().ToString()); + }); + await Verify(ex); + } + [Theory] [InlineData("RevitObject.json.gz", "3416d3fe01c9196115514c4a2f41617b", 7818)] public async Task Test_Exceptions_Receive_Server(string fileName, string rootId, int oldCount) @@ -67,10 +92,10 @@ public class ExceptionTests var closures = await TestFileManager.GetFileAsClosures(fileName); closures.Count.Should().Be(oldCount); - var o = new ObjectLoader(new DummySqLiteReceiveManager(closures), new ExceptionServerObjectManager(), null); - using var process = new DeserializeProcess( + await using var process = new DeserializeProcess( + new DummySqLiteReceiveManager(closures), + new ExceptionServerObjectManager(), null, - o, new BaseDeserializer(new ObjectDeserializerFactory()), new NullLoggerFactory(), default, @@ -92,14 +117,10 @@ public class ExceptionTests var closures = await TestFileManager.GetFileAsClosures(fileName); closures.Count.Should().Be(oldCount); - var o = new ObjectLoader( + await using var process = new DeserializeProcess( new ExceptionSendCacheManager(hasObject), new DummyReceiveServerObjectManager(closures), - null - ); - using var process = new DeserializeProcess( null, - o, new BaseDeserializer(new ObjectDeserializerFactory()), new NullLoggerFactory(), default, diff --git a/tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.cs b/tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.cs index bf347fc4..0bd05a14 100644 --- a/tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.cs +++ b/tests/Speckle.Sdk.Serialization.Tests/ExplicitInterfaceTests.cs @@ -19,7 +19,7 @@ public class ExplicitInterfaceTests var testClass = new TestClass() { RegularProperty = "Hello" }; var objects = new Dictionary(); - using var process2 = new SerializeProcess( + await using var process2 = new SerializeProcess( null, new DummySendCacheManager(objects), new DummyServerObjectManager(), diff --git a/tests/Speckle.Sdk.Serialization.Tests/SerializationTests.cs b/tests/Speckle.Sdk.Serialization.Tests/SerializationTests.cs index 4d6f9e9f..64db5cb9 100644 --- a/tests/Speckle.Sdk.Serialization.Tests/SerializationTests.cs +++ b/tests/Speckle.Sdk.Serialization.Tests/SerializationTests.cs @@ -19,13 +19,9 @@ public class SerializationTests { private class TestLoader(string json) : IObjectLoader { - public Task<(Json, IReadOnlyCollection)> GetAndCache( - string rootId, - DeserializeProcessOptions? options, - CancellationToken cancellationToken - ) + public Task<(Json, IReadOnlyCollection)> GetAndCache(string rootId, DeserializeProcessOptions? options) { - var childrenIds = ClosureParser.GetChildrenIds(new(json), cancellationToken).Select(x => new Id(x)).ToList(); + var childrenIds = ClosureParser.GetChildrenIds(new(json), default).Select(x => new Id(x)).ToList(); return Task.FromResult<(Json, IReadOnlyCollection)>((new(json), childrenIds)); } @@ -49,11 +45,7 @@ public class SerializationTests public class TestObjectLoader(IReadOnlyDictionary idToObject) : IObjectLoader { - public Task<(Json, IReadOnlyCollection)> GetAndCache( - string rootId, - DeserializeProcessOptions? options, - CancellationToken cancellationToken - ) + public Task<(Json, IReadOnlyCollection)> GetAndCache(string rootId, DeserializeProcessOptions? options) { var json = idToObject.GetValueOrDefault(rootId); if (json == null) @@ -61,7 +53,7 @@ public class SerializationTests throw new KeyNotFoundException("Root not found"); } - var allChildren = ClosureParser.GetChildrenIds(json, cancellationToken).Select(x => new Id(x)).ToList(); + var allChildren = ClosureParser.GetChildrenIds(json, default).Select(x => new Id(x)).ToList(); return Task.FromResult<(Json, IReadOnlyCollection)>((new(json), allChildren)); } @@ -115,9 +107,9 @@ public class SerializationTests public async Task Basic_Namespace_Validation_New(string fileName) { var closures = await TestFileManager.GetFileAsClosures(fileName); - using var process = new DeserializeProcess( - null, + await using var process = new DeserializeProcess( new TestObjectLoader(closures), + null, new BaseDeserializer(new ObjectDeserializerFactory()), new NullLoggerFactory(), default @@ -210,25 +202,31 @@ public class SerializationTests var closures = await TestFileManager.GetFileAsClosures(fileName); closures.Count.Should().Be(oldCount); - var o = new ObjectLoader( - new DummySqLiteReceiveManager(closures), - new DummyReceiveServerObjectManager(closures), - null - ); - using var process = new DeserializeProcess( - null, - o, - new BaseDeserializer(new ObjectDeserializerFactory()), - new NullLoggerFactory(), - default, - new(true) - ); - var root = await process.Deserialize(rootId); - process.BaseCache.Count.Should().Be(oldCount); - process.Total.Should().Be(oldCount); + Base root; + using ( + var o = new ObjectLoader( + new DummySqLiteReceiveManager(closures), + new DummyReceiveServerObjectManager(closures), + null, + default + ) + ) + { + await using var process = new DeserializeProcess( + o, + null, + new BaseDeserializer(new ObjectDeserializerFactory()), + new NullLoggerFactory(), + default, + new(true) + ); + root = await process.Deserialize(rootId); + process.BaseCache.Count.Should().Be(oldCount); + process.Total.Should().Be(oldCount); + } var newIdToJson = new ConcurrentDictionary(); - using ( + await using ( var serializeProcess = new SerializeProcess( null, new DummySqLiteSendManager(), @@ -244,8 +242,6 @@ public class SerializationTests var (rootId2, _) = await serializeProcess.Serialize(root); rootId2.Should().Be(root.id); } - //ensures threads are done? - await Task.Delay(TimeSpan.FromSeconds(2)); newIdToJson.Count.Should().Be(newCount); foreach (var newKvp in newIdToJson) diff --git a/tests/Speckle.Sdk.Serialization.Tests/Speckle.Sdk.Serialization.Tests.csproj b/tests/Speckle.Sdk.Serialization.Tests/Speckle.Sdk.Serialization.Tests.csproj index 7984465a..47352da9 100644 --- a/tests/Speckle.Sdk.Serialization.Tests/Speckle.Sdk.Serialization.Tests.csproj +++ b/tests/Speckle.Sdk.Serialization.Tests/Speckle.Sdk.Serialization.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/tests/Speckle.Sdk.Serialization.Tests/packages.lock.json b/tests/Speckle.Sdk.Serialization.Tests/packages.lock.json index 89088e95..3eb30310 100644 --- a/tests/Speckle.Sdk.Serialization.Tests/packages.lock.json +++ b/tests/Speckle.Sdk.Serialization.Tests/packages.lock.json @@ -16,12 +16,12 @@ }, "Microsoft.NET.Test.Sdk": { "type": "Direct", - "requested": "[17.12.0, )", - "resolved": "17.12.0", - "contentHash": "kt/PKBZ91rFCWxVIJZSgVLk+YR+4KxTuHf799ho8WNiK5ZQpJNAEZCAWX86vcKrs+DiYjiibpYKdGZP6+/N17w==", + "requested": "[17.13.0, )", + "resolved": "17.13.0", + "contentHash": "W19wCPizaIC9Zh47w8wWI/yxuqR7/dtABwOrc8r2jX/8mUNxM2vw4fXDh+DJTeogxV+KzKwg5jNNGQVwf3LXyA==", "dependencies": { - "Microsoft.CodeCoverage": "17.12.0", - "Microsoft.TestPlatform.TestHost": "17.12.0" + "Microsoft.CodeCoverage": "17.13.0", + "Microsoft.TestPlatform.TestHost": "17.13.0" } }, "Microsoft.SourceLink.GitHub": { @@ -54,9 +54,9 @@ }, "xunit.runner.visualstudio": { "type": "Direct", - "requested": "[3.0.1, )", - "resolved": "3.0.1", - "contentHash": "lbyYtsBxA8Pz8kaf5Xn/Mj1mL9z2nlBWdZhqFaj66nxXBa4JwiTDm4eGcpSMet6du9TOWI6bfha+gQR6+IHawg==" + "requested": "[3.0.2, )", + "resolved": "3.0.2", + "contentHash": "oXbusR6iPq0xlqoikjdLvzh+wQDkMv9If58myz9MEzldS4nIcp442Btgs2sWbYWV+caEluMe2pQCZ0hUZgPiow==" }, "Argon": { "type": "Transitive", @@ -110,8 +110,8 @@ }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA==" + "resolved": "17.13.0", + "contentHash": "9LIUy0y+DvUmEPtbRDw6Bay3rzwqFV8P4efTrK4CZhQle3M/QwLPjISghfcolmEGAPWxuJi6m98ZEfk4VR4Lfg==" }, "Microsoft.Data.Sqlite.Core": { "type": "Transitive", @@ -176,18 +176,18 @@ }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==", + "resolved": "17.13.0", + "contentHash": "bt0E0Dx+iqW97o4A59RCmUmz/5NarJ7LRL+jXbSHod72ibL5XdNm1Ke+UO5tFhBG4VwHLcSjqq9BUSblGNWamw==", "dependencies": { "System.Reflection.Metadata": "1.6.0" } }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "MiPEJQNyADfwZ4pJNpQex+t9/jOClBGMiCiVVFuELCMSX2nmNfvUor3uFVxNNCg30uxDP8JDYfPnMXQzsfzYyg==", + "resolved": "17.13.0", + "contentHash": "9GGw08Dc3AXspjekdyTdZ/wYWFlxbgcF0s7BKxzVX+hzAwpifDOdxM+ceVaaJSQOwqt3jtuNlHn3XTpKUS9x9Q==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "17.12.0", + "Microsoft.TestPlatform.ObjectModel": "17.13.0", "Newtonsoft.Json": "13.0.1" } }, @@ -339,10 +339,10 @@ "dependencies": { "GraphQL.Client": "[6.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -353,11 +353,11 @@ "speckle.sdk.testing": { "type": "Project", "dependencies": { - "Microsoft.NET.Test.Sdk": "[17.12.0, )", + "Microsoft.NET.Test.Sdk": "[17.13.0, )", "Speckle.Sdk": "[1.0.0, )", "Verify.Quibble": "[2.1.1, )", "Verify.Xunit": "[28.10.1, )", - "xunit.runner.visualstudio": "[3.0.1, )" + "xunit.runner.visualstudio": "[3.0.2, )" } }, "GraphQL.Client": { @@ -379,7 +379,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -389,13 +389,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -407,9 +407,9 @@ }, "Speckle.DoubleNumerics": { "type": "CentralTransitive", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.Newtonsoft.Json": { "type": "CentralTransitive", diff --git a/Speckle.Sdk.Testing/Framework/AggregationExceptionScrubber.cs b/tests/Speckle.Sdk.Testing/Framework/AggregationExceptionScrubber.cs similarity index 100% rename from Speckle.Sdk.Testing/Framework/AggregationExceptionScrubber.cs rename to tests/Speckle.Sdk.Testing/Framework/AggregationExceptionScrubber.cs diff --git a/Speckle.Sdk.Testing/Framework/DummyReceiveServerObjectManager.cs b/tests/Speckle.Sdk.Testing/Framework/DummyReceiveServerObjectManager.cs similarity index 100% rename from Speckle.Sdk.Testing/Framework/DummyReceiveServerObjectManager.cs rename to tests/Speckle.Sdk.Testing/Framework/DummyReceiveServerObjectManager.cs diff --git a/Speckle.Sdk.Testing/Framework/DummySendServerObjectManager.cs b/tests/Speckle.Sdk.Testing/Framework/DummySendServerObjectManager.cs similarity index 100% rename from Speckle.Sdk.Testing/Framework/DummySendServerObjectManager.cs rename to tests/Speckle.Sdk.Testing/Framework/DummySendServerObjectManager.cs diff --git a/Speckle.Sdk.Testing/Framework/DummySqLiteReceiveManager.cs b/tests/Speckle.Sdk.Testing/Framework/DummySqLiteReceiveManager.cs similarity index 100% rename from Speckle.Sdk.Testing/Framework/DummySqLiteReceiveManager.cs rename to tests/Speckle.Sdk.Testing/Framework/DummySqLiteReceiveManager.cs diff --git a/Speckle.Sdk.Testing/Framework/DummySqLiteSendManager.cs b/tests/Speckle.Sdk.Testing/Framework/DummySqLiteSendManager.cs similarity index 100% rename from Speckle.Sdk.Testing/Framework/DummySqLiteSendManager.cs rename to tests/Speckle.Sdk.Testing/Framework/DummySqLiteSendManager.cs diff --git a/Speckle.Sdk.Testing/Framework/ExceptionScrubber.cs b/tests/Speckle.Sdk.Testing/Framework/ExceptionScrubber.cs similarity index 100% rename from Speckle.Sdk.Testing/Framework/ExceptionScrubber.cs rename to tests/Speckle.Sdk.Testing/Framework/ExceptionScrubber.cs diff --git a/Speckle.Sdk.Testing/Framework/IdStringSerializer.cs b/tests/Speckle.Sdk.Testing/Framework/IdStringSerializer.cs similarity index 100% rename from Speckle.Sdk.Testing/Framework/IdStringSerializer.cs rename to tests/Speckle.Sdk.Testing/Framework/IdStringSerializer.cs diff --git a/Speckle.Sdk.Testing/Framework/JsonStringSerializer.cs b/tests/Speckle.Sdk.Testing/Framework/JsonStringSerializer.cs similarity index 100% rename from Speckle.Sdk.Testing/Framework/JsonStringSerializer.cs rename to tests/Speckle.Sdk.Testing/Framework/JsonStringSerializer.cs diff --git a/Speckle.Sdk.Testing/Global.cs b/tests/Speckle.Sdk.Testing/Global.cs similarity index 100% rename from Speckle.Sdk.Testing/Global.cs rename to tests/Speckle.Sdk.Testing/Global.cs diff --git a/Speckle.Sdk.Testing/Speckle.Sdk.Testing.csproj b/tests/Speckle.Sdk.Testing/Speckle.Sdk.Testing.csproj similarity index 85% rename from Speckle.Sdk.Testing/Speckle.Sdk.Testing.csproj rename to tests/Speckle.Sdk.Testing/Speckle.Sdk.Testing.csproj index ba4b54c6..b5ecb4ed 100644 --- a/Speckle.Sdk.Testing/Speckle.Sdk.Testing.csproj +++ b/tests/Speckle.Sdk.Testing/Speckle.Sdk.Testing.csproj @@ -13,7 +13,7 @@ - + diff --git a/Speckle.Sdk.Testing/SpeckleVerify.cs b/tests/Speckle.Sdk.Testing/SpeckleVerify.cs similarity index 100% rename from Speckle.Sdk.Testing/SpeckleVerify.cs rename to tests/Speckle.Sdk.Testing/SpeckleVerify.cs diff --git a/Speckle.Sdk.Testing/VerifyTests.cs b/tests/Speckle.Sdk.Testing/VerifyTests.cs similarity index 100% rename from Speckle.Sdk.Testing/VerifyTests.cs rename to tests/Speckle.Sdk.Testing/VerifyTests.cs diff --git a/Speckle.Sdk.Testing/packages.lock.json b/tests/Speckle.Sdk.Testing/packages.lock.json similarity index 91% rename from Speckle.Sdk.Testing/packages.lock.json rename to tests/Speckle.Sdk.Testing/packages.lock.json index c11b7ca1..64fa5df7 100644 --- a/Speckle.Sdk.Testing/packages.lock.json +++ b/tests/Speckle.Sdk.Testing/packages.lock.json @@ -4,12 +4,12 @@ "net8.0": { "Microsoft.NET.Test.Sdk": { "type": "Direct", - "requested": "[17.12.0, )", - "resolved": "17.12.0", - "contentHash": "kt/PKBZ91rFCWxVIJZSgVLk+YR+4KxTuHf799ho8WNiK5ZQpJNAEZCAWX86vcKrs+DiYjiibpYKdGZP6+/N17w==", + "requested": "[17.13.0, )", + "resolved": "17.13.0", + "contentHash": "W19wCPizaIC9Zh47w8wWI/yxuqR7/dtABwOrc8r2jX/8mUNxM2vw4fXDh+DJTeogxV+KzKwg5jNNGQVwf3LXyA==", "dependencies": { - "Microsoft.CodeCoverage": "17.12.0", - "Microsoft.TestPlatform.TestHost": "17.12.0" + "Microsoft.CodeCoverage": "17.13.0", + "Microsoft.TestPlatform.TestHost": "17.13.0" } }, "Microsoft.SourceLink.GitHub": { @@ -62,9 +62,9 @@ }, "xunit.runner.visualstudio": { "type": "Direct", - "requested": "[3.0.1, )", - "resolved": "3.0.1", - "contentHash": "lbyYtsBxA8Pz8kaf5Xn/Mj1mL9z2nlBWdZhqFaj66nxXBa4JwiTDm4eGcpSMet6du9TOWI6bfha+gQR6+IHawg==" + "requested": "[3.0.2, )", + "resolved": "3.0.2", + "contentHash": "oXbusR6iPq0xlqoikjdLvzh+wQDkMv9If58myz9MEzldS4nIcp442Btgs2sWbYWV+caEluMe2pQCZ0hUZgPiow==" }, "Argon": { "type": "Transitive", @@ -118,8 +118,8 @@ }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA==" + "resolved": "17.13.0", + "contentHash": "9LIUy0y+DvUmEPtbRDw6Bay3rzwqFV8P4efTrK4CZhQle3M/QwLPjISghfcolmEGAPWxuJi6m98ZEfk4VR4Lfg==" }, "Microsoft.Data.Sqlite.Core": { "type": "Transitive", @@ -184,18 +184,18 @@ }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==", + "resolved": "17.13.0", + "contentHash": "bt0E0Dx+iqW97o4A59RCmUmz/5NarJ7LRL+jXbSHod72ibL5XdNm1Ke+UO5tFhBG4VwHLcSjqq9BUSblGNWamw==", "dependencies": { "System.Reflection.Metadata": "1.6.0" } }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "MiPEJQNyADfwZ4pJNpQex+t9/jOClBGMiCiVVFuELCMSX2nmNfvUor3uFVxNNCg30uxDP8JDYfPnMXQzsfzYyg==", + "resolved": "17.13.0", + "contentHash": "9GGw08Dc3AXspjekdyTdZ/wYWFlxbgcF0s7BKxzVX+hzAwpifDOdxM+ceVaaJSQOwqt3jtuNlHn3XTpKUS9x9Q==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "17.12.0", + "Microsoft.TestPlatform.ObjectModel": "17.13.0", "Newtonsoft.Json": "13.0.1" } }, @@ -341,10 +341,10 @@ "dependencies": { "GraphQL.Client": "[6.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -371,7 +371,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -381,13 +381,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -399,9 +399,9 @@ }, "Speckle.DoubleNumerics": { "type": "CentralTransitive", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.Newtonsoft.Json": { "type": "CentralTransitive", diff --git a/tests/Speckle.Sdk.Tests.Integration/packages.lock.json b/tests/Speckle.Sdk.Tests.Integration/packages.lock.json index 68b3c45e..32c8bf35 100644 --- a/tests/Speckle.Sdk.Tests.Integration/packages.lock.json +++ b/tests/Speckle.Sdk.Tests.Integration/packages.lock.json @@ -10,12 +10,12 @@ }, "Microsoft.NET.Test.Sdk": { "type": "Direct", - "requested": "[17.12.0, )", - "resolved": "17.12.0", - "contentHash": "kt/PKBZ91rFCWxVIJZSgVLk+YR+4KxTuHf799ho8WNiK5ZQpJNAEZCAWX86vcKrs+DiYjiibpYKdGZP6+/N17w==", + "requested": "[17.13.0, )", + "resolved": "17.13.0", + "contentHash": "W19wCPizaIC9Zh47w8wWI/yxuqR7/dtABwOrc8r2jX/8mUNxM2vw4fXDh+DJTeogxV+KzKwg5jNNGQVwf3LXyA==", "dependencies": { - "Microsoft.CodeCoverage": "17.12.0", - "Microsoft.TestPlatform.TestHost": "17.12.0" + "Microsoft.CodeCoverage": "17.13.0", + "Microsoft.TestPlatform.TestHost": "17.13.0" } }, "Microsoft.SourceLink.GitHub": { @@ -53,9 +53,9 @@ }, "xunit.runner.visualstudio": { "type": "Direct", - "requested": "[3.0.1, )", - "resolved": "3.0.1", - "contentHash": "lbyYtsBxA8Pz8kaf5Xn/Mj1mL9z2nlBWdZhqFaj66nxXBa4JwiTDm4eGcpSMet6du9TOWI6bfha+gQR6+IHawg==" + "requested": "[3.0.2, )", + "resolved": "3.0.2", + "contentHash": "oXbusR6iPq0xlqoikjdLvzh+wQDkMv9If58myz9MEzldS4nIcp442Btgs2sWbYWV+caEluMe2pQCZ0hUZgPiow==" }, "GraphQL.Client.Abstractions": { "type": "Transitive", @@ -85,8 +85,8 @@ }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA==" + "resolved": "17.13.0", + "contentHash": "9LIUy0y+DvUmEPtbRDw6Bay3rzwqFV8P4efTrK4CZhQle3M/QwLPjISghfcolmEGAPWxuJi6m98ZEfk4VR4Lfg==" }, "Microsoft.Data.Sqlite.Core": { "type": "Transitive", @@ -151,18 +151,18 @@ }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==", + "resolved": "17.13.0", + "contentHash": "bt0E0Dx+iqW97o4A59RCmUmz/5NarJ7LRL+jXbSHod72ibL5XdNm1Ke+UO5tFhBG4VwHLcSjqq9BUSblGNWamw==", "dependencies": { "System.Reflection.Metadata": "1.6.0" } }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "MiPEJQNyADfwZ4pJNpQex+t9/jOClBGMiCiVVFuELCMSX2nmNfvUor3uFVxNNCg30uxDP8JDYfPnMXQzsfzYyg==", + "resolved": "17.13.0", + "contentHash": "9GGw08Dc3AXspjekdyTdZ/wYWFlxbgcF0s7BKxzVX+hzAwpifDOdxM+ceVaaJSQOwqt3jtuNlHn3XTpKUS9x9Q==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "17.12.0", + "Microsoft.TestPlatform.ObjectModel": "17.13.0", "Newtonsoft.Json": "13.0.1" } }, @@ -266,10 +266,10 @@ "dependencies": { "GraphQL.Client": "[6.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -281,13 +281,13 @@ "type": "Project", "dependencies": { "AwesomeAssertions": "[8.0.0, )", - "Microsoft.Extensions.DependencyInjection": "[2.2.0, 2.2.0]", - "Microsoft.NET.Test.Sdk": "[17.12.0, )", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Extensions.DependencyInjection": "[2.2.0, )", + "Microsoft.NET.Test.Sdk": "[17.13.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Sdk": "[1.0.0, )", "altcover": "[9.0.1, )", "xunit": "[2.9.3, )", - "xunit.runner.visualstudio": "[3.0.1, )" + "xunit.runner.visualstudio": "[3.0.2, )" } }, "AwesomeAssertions": { @@ -315,7 +315,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -325,7 +325,7 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==", "dependencies": { @@ -334,13 +334,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -352,9 +352,9 @@ }, "Speckle.DoubleNumerics": { "type": "CentralTransitive", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.Newtonsoft.Json": { "type": "CentralTransitive", diff --git a/tests/Speckle.Sdk.Tests.Performance/Benchmarks/GeneralDeserializerTest.cs b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/GeneralDeserializerTest.cs index 3b1a4fc2..e6cc814a 100644 --- a/tests/Speckle.Sdk.Tests.Performance/Benchmarks/GeneralDeserializerTest.cs +++ b/tests/Speckle.Sdk.Tests.Performance/Benchmarks/GeneralDeserializerTest.cs @@ -56,10 +56,10 @@ public class GeneralDeserializer : IDisposable streamId, null ); - var o = new ObjectLoader(sqlite, serverObjects, null); - using var process = new DeserializeProcess( + await using var process = new DeserializeProcess( + sqlite, + serverObjects, null, - o, new BaseDeserializer(new ObjectDeserializerFactory()), default, new(skipCache) diff --git a/tests/Speckle.Sdk.Tests.Performance/packages.lock.json b/tests/Speckle.Sdk.Tests.Performance/packages.lock.json index d14d822b..7a4a7024 100644 --- a/tests/Speckle.Sdk.Tests.Performance/packages.lock.json +++ b/tests/Speckle.Sdk.Tests.Performance/packages.lock.json @@ -22,7 +22,7 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Direct", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==", "dependencies": { @@ -351,10 +351,10 @@ "dependencies": { "GraphQL.Client": "[6.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -375,7 +375,7 @@ }, "Microsoft.Bcl.AsyncInterfaces": { "type": "CentralTransitive", - "requested": "[5.0.0, 5.0.0]", + "requested": "[5.0.0, )", "resolved": "1.1.0", "contentHash": "1Am6l4Vpn3/K32daEqZI+FFr96OlZkgwK2LcT3pZ2zWubR5zTPW3/FkO1Rat9kb7oQOa4rxgl9LJHc5tspCWfg==" }, @@ -387,7 +387,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -397,13 +397,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": { @@ -415,9 +415,9 @@ }, "Speckle.DoubleNumerics": { "type": "CentralTransitive", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.Newtonsoft.Json": { "type": "CentralTransitive", diff --git a/tests/Speckle.Sdk.Tests.Unit/Serialisation/BatchTests.cs b/tests/Speckle.Sdk.Tests.Unit/Serialisation/BatchTests.cs index 9d8f2036..a23d44b2 100644 --- a/tests/Speckle.Sdk.Tests.Unit/Serialisation/BatchTests.cs +++ b/tests/Speckle.Sdk.Tests.Unit/Serialisation/BatchTests.cs @@ -7,14 +7,9 @@ namespace Speckle.Sdk.Tests.Unit.Serialisation; public class BatchTests { - private class BatchItem : IHasSize + private class BatchItem(int size) : IHasByteSize { - public BatchItem(int size) - { - Size = size; - } - - public int Size { get; } + public int ByteSize { get; } = size; } [Fact] @@ -22,9 +17,9 @@ public class BatchTests { using var batch = new Batch(); batch.Add(new BatchItem(1)); - batch.Size.Should().Be(1); + batch.BatchByteSize.Should().Be(1); batch.Add(new BatchItem(2)); - batch.Size.Should().Be(3); + batch.BatchByteSize.Should().Be(3); } [Fact] @@ -33,12 +28,74 @@ public class BatchTests using var batch = new Batch(); batch.Add(new BatchItem(1)); batch.Add(new BatchItem(2)); - batch.Size.Should().Be(3); + batch.BatchByteSize.Should().Be(3); batch.Items.Capacity.Should().Be(Pools.DefaultCapacity); batch.TrimExcess(); batch.Items.Capacity.Should().Be(2); - batch.Size.Should().Be(3); + batch.BatchByteSize.Should().Be(3); + } + + [Fact] + public void Basics() + { + using var batch = BatchExtensions.CreateBatch(); + batch.AddBatchItem(new BatchItem(2)); + batch.BatchByteSize.Should().Be(2); + batch.AddBatchItem(new BatchItem(2)); + batch.BatchByteSize.Should().Be(4); + batch.AddBatchItem(new BatchItem(2)); + batch.BatchByteSize.Should().Be(6); + + batch.TrimExcess(); + batch.BatchByteSize.Should().Be(6); + batch.Items.Count.Should().Be(3); + + batch.AddBatchItem(new BatchItem(2)); + batch.BatchByteSize.Should().Be(8); + batch.Items.Count.Should().Be(4); + } + + [Fact] + public void Large_Message_Problem_1() + { + const int MAX_BATCH_SIZE = 5; + + using var batch = BatchExtensions.CreateBatch(); + batch.AddBatchItem(new BatchItem(2)); + bool full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE; + full.Should().BeFalse(); + batch.AddBatchItem(new BatchItem(2)); + full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE; + full.Should().BeFalse(); + batch.AddBatchItem(new BatchItem(2)); + full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE; + full.Should().BeTrue(); + } + + [Fact] + public void Large_Message_Problem_2() + { + const int MAX_BATCH_SIZE = 5; + + using var batch = BatchExtensions.CreateBatch(); + batch.AddBatchItem(new BatchItem(63)); + bool full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE; + full.Should().BeTrue(); + } + + [Fact] + public void Large_Message_Problem_3() + { + const int MAX_BATCH_SIZE = 5; + + using var batch = BatchExtensions.CreateBatch(); + batch.AddBatchItem(new BatchItem(2)); + bool full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE; + full.Should().BeFalse(); + batch.AddBatchItem(new BatchItem(63)); + full = batch.GetBatchSize(MAX_BATCH_SIZE) == MAX_BATCH_SIZE; + full.Should().BeTrue(); } } diff --git a/tests/Speckle.Sdk.Tests.Unit/packages.lock.json b/tests/Speckle.Sdk.Tests.Unit/packages.lock.json index f0639add..07972a13 100644 --- a/tests/Speckle.Sdk.Tests.Unit/packages.lock.json +++ b/tests/Speckle.Sdk.Tests.Unit/packages.lock.json @@ -16,7 +16,7 @@ }, "Microsoft.Extensions.DependencyInjection": { "type": "Direct", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==", "dependencies": { @@ -25,12 +25,12 @@ }, "Microsoft.NET.Test.Sdk": { "type": "Direct", - "requested": "[17.12.0, )", - "resolved": "17.12.0", - "contentHash": "kt/PKBZ91rFCWxVIJZSgVLk+YR+4KxTuHf799ho8WNiK5ZQpJNAEZCAWX86vcKrs+DiYjiibpYKdGZP6+/N17w==", + "requested": "[17.13.0, )", + "resolved": "17.13.0", + "contentHash": "W19wCPizaIC9Zh47w8wWI/yxuqR7/dtABwOrc8r2jX/8mUNxM2vw4fXDh+DJTeogxV+KzKwg5jNNGQVwf3LXyA==", "dependencies": { - "Microsoft.CodeCoverage": "17.12.0", - "Microsoft.TestPlatform.TestHost": "17.12.0" + "Microsoft.CodeCoverage": "17.13.0", + "Microsoft.TestPlatform.TestHost": "17.13.0" } }, "Microsoft.SourceLink.GitHub": { @@ -51,9 +51,9 @@ }, "Speckle.DoubleNumerics": { "type": "Direct", - "requested": "[4.0.1, )", - "resolved": "4.0.1", - "contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w==" + "requested": "[4.1.0, )", + "resolved": "4.1.0", + "contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A==" }, "Speckle.InterfaceGenerator": { "type": "Direct", @@ -74,9 +74,9 @@ }, "xunit.runner.visualstudio": { "type": "Direct", - "requested": "[3.0.1, )", - "resolved": "3.0.1", - "contentHash": "lbyYtsBxA8Pz8kaf5Xn/Mj1mL9z2nlBWdZhqFaj66nxXBa4JwiTDm4eGcpSMet6du9TOWI6bfha+gQR6+IHawg==" + "requested": "[3.0.2, )", + "resolved": "3.0.2", + "contentHash": "oXbusR6iPq0xlqoikjdLvzh+wQDkMv9If58myz9MEzldS4nIcp442Btgs2sWbYWV+caEluMe2pQCZ0hUZgPiow==" }, "GraphQL.Client.Abstractions": { "type": "Transitive", @@ -106,8 +106,8 @@ }, "Microsoft.CodeCoverage": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA==" + "resolved": "17.13.0", + "contentHash": "9LIUy0y+DvUmEPtbRDw6Bay3rzwqFV8P4efTrK4CZhQle3M/QwLPjISghfcolmEGAPWxuJi6m98ZEfk4VR4Lfg==" }, "Microsoft.Data.Sqlite.Core": { "type": "Transitive", @@ -172,18 +172,18 @@ }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==", + "resolved": "17.13.0", + "contentHash": "bt0E0Dx+iqW97o4A59RCmUmz/5NarJ7LRL+jXbSHod72ibL5XdNm1Ke+UO5tFhBG4VwHLcSjqq9BUSblGNWamw==", "dependencies": { "System.Reflection.Metadata": "1.6.0" } }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", - "resolved": "17.12.0", - "contentHash": "MiPEJQNyADfwZ4pJNpQex+t9/jOClBGMiCiVVFuELCMSX2nmNfvUor3uFVxNNCg30uxDP8JDYfPnMXQzsfzYyg==", + "resolved": "17.13.0", + "contentHash": "9GGw08Dc3AXspjekdyTdZ/wYWFlxbgcF0s7BKxzVX+hzAwpifDOdxM+ceVaaJSQOwqt3jtuNlHn3XTpKUS9x9Q==", "dependencies": { - "Microsoft.TestPlatform.ObjectModel": "17.12.0", + "Microsoft.TestPlatform.ObjectModel": "17.13.0", "Newtonsoft.Json": "13.0.1" } }, @@ -287,10 +287,10 @@ "dependencies": { "GraphQL.Client": "[6.0.0, )", "Microsoft.CSharp": "[4.7.0, )", - "Microsoft.Data.Sqlite": "[7.0.5, 7.0.5]", - "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, 2.2.0]", - "Microsoft.Extensions.Logging": "[2.2.0, 2.2.0]", - "Speckle.DoubleNumerics": "[4.0.1, )", + "Microsoft.Data.Sqlite": "[7.0.5, )", + "Microsoft.Extensions.DependencyInjection.Abstractions": "[2.2.0, )", + "Microsoft.Extensions.Logging": "[2.2.0, )", + "Speckle.DoubleNumerics": "[4.1.0, )", "Speckle.Newtonsoft.Json": "[13.0.2, )", "Speckle.Sdk.Dependencies": "[1.0.0, )" } @@ -317,7 +317,7 @@ }, "Microsoft.Data.Sqlite": { "type": "CentralTransitive", - "requested": "[7.0.5, 7.0.5]", + "requested": "[7.0.5, )", "resolved": "7.0.5", "contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==", "dependencies": { @@ -327,13 +327,13 @@ }, "Microsoft.Extensions.DependencyInjection.Abstractions": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw==" }, "Microsoft.Extensions.Logging": { "type": "CentralTransitive", - "requested": "[2.2.0, 2.2.0]", + "requested": "[2.2.0, )", "resolved": "2.2.0", "contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==", "dependencies": {