Skip to content

Commit

Permalink
Added DUI3 Operations.Send changes to Sdk (#68)
Browse files Browse the repository at this point in the history
* Added DUI3 Operations.Send changes to Sdk

* Tests

* more tests

---------

Co-authored-by: Dimitrie Stefanescu <[email protected]>
  • Loading branch information
JR-Morgan and didimitrie authored Aug 12, 2024
1 parent cfc4018 commit 66b3c5e
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 67 deletions.
2 changes: 1 addition & 1 deletion src/Speckle.Sdk/Api/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public static async Task<string> Send(
using var transport = serverTransportFactory.Create(client.Account, sw.StreamId);
var branchName = string.IsNullOrEmpty(sw.BranchName) ? "main" : sw.BranchName;

var objectId = await Operations.Send(data, transport, useDefaultCache, onProgressAction).ConfigureAwait(false);
var (objectId, _) = await Operations.Send(data, transport, useDefaultCache, onProgressAction).ConfigureAwait(false);

Analytics.TrackEvent(client.Account, Analytics.Events.Send);

Expand Down
39 changes: 21 additions & 18 deletions src/Speckle.Sdk/Api/Operations/Operations.Send.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public static partial class Operations
/// <exception cref="ArgumentNullException">The <paramref name="transport"/> or <paramref name="value"/> was <see langword="null"/></exception>
/// <example><code>
/// using ServerTransport destination = new(account, streamId);
/// string objectId = await Send(mySpeckleObject, destination, true);
/// var (objectId, references) = await Send(mySpeckleObject, destination, true);
/// </code></example>
public static async Task<string> Send(
public static async Task<(string rootObjId, IReadOnlyDictionary<string, ObjectReference> convertedReferences)> Send(
Base value,
ITransport transport,
bool useDefaultCache,
Expand Down Expand Up @@ -58,7 +58,7 @@ public static async Task<string> Send(
/// <exception cref="SpeckleException">Serialization or Send operation was unsuccessful</exception>
/// <exception cref="TransportException">One or more <paramref name="transports"/> failed to send</exception>
/// <exception cref="OperationCanceledException">The <paramref name="cancellationToken"/> requested cancellation</exception>
public static async Task<string> Send(
public static async Task<(string rootObjId, IReadOnlyDictionary<string, ObjectReference> convertedReferences)> Send(
Base value,
IReadOnlyCollection<ITransport> transports,
Action<ConcurrentDictionary<string, int>>? onProgressAction = null,
Expand Down Expand Up @@ -87,7 +87,7 @@ public static async Task<string> Send(

var internalProgressAction = GetInternalProgressAction(onProgressAction);

BaseObjectSerializerV2 serializerV2 = new(transports, internalProgressAction, false, cancellationToken);
BaseObjectSerializerV2 serializerV2 = new(transports, internalProgressAction, true, cancellationToken);

foreach (var t in transports)
{
Expand All @@ -96,10 +96,25 @@ public static async Task<string> Send(
t.BeginWrite();
}

string hash;
try
{
hash = await SerializerSend(value, serializerV2, cancellationToken).ConfigureAwait(false);
var rootObjectId = await SerializerSend(value, serializerV2, cancellationToken).ConfigureAwait(false);

sendTimer.Stop();
activity?.SetTag("transportElapsedBreakdown", transports.ToDictionary(t => t.TransportName, t => t.Elapsed));
activity?.SetTag(
"note",
"the elapsed summary doesn't need to add up to the total elapsed... Threading magic..."
);
activity?.SetTag("serializerElapsed", serializerV2.Elapsed);
SpeckleLog.Logger.Information(
"Finished sending {objectCount} objects after {elapsed}, result {objectId}",
transports.Max(t => t.SavedObjectCount),
sendTimer.Elapsed.TotalSeconds,
rootObjectId
);

return (rootObjectId, serializerV2.ObjectReferences);
}
catch (Exception ex) when (!ex.IsFatal())
{
Expand All @@ -122,18 +137,6 @@ public static async Task<string> Send(
t.EndWrite();
}
}

sendTimer.Stop();
activity?.SetTag("transportElapsedBreakdown", transports.ToDictionary(t => t.TransportName, t => t.Elapsed));
activity?.SetTag("note", "the elapsed summary doesn't need to add up to the total elapsed... Threading magic...");
activity?.SetTag("serializerElapsed", serializerV2.Elapsed);
SpeckleLog.Logger.Information(
"Finished sending {objectCount} objects after {elapsed}, result {objectId}",
transports.Max(t => t.SavedObjectCount),
sendTimer.Elapsed.TotalSeconds,
hash
);
return hash;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Speckle.Sdk/Models/Extras.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ namespace Speckle.Sdk.Models;
/// See the following <see href="https://pics.me.me/chunky-boi-57848570.png">reference.</see>
/// </summary>
[SpeckleType("Speckle.Core.Models.DataChunk")]
public class DataChunk : Base
public sealed class DataChunk : Base
{
public List<object> data { get; set; } = new();
}

[SpeckleType("Speckle.Core.Models.ObjectReference")]
public class ObjectReference : Base
public sealed class ObjectReference : Base
{
public new string speckle_type = "reference";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ public async Task CommitCreate()

myObject["@Points"] = ptsList;

_objectId = await Operations.Send(myObject, new List<ITransport> { _myServerTransport });
(_objectId, _) = await Operations.Send(myObject, new List<ITransport> { _myServerTransport });

Assert.That(_objectId, Is.Not.Null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ public async Task SubscribeCommitCreated()

myObject["Points"] = ptsList;

var objectId = await Operations.Send(myObject, _myServerTransport, false);
var sendResult = await Operations.Send(myObject, _myServerTransport, false);

var commitInput = new CommitCreateInput
{
streamId = _streamId,
branchName = "awesome-features",
objectId = objectId,
objectId = sendResult.rootObjId,
message = "sending some test points",
sourceApplication = "Tests",
totalChildrenCount = 20
Expand Down
2 changes: 1 addition & 1 deletion tests/Speckle.Sdk.Tests.Integration/Fixtures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static async Task<Client> SeedUserWithClient()
public static async Task<string> CreateVersion(Client client, string projectId, string modelId)
{
using ServerTransport remote = new(client.Account, projectId);
var objectId = await Operations.Send(new() { applicationId = "ASDF" }, remote, false);
var (objectId, _) = await Operations.Send(new() { applicationId = "ASDF" }, remote, false);
CreateVersionInput input = new(objectId, modelId, projectId);
return await client.Version.Create(input);
}
Expand Down
12 changes: 6 additions & 6 deletions tests/Speckle.Sdk.Tests.Integration/ServerTransportTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ public async Task SendAndReceiveObjectWithBlobs()
var myObject = Fixtures.GenerateSimpleObject();
myObject["blobs"] = Fixtures.GenerateThreeBlobs();

var sentObjectId = await Operations.Send(myObject, _transport, false);
var sendResult = await Operations.Send(myObject, _transport, false);

// NOTE: used to debug diffing
// await Operations.Send(myObject, new List<ITransport> { transport });

var receivedObject = await Operations.Receive(sentObjectId, _transport, new MemoryTransport());
var receivedObject = await Operations.Receive(sendResult.rootObjId, _transport, new MemoryTransport());

var allFiles = Directory
.GetFiles(_transport.BlobStorageFolder)
Expand Down Expand Up @@ -108,9 +108,9 @@ public async Task SendWithBlobsWithoutSQLiteSendCache()
myObject["blobs"] = Fixtures.GenerateThreeBlobs();

var memTransport = new MemoryTransport();
var sentObjectId = await Operations.Send(myObject, new List<ITransport> { _transport, memTransport });
var sendResult = await Operations.Send(myObject, new List<ITransport> { _transport, memTransport });

var receivedObject = await Operations.Receive(sentObjectId, _transport, new MemoryTransport());
var receivedObject = await Operations.Receive(sendResult.rootObjId, _transport, new MemoryTransport());

var allFiles = Directory
.GetFiles(_transport.BlobStorageFolder)
Expand Down Expand Up @@ -141,10 +141,10 @@ public async Task SendReceiveWithCleanedMemoryCache()
myObject["blobs"] = Fixtures.GenerateThreeBlobs();

var memTransport = new MemoryTransport();
var sentObjectId = await Operations.Send(myObject, new ITransport[] { _transport, memTransport });
var sendResult = await Operations.Send(myObject, new ITransport[] { _transport, memTransport });

memTransport = new MemoryTransport();
Base receivedObject = await Operations.Receive(sentObjectId, _transport, memTransport);
Base receivedObject = await Operations.Receive(sendResult.rootObjId, _transport, memTransport);
Assert.That(receivedObject, Is.Not.Null);

var allFiles = Directory
Expand Down
6 changes: 3 additions & 3 deletions tests/Speckle.Sdk.Tests.Unit/Api/Operations/ClosureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public void Setup()
}

[Test(Description = "Checks whether closures are generated correctly by the serialiser.")]
public void CorrectDecompositionTracking()
public async Task CorrectDecompositionTracking()
{
var d5 = new Base();
((dynamic)d5).name = "depth five"; // end v
Expand All @@ -45,9 +45,9 @@ public void CorrectDecompositionTracking()

var transport = new MemoryTransport();

var result = Sdk.Api.Operations.Send(d1, transport, false).Result;
var sendResult = await Sdk.Api.Operations.Send(d1, transport, false);

var test = Sdk.Api.Operations.Receive(result, localTransport: transport).Result;
var test = await Sdk.Api.Operations.Receive(sendResult.rootObjId, localTransport: transport);

test.id.NotNull();
Assert.That(d1.GetId(true), Is.EqualTo(test.id));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using NUnit.Framework;
using Speckle.Sdk.Models;
using Speckle.Sdk.Transports;

namespace Speckle.Sdk.Tests.Unit.Api.Operations;

public class SendObjectReferences
{
[TestCase(0)]
[TestCase(1)]
[TestCase(10)]
public async Task SendObjectsWithApplicationIds(int testDepth)
{
Base testData = GenerateTestCase(testDepth, true);
MemoryTransport transport = new();
var result = await Speckle.Sdk.Api.Operations.Send(testData, [transport]);

Assert.That(result.rootObjId, Is.Not.Null);
Assert.That(result.rootObjId, Has.Length.EqualTo(32));

Assert.That(result.convertedReferences, Has.Count.EqualTo(Math.Pow(2, testDepth + 1) - 2));
}

[TestCase(0)]
[TestCase(1)]
[TestCase(10)]
public async Task SendObjectsWithoutApplicationIds(int testDepth)
{
Base testData = GenerateTestCase(testDepth, false);
MemoryTransport transport = new();
var result = await Speckle.Sdk.Api.Operations.Send(testData, [transport]);

Assert.That(result.rootObjId, Is.Not.Null);
Assert.That(result.rootObjId, Has.Length.EqualTo(32));

Assert.That(result.convertedReferences, Is.Empty);
}

private Base GenerateTestCase(int depth, bool withAppId)
{
var appId = withAppId ? $"{Guid.NewGuid()}" : null;
var ret = new Base() { applicationId = appId, };
if (depth > 0)
{
ret["@elements"] = new List<Base>
{
GenerateTestCase(depth - 1, withAppId),
GenerateTestCase(depth - 1, withAppId)
};
}

return ret;
}
}
44 changes: 11 additions & 33 deletions tests/Speckle.Sdk.Tests.Unit/Api/Operations/SendReceiveLocal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ public async Task LocalUpload()
}

using SQLiteTransport localTransport = new();
_objId01 = await Sdk.Api.Operations.Send(myObject, localTransport, false);
(_objId01, var references) = await Sdk.Api.Operations.Send(myObject, localTransport, false);

Assert.That(_objId01, Is.Not.Null);
Assert.That(references, Has.Count.EqualTo(NUM_OBJECTS));

TestContext.Out.WriteLine($"Written {NUM_OBJECTS + 1} objects. Commit id is {_objId01}");
}

Expand Down Expand Up @@ -71,7 +73,7 @@ public async Task LocalUploadDownload()
);
}

_objId01 = await Sdk.Api.Operations.Send(myObject, _sut, false);
(_objId01, _) = await Sdk.Api.Operations.Send(myObject, _sut, false);

var commitPulled = await Sdk.Api.Operations.Receive(_objId01);
List<object> items = (List<object>)commitPulled["@items"].NotNull();
Expand All @@ -95,7 +97,7 @@ public async Task LocalUploadDownloadSmall()
);
}

_objId01 = await Sdk.Api.Operations.Send(myObject, _sut, false);
(_objId01, _) = await Sdk.Api.Operations.Send(myObject, _sut, false);

Assert.That(_objId01, Is.Not.Null);
TestContext.Out.WriteLine($"Written {NUM_OBJECTS + 1} objects. Commit id is {_objId01}");
Expand All @@ -119,7 +121,7 @@ public async Task LocalUploadDownloadListDic()
myObject["@dictionary"] = myDic;
myObject["@list"] = myList;

_objId01 = await Sdk.Api.Operations.Send(myObject, _sut, false);
(_objId01, _) = await Sdk.Api.Operations.Send(myObject, _sut, false);

Assert.That(_objId01, Is.Not.Null);

Expand Down Expand Up @@ -157,7 +159,7 @@ public async Task UploadDownloadNonCommitObject()
((List<Base>)((dynamic)obj)["@LayerC"]).Add(new Point(i, i, i + rand.NextDouble()) { applicationId = i + "baz" });
}

_objId01 = await Sdk.Api.Operations.Send(obj, _sut, false);
(_objId01, _) = await Sdk.Api.Operations.Send(obj, _sut, false);

Assert.That(_objId01, Is.Not.Null);
TestContext.Out.WriteLine($"Written {NUM_OBJECTS + 1} objects. Commit id is {_objId01}");
Expand Down Expand Up @@ -195,7 +197,7 @@ public async Task UploadProgressReports()
}

ConcurrentDictionary<string, int>? progress = null;
_commitId02 = await Sdk.Api.Operations.Send(
(_commitId02, _) = await Sdk.Api.Operations.Send(
myObject,
_sut,
false,
Expand Down Expand Up @@ -230,37 +232,13 @@ public async Task ShouldNotDisposeTransports()
@base["test"] = "the best";

SQLiteTransport myLocalTransport = new();
var id = await Sdk.Api.Operations.Send(@base, myLocalTransport, false);
var sendResult = await Sdk.Api.Operations.Send(@base, myLocalTransport, false);
await Sdk.Api.Operations.Send(@base, myLocalTransport, false);

_ = await Sdk.Api.Operations.Receive(id, null, myLocalTransport);
await Sdk.Api.Operations.Receive(id, null, myLocalTransport);
_ = await Sdk.Api.Operations.Receive(sendResult.rootObjId, null, myLocalTransport);
await Sdk.Api.Operations.Receive(sendResult.rootObjId, null, myLocalTransport);
}

//[Test]
//public async Task DiskTransportTest()
//{
// var myObject = new Base();
// myObject["@items"] = new List<Base>();
// myObject["test"] = "random";

// var rand = new Random();

// for (int i = 0; i < 100; i++)
// {
// ((List<Base>)myObject["@items"]).Add(new Point(i, i, i) { applicationId = i + "-___/---" });
// }

// var dt = new Speckle.Sdk.Transports.Speckle.Speckle.Sdk.Transports();
// var id = await Operations.Send(myObject, new List<ITransport>() { dt }, false);

// Assert.IsNotNull(id);

// var rebase = await Operations.Receive(id, dt);

// Assert.AreEqual(rebase.GetId(true), id);
//}

public void Dispose()
{
_sut.Dispose();
Expand Down

0 comments on commit 66b3c5e

Please sign in to comment.