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

restore behavior of extension loadNodeLibrary method #10187

Merged

Conversation

mjkkirschner
Copy link
Member

@mjkkirschner mjkkirschner commented Dec 3, 2019

Purpose

https://jira.autodesk.com/browse/DYN-2325
previously the method LoadNodeLibrary on dynamoModel - accessed via the extensionLibraryLoader had the behavior that it would successfully load zerotouch OR NodeModel assemblies and add them to the library.

after this pr:
#9736

this no longer works for zerotouch assemblies as the call is redirected to LibraryServices.LoadNodeLibrary instead of ImportLibrary - which no longer raises a LibraryLoaded event .

to remedy this I simply added the event raise back to the branch of code where a zero touch assembly is encountered. The libraryLoaded event, among other things, adds the zero touch nodes to search which updates the library view.

@aparajit-pratap does this have a negative impact on the work you did here? If thats the case we can isolate this by only adding the event raise to the ExtensionLibraryLoader class and keep it out of DynamoModel - but it does seem like a significant change in behavior and cause of confusion (zero touch functions are in the VM, but none of them are loaded into the library)

I would like to get this or the alternative (or something better) into 2.5 to avoid breaking integrations which rely on this functionality.

we will also need to add a test that ensures the searchModel is updated when this function is called. ✔️

Screen Shot 2019-12-02 at 6 58 41 PM

Update:

This PR now implements equals and getHashCode() for the NodeSearchElement base class - so that duplicate searchElements cannot be added to search if they contain matching properties. This was not a problem for builtin nodes, but for nodeModels and zeroTouch where we construct new nodeSearchElements whenever the importLibrary or loadNodeLibrary methods are called, this could lead to extra search entries being created if those apis were called from extensions.

The reason that we have this duplication problem when reverting back to ImportLibrary is that the method AddZeroTouchNodeToSearch is called when ImportLibrary is done importing, as it raises the event OnLibrariesImported for each library - then later, after all packages are loaded - the packageLoader raises the same handler via the PackageLoaded event. - calling AddZeroTouchNodeToSearch again.

so this solution works, but it leaves something to be desired, why do this extra work of scanning the zt functions again. I think other solutions might be

1. to remove the additional call in the packageLoader which re-raises the LibraryLoaded events - I believe @aparajit-pratap added this to finish importing all libraries into search only after all packages were loaded for a small speedup benefit, but it seems this may be the root of some of our issues. What do you think about removing this?

  1. We can add a new method like ImportLibrary - which does not raise the LoadedEvent and does not add anything to search - package manager extension can use this method instead of the public one. I find this odd because it just seems strange to me to have a method which imports a library but does not finish adding it to search, but we can make this method very explicitly named and documented - perhaps its a parameter added to an overload of LoadNodeLibrary to control adding to search. ie LoadNodeLibrary(Assembly assem, addToSearch = true)

3. whats in this PR currently - overriding equals and getHashcode - so that when the zt packages are added again to the search we end up just resetting the search element tags - but don't add a new element - it's some wasted cycles per zt function imported per package.

In any case we can leave these overrides in NodeSearchModel if the team thinks this is the correct behavior - thats my opinion.

update2:

went with solution 2. Removed equality overrides as we would need to add them for each class and carefully test the assumptions each class makes. For now this PR restores the old behavior of the API for extensions authors and keeps the new behavior for package manager using an internal method.

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.

Reviewers

@reddyashish @aparajit-pratap

FYIs

@jhauswirth

@mjkkirschner mjkkirschner added this to the 2.5.0 milestone Dec 3, 2019
@mjkkirschner mjkkirschner added PTAL Please Take A Look 👀 developer experience more high-level issues that are more specific to individuals actively developing on Dynamo. API labels Dec 3, 2019
@mjkkirschner
Copy link
Member Author

self serve is running now.

review comments
@mjkkirschner mjkkirschner added the DNM Do not merge. For PRs. label Dec 3, 2019
do not add duplicate search entires
@mjkkirschner
Copy link
Member Author

@QilongTang @reddyashish @aparajit-pratap - working with @aparajit-pratap we found that the nodeSearchModel did not override equals and gethashcode even though they are used as keys for the searchModel dictionary -

after implementing this keys are no longer duplicated when importing the library, even if the library is already imported. That seems like a good thing.

I would like to make the equality and hashcode checks more unique though, taking into account parameters, category etc just incase a node only differs by parameters or there is an overload - for zero touch that would usually be taken care of by the creationName containing the parameter names, but since this is the base class we need to consider all node search types.

@mjkkirschner
Copy link
Member Author

There are some failing tests with this change -

Errors and Failures:
1) Test Failure : Dynamo.Tests.SearchModelTests.CanRefactorCustomNodeWhilePreservingDuplicates
     Expected: 2
  But was:  1

at Dynamo.Tests.SearchModelTests.CanRefactorCustomNodeWhilePreservingDuplicates()

2) Test Failure : ViewExtensionLibraryTests.LibraryResourceProviderTests.LibraryDataUpdatedEventRaised
     Expected: 6
  But was:  3

at ViewExtensionLibraryTests.LibraryResourceProviderTests.LibraryDataUpdatedEventRaised() in E:\Builds\mjkkirschner_Dynamo\loadNodeLibraryRegression\Dynamo\test\ViewExtensionLibraryTests\LibraryResourceProviderTests.cs:line 414

looking into them.

… guid as seperate entries

add API test
improve equality and hashcode
@aparajit-pratap
Copy link
Contributor

aparajit-pratap commented Dec 4, 2019

  1. to remove the additional call in the packageLoader which re-raises the LibraryLoaded events - I believe @aparajit-pratap added this to finish importing all libraries into search only after all packages were loaded for a small speedup benefit, but it seems this may be the root of some of our issues. What do you think about removing this?

@mjkkirschner I'm not sure what you mean by "removing this". We have to finish importing into VM and adding to search after all packages are loaded, don't we? Or are you suggesting we revert to the old inefficient way of doing things again and again for each package?

@aparajit-pratap
Copy link
Contributor

I would like to make the equality and hashcode checks more unique though, taking into account parameters, category etc just incase a node only differs by parameters or there is an overload - for zero touch that would usually be taken care of by the creationName containing the parameter names, but since this is the base class we need to consider all node search types.

Can you give an example? Not sure, if I understand.

@mjkkirschner
Copy link
Member Author

@mjkkirschner I'm not sure what you mean by "removing this". We have to finish importing into VM and adding to search after all packages are loaded, don't we? Or are you suggesting we revert to the old inefficient way of doing things again and again for each package?

yes - my understanding is that by reverting to importLibrary in this PR we've already reverted back to the inefficient way of doing this - now we're wasting even more time by doing both - once for each package, and then again for all of them at the end, which is why my PR broke your test.

@mjkkirschner
Copy link
Member Author

Can you give an example? Not sure, if I understand.

I've already done this in the current PR - I was just worried about types which might somehow have the same name, but different parameters, I think this is unlikely but parameters is now added to the equality and hashcode check.

@aparajit-pratap
Copy link
Contributor

I've already done this in the current PR - I was just worried about types which might somehow have the same name, but different parameters, I think this is unlikely but parameters is now added to the equality and hashcode check.

One example of this is:
image
So it's good to check for parameters as well.

@aparajit-pratap
Copy link
Contributor

yes - my understanding is that by reverting to importLibrary in this PR we've already reverted back to the inefficient way of doing this - now we're wasting even more time by doing both - once for each package, and then again for all of them at the end, which is why my PR broke your test.

Hmm, let's discuss it again tomorrow.

use this to revert to old behavior for API users while keeping package manager behavior unchanged
update tests to use new method
@mjkkirschner mjkkirschner removed the DNM Do not merge. For PRs. label Dec 4, 2019
/// <param name="suppressZeroTouchLibraryLoad">If True, zero touch types will not be added to search.
/// This is used by packageManager extension to defer adding ZT libraries to search until all libraries are loaded.
/// </param>
internal void LoadNodeLibrary(Assembly assem, bool suppressZeroTouchLibraryLoad)
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor, but can we make the second parameter to this method a default argument set to true just coz it's called in a number of places internally with true?

/// </summary>
/// <param name="assem">The assembly to load which contains the types to import.</param>
/// <param name="suppressZeroTouchLibraryLoad">If True, zero touch types will not be added to search.
/// This is used by packageManager extension to defer adding ZT libraries to search until all libraries are loaded.
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the code comments 👍

Copy link
Contributor

@QilongTang QilongTang left a comment

Choose a reason for hiding this comment

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

LGTM with a few comments

@@ -24,14 +24,28 @@ internal ExtensionLibraryLoader(DynamoModel model)
}

/// <summary>
/// Loads the node library.
/// Loads a zZeroTouch or NodeModel based node into the VM and search.
Copy link
Contributor

Choose a reason for hiding this comment

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

typo ZeroTouch

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you remind me where is this used in this file?

@reddyashish
Copy link
Contributor

Looks good to me.

Copy link
Contributor

@reddyashish reddyashish left a comment

Choose a reason for hiding this comment

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

public void ExtensionLoader_LoadNodeLibraryAddsZTNodesToSearch()
{
var assemPath = Path.Combine(testpkgPath, "Dynamo Samples", "bin", "SampleLibraryZeroTouch.dll");
var assembly = Assembly.LoadFrom(assemPath);
Copy link
Member Author

Choose a reason for hiding this comment

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

@QilongTang reflection is used to load this assembly.

@mjkkirschner mjkkirschner merged commit 0605400 into DynamoDS:master Dec 5, 2019
mjkkirschner added a commit to mjkkirschner/Dynamo that referenced this pull request Dec 5, 2019
* raise event when importing zt node via LoadNodeLibrary method to restore behavior

* Update DynamoModel.cs

review comments

* test passes with this change-
do not add duplicate search entires

* update behavior of custom node test - no longer entries with the same guid as seperate entries
add API test
improve equality and hashcode

* add new method to extensionLibraryLoader
use this to revert to old behavior for API users while keeping package manager behavior unchanged
update tests to use new method

* review comments

(cherry picked from commit 0605400)
mjkkirschner added a commit that referenced this pull request Dec 5, 2019
* raise event when importing zt node via LoadNodeLibrary method to restore behavior

* Update DynamoModel.cs

review comments

* test passes with this change-
do not add duplicate search entires

* update behavior of custom node test - no longer entries with the same guid as seperate entries
add API test
improve equality and hashcode

* add new method to extensionLibraryLoader
use this to revert to old behavior for API users while keeping package manager behavior unchanged
update tests to use new method

* review comments

(cherry picked from commit 0605400)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API developer experience more high-level issues that are more specific to individuals actively developing on Dynamo. PTAL Please Take A Look 👀
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants