Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0c5435a
stream files
dimven-adsk Jun 2, 2025
c14b06f
bugfix
dimven-adsk Jun 2, 2025
7432de4
Merge branch 'master' of github.com:DynamoDS/Dynamo into reope/perfor…
aparajit-pratap Jun 6, 2025
b62daf7
review comments
aparajit-pratap Jun 6, 2025
2eea75b
Update src/DynamoCore/Core/CustomNodeManager.cs
aparajit-pratap Jun 6, 2025
5e483bc
merge customnodeinfo caching from Craig and resolve merge conflicts
saintentropy Jun 4, 2025
0512508
make property public for Json deserialization
aparajit-pratap Jun 9, 2025
5506260
fix
aparajit-pratap Jun 10, 2025
0568721
fix
aparajit-pratap Jun 10, 2025
dc24710
fix
aparajit-pratap Jun 10, 2025
2e46edf
cleanup of extraneous code
aparajit-pratap Jun 11, 2025
e17d0ad
restore code but commented out with TODO
aparajit-pratap Jun 11, 2025
6652d18
revert one change
aparajit-pratap Jun 12, 2025
03b6ff8
cleanup
aparajit-pratap Jun 17, 2025
4204912
refactor initialize customnode manager
aparajit-pratap Jun 27, 2025
2ecf48e
Update src/DynamoCore/Core/CustomNodeDefinition.cs
aparajit-pratap Jun 27, 2025
d494741
invalidate cache - attempt 1
aparajit-pratap Jun 30, 2025
c549583
invalidate cache - attempt 2
aparajit-pratap Jul 1, 2025
5056fd3
Merge branch 'customnode-loading-perf' of github.com:aparajit-pratap/…
aparajit-pratap Jul 1, 2025
116757d
Merge branch 'master' of github.com:DynamoDS/Dynamo into customnode-l…
aparajit-pratap Jul 1, 2025
1fafedf
Update src/DynamoCore/Core/CustomNodeManager.cs
aparajit-pratap Jul 1, 2025
b85a95f
Merge branch 'customnode-loading-perf' of github.com:aparajit-pratap/…
aparajit-pratap Jul 1, 2025
6d38b71
make custom node cache thread safe
aparajit-pratap Jul 2, 2025
6f6830a
Update src/DynamoCore/Core/CustomNodeManager.cs
aparajit-pratap Jul 2, 2025
36477f6
add error message as resource string
aparajit-pratap Jul 2, 2025
6294e13
refactor customnodemanager
aparajit-pratap Jul 3, 2025
09cfc7e
cleanup
aparajit-pratap Jul 6, 2025
4bfebbb
final fixes
aparajit-pratap Jul 7, 2025
5fdafb0
Merge branch 'master' of github.com:DynamoDS/Dynamo into customnode-l…
aparajit-pratap Jul 7, 2025
ad11e1a
temporarily mark test as failure to try unblocking build pipeline
aparajit-pratap Jul 7, 2025
d121a96
resolve merge conflicts
aparajit-pratap Jul 8, 2025
1e6f5d9
sort usings
aparajit-pratap Jul 9, 2025
c523c95
resolve conflicts
aparajit-pratap Jul 9, 2025
927dfda
use custom node cache only in sandbox
aparajit-pratap Jul 10, 2025
4114193
final cleanup
aparajit-pratap Jul 10, 2025
e53911a
update public api lists
aparajit-pratap Jul 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions src/DynamoApplications/StartupUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ private static DynamoModel PrepareModel(
bool cliMode = true,
string userDataFolder = "",
string commonDataFolder = "",
bool serviceMode = false)
bool serviceMode = false,
bool useCustomNodeCache = false)
{
var normalizedCLILocale = string.IsNullOrEmpty(cliLocale) ? null : cliLocale;
IPathResolver pathResolver = CreatePathResolver(false, string.Empty, string.Empty, string.Empty);
Expand All @@ -214,7 +215,8 @@ private static DynamoModel PrepareModel(
noNetworkMode: noNetworkMode,
info: analyticsInfo,
isServiceMode: serviceMode,
cliLocale: normalizedCLILocale
cliLocale: normalizedCLILocale,
useCustomNodeCache
);
model.IsASMLoaded = isASMloaded;
return model;
Expand Down Expand Up @@ -285,7 +287,8 @@ public static DynamoModel MakeModel(bool CLImode, string asmPath = "", string ho
/// <param name="asmPath">Path to directory containing geometry library binaries</param>
/// <param name="info">Host analytics info specifying Dynamo launching host related information.</param>
/// <returns></returns>
public static DynamoModel MakeModel(bool CLImode, string CLIlocale, bool noNetworkMode, string asmPath = "", HostAnalyticsInfo info = new HostAnalyticsInfo())
public static DynamoModel MakeModel(bool CLImode, string CLIlocale, bool noNetworkMode, string asmPath = "",
HostAnalyticsInfo info = new HostAnalyticsInfo())
{
var model = PrepareModel(
cliLocale: CLIlocale,
Expand All @@ -296,6 +299,22 @@ public static DynamoModel MakeModel(bool CLImode, string asmPath = "", string ho
return model;
}

internal static DynamoModel MakeModel(bool CLImode, string CLIlocale, bool noNetworkMode, bool useCustomNodeCache,
string asmPath = "", HostAnalyticsInfo info = new HostAnalyticsInfo())
{
var model = PrepareModel(
cliLocale: CLIlocale,
asmPath: asmPath,
noNetworkMode: noNetworkMode,
analyticsInfo: info,
cliMode: CLImode,
userDataFolder: "",
commonDataFolder: "",
serviceMode: false,
useCustomNodeCache);
return model;
}

/// <summary>
/// It returns an IPathResolver based on the mode and some locations
/// </summary>
Expand Down Expand Up @@ -371,7 +390,8 @@ private static DynamoModel StartDynamoWithDefaultConfig(bool CLImode,
bool noNetworkMode,
HostAnalyticsInfo info = new HostAnalyticsInfo(),
bool isServiceMode = false,
string cliLocale = null)
string cliLocale = null,
bool useCustomNodeCache = false)
{

var config = new DynamoModel.DefaultStartConfiguration
Expand All @@ -387,6 +407,7 @@ private static DynamoModel StartDynamoWithDefaultConfig(bool CLImode,
Preferences = PreferenceSettings.Instance,
NoNetworkMode = noNetworkMode,
CLILocale = cliLocale,
UseCustomNodeCache = useCustomNodeCache,
//Breaks all Lucene calls. TI enable this would require a lot of refactoring around Lucene usage in Dynamo.
//IsHeadless = CLImode
};
Expand Down
78 changes: 76 additions & 2 deletions src/DynamoCore/Core/CustomNodeDefinition.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Dynamo.Engine;
using Dynamo.Engine.CodeGeneration;
using Dynamo.Graph.Nodes;
using Dynamo.Graph.Nodes.CustomNodes;
using Dynamo.Graph.Workspaces;
using Dynamo.Library;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ProtoCore;
using ProtoCore.AST.AssociativeAST;

Expand Down Expand Up @@ -302,6 +305,9 @@ public CustomNodeInfo(Guid functionId, string name, string category, string desc
if (String.IsNullOrWhiteSpace(Category))
Category = Dynamo.Properties.Resources.DefaultCustomNodeCategory;
}

[JsonConstructor] public CustomNodeInfo() { }

Copilot AI Jul 1, 2025

Copy link

Choose a reason for hiding this comment

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

[nitpick] Applying JsonConstructor to the parameterless constructor may override default constructor selection and lead to incomplete initialization. Remove the attribute or apply it to a fully-initializing constructor.

Suggested change
[JsonConstructor] public CustomNodeInfo() { }
public CustomNodeInfo() { }

Copilot uses AI. Check for mistakes.

/// <summary>
/// Returns custom node unique ID
/// </summary>
Expand All @@ -315,7 +321,7 @@ public CustomNodeInfo(Guid functionId, string name, string category, string desc
/// <summary>
/// Returns custom node category
/// </summary>
public string Category { get; set; }
public string Category { get; set; } = string.Empty;

/// <summary>
/// Returns custom node description
Expand All @@ -337,13 +343,81 @@ public CustomNodeInfo(Guid functionId, string name, string category, string desc
/// Indicates if custom node is part of the library search.
/// If true, then custom node is part of library search.
/// </summary>
public bool IsVisibleInDynamoLibrary { get; private set; }
public bool IsVisibleInDynamoLibrary { get; set; }
Comment thread
aparajit-pratap marked this conversation as resolved.

/// <summary>
/// Only valid if IsPackageMember is true.
/// Can be used to identify which package
/// requested this CustomNode to load.
/// </summary>
public PackageInfo PackageInfo { get; internal set; }


private static readonly string[] topLevelJsonKeys = { "Uuid", "Category", "Description", "Name" };
private static readonly Dictionary<string, object> propertyLookup = new Dictionary<string, object>();
private static object isVisibleInDynamoLibraryProp = null;
private static DefaultJsonNameTable propertyTable = null;

internal static bool GetFromJsonDocument(string path, out CustomNodeInfo info, out Exception ex)
{
if (propertyTable == null)
{
propertyTable = new DefaultJsonNameTable();
foreach (var pn in topLevelJsonKeys)
{
propertyLookup[pn] = propertyTable.Add(pn);
}
isVisibleInDynamoLibraryProp = propertyTable.Add(nameof(IsVisibleInDynamoLibrary));
Comment thread
aparajit-pratap marked this conversation as resolved.
Comment thread
aparajit-pratap marked this conversation as resolved.
Comment thread
aparajit-pratap marked this conversation as resolved.
}

Comment thread
aparajit-pratap marked this conversation as resolved.
try
{
var data = new JObject();
// JsonTextRead will automatically dispose of the stream reader
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
using (var jr = new JsonTextReader(new StreamReader(fs)) { PropertyNameTable = propertyTable })
{
while (jr.Read())
{
if (data.Count == topLevelJsonKeys.Length + 1)
{
break; // we have all of the
}

if (jr.TokenType == JsonToken.PropertyName)
{
if (jr.Depth == 1)
{
foreach (var prop in propertyLookup)
{
if (jr.Value == prop.Value)
{
data[prop.Key] = jr.ReadAsString() ?? "";
break;
}
}
}
else if (jr.Value == isVisibleInDynamoLibraryProp)
{
data[nameof(IsVisibleInDynamoLibrary)] = jr.ReadAsBoolean();
}
}
}
}

ex = null;
data["FunctionId"] = data.GetValue("Uuid");
data["Path"] = path;

info = data.ToObject<CustomNodeInfo>();
return true;
}
catch (Exception e)
{
ex = e;
info = null;
return false;
}
}
}
}
Loading
Loading