Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert Trace Serialization mechanism from SOAP to JSON #14530

Merged
merged 11 commits into from
Nov 17, 2023

Conversation

saintentropy
Copy link
Contributor

@saintentropy saintentropy commented Oct 29, 2023

Purpose

Experiment with alternative to the SOAP Formatter utilized in trace and Element binding data. This PR makes two primary changes related to trace:

Modify the public TraceSupport APIs to utilize string as the storage mechanism vs ISerializable. These are the primary mechanism for implementing Trace within ZT implementation.

  • ISerializable GetTraceData(string key) -> sting GetTraceData(string key)
  • SetTraceData(string key, ISerializable value) -> SetTraceData(string key, string value)

Modify the public Callsite APIs to return strings vs ISerializables. The following APIs are impacted. These are typically used by host integration for more advance manipulation of the trace data.

  • IList<ISerializable> GetOrphanedSerializables() -> IList<string> GetOrphanedSerializables()
  • IList<ISerializable> GetAllSerializablesFromSingleRunTraceData ->
    IList<string> GetAllSerializablesFromSingleRunTraceData

Modify the public virtual method on DynamoModel. I believe that DynamoRevit is the only downstream host that utilizes this mechanism.

  • PostTraceReconciliation(Dictionary<Guid, List<ISerializable>> orphanedSerializables) ->
    PostTraceReconciliation(Dictionary<Guid, List<string>> orphanedSerializables)

The second change to this PR is modification of the serialization mechanism used to store Element binding data in the file. Although these are public, I don't know of any other consumer. The primary change is modifying the SingleRunTraceData object main property public ISerializable Data -> public string Data. There are other methods on this class that change but all are ISerializable to string

Declarations

Check these if you believe they are true

  • The codebase is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated
  • This PR contains no files larger than 50 MB

Release Notes

Trace mechanism has dropped support for insecure SOAP deserialization, and now requires clients to use strings. Data is still intended to be opaque for users.

Reviewers

FYIs

@aparajit-pratap @mjkkirschner

@saintentropy saintentropy added the DNM Do not merge. For PRs. label Oct 29, 2023
@mjkkirschner
Copy link
Member

Two more thoughts

  1. What happens if you load a graph with a lot of old format trace data- do we get tons of Json exceptions? Can we dump old data from v2 graphs instead?
  2. I think there are some element binding performance graphs and tests floating around - I guess we’ll need up to update them as well.

@mjkkirschner mjkkirschner removed the DNM Do not merge. For PRs. label Nov 16, 2023
/// </summary>
/// <param name="serializedTraceData">The data to load</param>
public void LoadSerializedDataIntoTraceCache(string serializedTraceData)
{
if (serializedTraceData == null)
if (serializedTraceData == null || CheckIfTraceDataIsLegacySOAPFormat(serializedTraceData))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you skip the CheckIfTraceDataIsLegacy...?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then the try catch below will get hit and we'll end up doing a full base64 decode and catching an exception.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing we can do regarding your question about earlier catches and optimization of this check is handle something in here -> https://github.com/DynamoDS/Dynamo/blob/master/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs. This is the only place dynamo core encounters the Soap data. Maybe you can catch the old data there and then here the input string would be null. That might also help you with your task @aparajit-pratap . The nice thing is that the SerializationConverter is doing the whole Bindings section of the graph at once vs here were it is per callsite

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the D4C3D case we may just need to communicate the same pattern as the load data from dwg file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This optimization can be done later too. This function could stay the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually even better, if you catch bad data at the file deserialization then even the GetOrphanedSerializablesAndClearHistoricalTraceData pass would be short circuited. It is looking at HomeWorkSpace.PreloadedTraceData which is set during deserialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's just as simple as checking the DynamoVersion? Not full proof but in theory you should never have XML graph or a 2.x graph with good data.

@mjkkirschner mjkkirschner changed the title WIP Experiment: Convert Trace Serialization mechanism from SOAP to JSON Convert Trace Serialization mechanism from SOAP to JSON Nov 16, 2023
@saintentropy
Copy link
Contributor Author

Hey @mjkkirschner I also forgot we should remove the Soap Formatter
Here -> https://github.com/DynamoDS/Dynamo/blob/master/src/Engine/ProtoCore/ProtoCore.csproj#L26

log
shorten legacy check
Copy link

github-actions bot commented Nov 17, 2023

⚠️ [run-bin-diff-net60-windows] - Files Added/Deleted::1 file(s) have been deleted!
(Updated: 2023-11-17-02:07:25)

/// <returns>A flat collection of ISerializable objects.</returns>
public static IList<ISerializable> GetAllSerializablesFromSingleRunTraceData(
/// <returns>A flat collection of strings.</returns>
public static IList<string> GetAllSerializablesFromSingleRunTraceData(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On thing we may be able to verify is does this need to be public. Internal it is only called one place GetOrphanedSerializablesAndClearHistoricalTraceData... Maybe in terms of quick validation of old data we can do it upstream and escape calling this one by one per node guid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm. Looks like D4C3D calls it in their own version of GetAllSerializablesFromSingleRunTraceData.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So maybe stays public but we can also escape calls upstream and discuss with D4C3D the same optimization

Comment on lines +199 to +202
AssertPreviewValue("da39dbe5f59649b18c2fb6ca54acba7b", 6);
AssertPreviewValue("2366239164a9441a8c4dcd981d9cf542", 7);
AssertPreviewValue("8cfce012280342f3bd688520d68a7f66", 10);
AssertPreviewValue("08448232ee094aad8280e9a99ed44f46", 11);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, what are these values that have changed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handwritten values were replace with values generated by interacting with the graph instead. It's a bit harder to write values directly into trace by hand since the data is bas64 encoded and gzipped

Copy link
Member

@mjkkirschner mjkkirschner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit: self

@mjkkirschner mjkkirschner merged commit d8de392 into DynamoDS:master Nov 17, 2023
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants