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

DYN-1662: As a dynamo dev, I want to serialize what packages are needed in a graph #9723

Merged
merged 61 commits into from
Jun 3, 2019

Conversation

scottmitchell
Copy link
Collaborator

@scottmitchell scottmitchell commented May 19, 2019

Purpose

This PR adds PackageDependencies as a top level item in the .dyn file. Now, when a WorkspaceModel is serialized, it will collect locally installed package data from the package manager, and then serialize the data of those packages that are used in the graph. It currently looks like this:

"PackageDependencies": [
    {
      "Name": "HowickMaker",  // Zerotouch
      "Version": "0.3.0",
      "Dependents": [
        "f35f1f65418a4bf392e3176a28f2dd51"
      ]
    },
    {
      "Name": "NodeModelCharts",  // NodeModel
      "Version": "2.0.2",
      "Dependents": [
        "4c6e96b3da44456f81a52c587316cd3b",
        "d44934a410c54e72b2aeedd4b7bff526"
      ]
    },
    {
      "Name": "Clockwork for Dynamo 2.x",  // Custom Node
      "Version": "2.1.2",
      "Dependents": [
        "00d7d5e810d3443b9909980da84b8ce2"
      ]
    }
  ],

TODO:

  • Tests

Declarations

Check these if you believe they are true

  • The code base 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.

Reviewers

@mjkkirschner @QilongTang

FYIs

@varvaratou

@mjkkirschner
Copy link
Member

@gregmarr PTAL this PR impacts the schema.

@gregmarr
Copy link
Contributor

Are the three levels of nesting here ("Extensions": { "DynamoPackageManager": { "InstalledPackages") because additional sibling items are expected to be added in the future?

@scottmitchell
Copy link
Collaborator Author

@gregmarr Yes, part of the idea here is to have a general way for extensions to serialize data to the .dyn file. In the future, this could include other internally developed extensions, and 3rd party extensions. These would all be siblings within Extensions.

As far as the schema inside of DynamoPackageManager, I just threw InstalledPackages in there as a POC for now. What we really care about are the PackageDependencies of the .dyn (currently working on adding this). It's possible we would want to add sibling items here in the future.

@gregmarr
Copy link
Contributor

"part of the idea here is to have a general way for extensions to serialize data to the .dyn file. In the future, this could include other internally developed extensions, and 3rd party extensions. These would all be siblings within Extensions."

We already explicitly allow additional data under the View and NodeView sections. That's where Dynamo is putting its additional data.

As this is data about which packages are needed to run the graph, this should be top-level data, as a sibling to the existing Dependencies which is for graphs that this graph depends on.
https://git.autodesk.com/aecgd/cogs/blob/master/api/service.yaml#L1538-L1545

Something like this:

  PackageDependencies:
    description: Ids of `Package`s used by this `Graph`.
    x-omitempty: true
    type: array
    items:
      $ref: "#/definitions/Package"

Package:
  description: The information on a package available from the Package Manager.
  type: object
  required:
  - Name
  - Version
  properties:
    Name:
      description: The name of the package.
      type: string
      example: Dynamo Node Package
    Version:
      description: The version string for the package.
      type: string
      example: 1.2.3

@scottmitchell
Copy link
Collaborator Author

@gregmarr thanks for the feedback. Makes sense. I’ll adopt the schema you’ve described here.

@gregmarr
Copy link
Contributor

Another thing that it would be good to add to a Package record would be the type of contents. For example, if it's just custom nodes, or if it also contains ZT nodes.

@aparajit-pratap
Copy link
Contributor

@scottmitchell what was the original idea of letting extensions to serialize their data as JSON? Are there cases where the graph (nodes) could have a dependency on extensions (other than packages)?

@scottmitchell
Copy link
Collaborator Author

@aparajit-pratap I'm not sure that there are cases where the graphs depend on an extension (although that's an interesting question). The idea here was just to explore the possibility of allowing extension developers to serialize data to the dyn—just a new, potentially useful api.

…ame CollectingPackageDependencies -> CollectingLocalPackages.
@@ -436,6 +442,23 @@ protected virtual void OnSaving(XmlDocument obj)
if (handler != null) handler(obj);
}


/// <summary>
/// Event that is fired when the workspace is collecting top level assemblies referenced by nodes
Copy link
Member

@mjkkirschner mjkkirschner Jun 1, 2019

Choose a reason for hiding this comment

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

Is it true that only one workspace at a time will ever handle these events and only one extension will ever invoke them?

If those invariants needs to hold for this to make sense - then I think we should watch for those and log or throw if either of those are not true.

IE - check the invocationList and make sure it's only one etc. - At a minimum - add a comment.

@mjkkirschner
Copy link
Member

mjkkirschner commented Jun 2, 2019

@scottmitchell this is looking solid - I am still a bit concerned about serialization performance especially during backup save because the default backup time is pretty low at 60 seconds.

I think we need to test this with a large graph - it might make sense to add serialization to the performance bench tool in the future - not sure that needs to happen here - but at the minimum we need to know the impact for a large graph with a large set of packages. (this can be done with a single unit test, profiling manually etc)

@scottmitchell
Copy link
Collaborator Author

@mjkkirschner I did a couple performance tests with and without package dependency collection/serialization. Looks like it makes serialization ~10% slower:

Model.ToJson() time in ms

Condition master. 12 packages. 100 nodes master. 12 packages. 500 nodes DYN-1622. 12 packages. 100 nodes DYN-1622. 12 packages. 500 nodes
646 2614 572 1824
569 1526 565 2305
465 1591 549 1866
464 2082 578 1895
461 1548 546 1924
469 1548 556 1873
593 1838 598 1928
462 1616 563 2037
474 1615 567 1909
534 1972 746 1991
Average 513.7 1795 584 1955.2
New/Old 113.69% 108.92%

@mjkkirschner
Copy link
Member

LGTM

@mjkkirschner mjkkirschner added the LGTM Looks good to me label Jun 3, 2019
@scottmitchell scottmitchell merged commit f6f43e2 into DynamoDS:master Jun 3, 2019
@@ -800,6 +800,10 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
writer.WriteEndArray();
writer.WriteEndObject();
}
else
{
logger.LogWarning("Unnsuccessful attempt to serialize a PackageDependencyInfo object.", Logging.WarningLevel.Moderate);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be localizable?

Copy link
Contributor

Choose a reason for hiding this comment

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

Good point, we should escape the localization of it

@scottmitchell scottmitchell changed the title [PTAL] [WIP] DYN-1662: As a dynamo dev, I want to serialize what packages are needed in a graph DYN-1662: As a dynamo dev, I want to serialize what packages are needed in a graph Jun 4, 2019
@scottmitchell scottmitchell removed the WIP label Jun 4, 2019
mjkkirschner pushed a commit that referenced this pull request Aug 3, 2019
…ages are needed in a graph (#9723)

* Add Extensions block to json

* Serialize package manager data to new Extensions block

* Added IPackage interface

* Added IPackage interface

* Added PackageDependencies property to workspace model

* Added comments

* Unsubscribe from workspace on dispose

* Simplify CollectingAssembliesUsed

* assemblyPackageDict uses AssemblyName objects instead of strings. Rename CollectingPackageDependencies -> CollectingLocalPackages.

* NodeLibraries should be internal, not private

* assemblyPackageDict uses AssemblyName.FullName

* Use set for packageDependencies to avoid duplicates

* Add some comments to assembly collection

* AssemblyNames summary

* Adds PackageDependency serialization support for custom nodes from packages

* Rename GetCustomNodesPackagesFromGuids

* Rename GetCustomNodesPackagesFromGuids

* Add new PackageInfo class to replace IPackage for serialization

* Remove IPackage

* Move assembly name matching logic to PackageManager in order to remove AssemblyNames property from PackageInfo

* Remove unnecessary

* Fix AssemblyNames error

* Null check for PackageInfo converter

* Add obsolete attribute to events that should only be used by package manager

* Use InternalsVisibleTo to ensure only PM extension can subscribe to package dependency events

* Serialize IDs of nodes that are dependent on each package

* Update package manager dictionary logic for package load and remove events

* Fix Guid serialization

* Add comment to InternalsVisibleTo

* Name changes to make referencedAssembly use more clear

* Add comments to Assembly collection and make more efficient

* Comment added

* Remove unnecessary ref

* Removed Unecessary ref

* Comment fixes

* Rename PackageInfo -> PackageDependencyInfo

* Use Version type for PackageDependencyInfo Version property

* Rename Dependents -> Nodes

* Move GetAssembliesReferencedByNodes

* Added PackageDependency deserialization

* Simplify if statement

* Improve PackageDependencies update

* PackageDependency deserialization null check

* one line code improvements

* IsNodeLibrary check

* Remove unnecessary Any check

* Add unsuccessful PackageDependencyInfo serialization log

* Log message when node libraries or custom nodes are loaded by multiple packages

* Improved RemovedNodes handling

* Simplify descriptor lookup

* Update comments

* Store list of packages per assembly

* Store list of packages per custom node id

* Unsubscribe CurrentWorkspaceChanged

* lock packageDependencies

* Add NodePackageDictionary and CustomNodePackageDictionary null check

* Move assembly collection to WorkspaceModel because LibraryServices no longer required

* Remove white space

* Add "PackageDependencies" item to test .dyn

* Remove PackageDependencyInfo FullName property

* Throw exception for illegal subscribers to PackageDependency events
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LGTM Looks good to me
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants