From 6312cda3e3b9454014db8f7b91e14ab0159f2dc7 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Fri, 6 Jan 2023 00:23:47 +0800 Subject: [PATCH 01/19] Service Mode Initial commit --- src/DynamoApplications/StartupUtils.cs | 44 +++++++-- src/DynamoCLI/Program.cs | 12 +-- src/DynamoCore/Models/DynamoModel.cs | 130 +++++++++++++------------ src/DynamoWPFCLI/Program.cs | 11 ++- 4 files changed, 117 insertions(+), 80 deletions(-) diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs index 04f99bbc003..254b6103efe 100644 --- a/src/DynamoApplications/StartupUtils.cs +++ b/src/DynamoApplications/StartupUtils.cs @@ -184,6 +184,7 @@ public static CommandLineArguments Parse(string[] args) bool keepAlive = false; bool showHelp = false; bool noConsole = false; + bool serviceMode = false; string userDataFolder = string.Empty; string commonDataFolder = string.Empty; @@ -220,7 +221,9 @@ public static CommandLineArguments Parse(string[] args) .Add("si=|SI=|sessionId", "Identify Dynamo host analytics session id", si => sessionId = si) .Add("pi=|PI=|parentId", "Identify Dynamo host analytics parent id", pi => parentId = pi) .Add("da|DA|disableAnalytics", "Disables analytics in Dynamo for the process liftime", da => disableAnalytics = da != null) - .Add("cr=|CR=|cerLocation", "Specify the crash error report tool location on disk ", cr => cerLocation = cr); + .Add("cr=|CR=|cerLocation", "Specify the crash error report tool location on disk ", cr => cerLocation = cr) + .Add("s|S|service mode", "Service mode, by pass certain Dynamo launch steps for maximum startup performance", s => serviceMode = s != null); + optionsSet.Parse(args); if (showHelp) @@ -249,7 +252,8 @@ public static CommandLineArguments Parse(string[] args) CommonDataFolder = commonDataFolder, DisableAnalytics = disableAnalytics, AnalyticsInfo = new HostAnalyticsInfo() { HostName = hostname, ParentId = parentId, SessionId = sessionId }, - CERLocation = cerLocation + CERLocation = cerLocation, + ServiceMode = serviceMode }; #endif } @@ -279,6 +283,7 @@ private static void ShowHelp(OptionSet opSet) public bool DisableAnalytics { get; set; } public HostAnalyticsInfo AnalyticsInfo { get; set; } public string CERLocation { get; set; } + public bool ServiceMode { get; set; } } /// @@ -339,6 +344,23 @@ private static IUpdateManager InitializeUpdateManager() return model; } + /// + /// Use this overload to construct a DynamoModel in CLI context when the location of ASM to use is known, host analytics info is known and you want to set data paths. + /// + /// Path to directory containing geometry library binaries + /// Path to be used by PathResolver for UserDataFolder + /// Path to be used by PathResolver for CommonDataFolder + /// + public static DynamoModel MakeCLIModel(string asmPath, string userDataFolder, string commonDataFolder, HostAnalyticsInfo info = new HostAnalyticsInfo(), bool isServiceMode = false) + { + // Preload ASM and display corresponding message on splash screen + DynamoModel.OnRequestUpdateLoadBarStatus(new SplashScreenLoadEventArgs(Resources.SplashScreenPreLoadingAsm, 10)); + var isASMloaded = PreloadASM(asmPath, out string geometryFactoryPath, out string preloaderLocation); + var model = StartDynamoWithDefaultConfig(true, userDataFolder, commonDataFolder, geometryFactoryPath, preloaderLocation, info, isServiceMode); + model.IsASMLoaded = isASMloaded; + return model; + } + /// /// Use this overload to construct a DynamoModel when the location of ASM to use is known and host name is known. /// @@ -455,19 +477,23 @@ private static DynamoModel StartDynamoWithDefaultConfig(bool CLImode, string commonDataFolder, string geometryFactoryPath, string preloaderLocation, - HostAnalyticsInfo info = new HostAnalyticsInfo()) + HostAnalyticsInfo info = new HostAnalyticsInfo(), + bool isServiceMode = false) { - var config = new DynamoModel.DefaultStartConfiguration() + var config = new DynamoModel.DefaultStartConfiguration { GeometryFactoryPath = geometryFactoryPath, ProcessMode = CLImode ? TaskProcessMode.Synchronous : TaskProcessMode.Asynchronous, HostAnalyticsInfo = info, - CLIMode = CLImode + CLIMode = CLImode, + AuthProvider = CLImode ? null : new Core.IDSDKManager(), + UpdateManager = CLImode ? null : OSHelper.IsWindows() ? InitializeUpdateManager() : null, + StartInTestMode = CLImode, + PathResolver = CLImode ? new CLIPathResolver(preloaderLocation, userDataFolder, commonDataFolder) as IPathResolver : new SandboxPathResolver(preloaderLocation) as IPathResolver, + // Update Default start config to include IsServiceMode so DynamoModel can initialize with that flag. If set later, it might be too late. + // TBD, do we want to reuse the old Context property? + Context = "Service" }; - config.AuthProvider = CLImode ? null : new Core.IDSDKManager(); - config.UpdateManager = CLImode ? null : OSHelper.IsWindows() ? InitializeUpdateManager() : null; - config.StartInTestMode = CLImode; - config.PathResolver = CLImode ? new CLIPathResolver(preloaderLocation, userDataFolder, commonDataFolder) as IPathResolver : new SandboxPathResolver(preloaderLocation) as IPathResolver; var model = DynamoModel.Start(config); return model; diff --git a/src/DynamoCLI/Program.cs b/src/DynamoCLI/Program.cs index bc916f338d3..76df1dd6e55 100644 --- a/src/DynamoCLI/Program.cs +++ b/src/DynamoCLI/Program.cs @@ -1,7 +1,5 @@ using System; -using System.IO; using System.Linq; -using System.Reflection; using System.Threading; using Dynamo.Applications; using Dynamo.Models; @@ -29,9 +27,10 @@ static internal void Main(string[] args) if (cmdLineArgs.KeepAlive) { - var thread = new Thread(() => RunKeepAlive(cmdLineArgs)); - - thread.Name = "DynamoModelKeepAlive"; + var thread = new Thread(() => RunKeepAlive(cmdLineArgs)) + { + Name = "DynamoModelKeepAlive" + }; thread.Start(); if (!useConsole) @@ -104,7 +103,8 @@ private static DynamoModel StartupDynamo(StartupUtils.CommandLineArguments cmdLi model = Dynamo.Applications.StartupUtils.MakeCLIModel(String.IsNullOrEmpty(cmdLineArgs.ASMPath) ? string.Empty : cmdLineArgs.ASMPath, cmdLineArgs.UserDataFolder, cmdLineArgs.CommonDataFolder, - cmdLineArgs.AnalyticsInfo); + cmdLineArgs.AnalyticsInfo, + cmdLineArgs.ServiceMode); if (!string.IsNullOrEmpty(cmdLineArgs.CERLocation)) { diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index a927bb3ceb1..ec8eb65cea4 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -637,15 +637,20 @@ protected DynamoModel(IStartConfiguration config) pathManager.EnsureDirectoryExistence(exceptions); Context = config.Context; + // This condition is TBD + var isServiceMode = config.Context.Equals("Service"); IsTestMode = config.StartInTestMode; IsHeadless = config.IsHeadless; DebugSettings = new DebugSettings(); Logger = new DynamoLogger(DebugSettings, pathManager.LogDirectory, IsTestMode, CLIMode); - foreach (var exception in exceptions) + if (!isServiceMode) { - Logger.Log(exception); // Log all exceptions. + foreach (var exception in exceptions) + { + Logger.Log(exception); // Log all exceptions. + } } MigrationManager = new MigrationManager(DisplayFutureFileMessage, DisplayObsoleteFileMessage); @@ -699,83 +704,88 @@ protected DynamoModel(IStartConfiguration config) // Do nothing for now } - // If user skipped analytics from assembly config, do not try to launch the analytics client - // or the feature flags client. - if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics) + // Bypass analytics initialization in service mode + if (!isServiceMode) { - // Start the Analytics service only when a session is not present. - // In an integrator host, as splash screen can be closed without shutting down the ViewModel, the analytics service is not stopped. - // So we don't want to start it when splash screen or dynamo window is launched again. - if (Analytics.client == null) + // If user skipped analytics from assembly config, do not try to launch the analytics client + // or the feature flags client. + if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics) { - AnalyticsService.Start(this, IsHeadless, IsTestMode); - } - else if (Analytics.client is DynamoAnalyticsClient dac) - { - if (dac.Session == null) + // Start the Analytics service only when a session is not present. + // In an integrator host, as splash screen can be closed without shutting down the ViewModel, the analytics service is not stopped. + // So we don't want to start it when splash screen or dynamo window is launched again. + if (Analytics.client == null) { AnalyticsService.Start(this, IsHeadless, IsTestMode); } - } - - //run process startup/reading on another thread so we don't block dynamo startup. - //if we end up needing to control aspects of dynamo model or view startup that we can't make - //event based/async then just run this on main thread - ie get rid of the Task.Run() - var mainThreadSyncContext = new SynchronizationContext(); - Task.Run(() => - { - try + else if (Analytics.client is DynamoAnalyticsClient dac) { - //this will kill the CLI process after cacheing the flags in Dynamo process. - using (FeatureFlags = - new DynamoUtilities.DynamoFeatureFlagsManager( - AnalyticsService.GetUserIDForSession(), - mainThreadSyncContext, - IsTestMode)) + if (dac.Session == null) { - FeatureFlags.MessageLogged += LogMessageWrapper; - //this will block task thread as it waits for data from feature flags process. - FeatureFlags.CacheAllFlags(); + AnalyticsService.Start(this, IsHeadless, IsTestMode); } } - catch (Exception e) { Logger.LogError($"could not start feature flags manager {e}"); }; - }); - //TODO just a test of feature flag event, safe to remove at any time. - DynamoUtilities.DynamoFeatureFlagsManager.FlagsRetrieved += CheckFeatureFlagTest; + //run process startup/reading on another thread so we don't block dynamo startup. + //if we end up needing to control aspects of dynamo model or view startup that we can't make + //event based/async then just run this on main thread - ie get rid of the Task.Run() + var mainThreadSyncContext = new SynchronizationContext(); + Task.Run(() => + { + try + { + //this will kill the CLI process after cacheing the flags in Dynamo process. + using (FeatureFlags = + new DynamoUtilities.DynamoFeatureFlagsManager( + AnalyticsService.GetUserIDForSession(), + mainThreadSyncContext, + IsTestMode)) + { + FeatureFlags.MessageLogged += LogMessageWrapper; + //this will block task thread as it waits for data from feature flags process. + FeatureFlags.CacheAllFlags(); + } + } + catch (Exception e) { Logger.LogError($"could not start feature flags manager {e}"); }; + }); - } + //TODO just a test of feature flag event, safe to remove at any time. + DynamoUtilities.DynamoFeatureFlagsManager.FlagsRetrieved += CheckFeatureFlagTest; - if (!IsTestMode && PreferenceSettings.IsFirstRun) - { - DynamoMigratorBase migrator = null; + } - try + // TBD: Do we need setting migrator for service mode? If we config the docker correctly, this can be skipped I guess + if (!IsTestMode && PreferenceSettings.IsFirstRun) { - var dynamoLookup = config.UpdateManager != null && config.UpdateManager.Configuration != null - ? config.UpdateManager.Configuration.DynamoLookUp : null; + DynamoMigratorBase migrator = null; - migrator = DynamoMigratorBase.MigrateBetweenDynamoVersions(pathManager, dynamoLookup); - } - catch (Exception e) - { - Logger.Log(e.Message); - } + try + { + var dynamoLookup = config.UpdateManager != null && config.UpdateManager.Configuration != null + ? config.UpdateManager.Configuration.DynamoLookUp : null; - if (migrator != null) - { - var isFirstRun = PreferenceSettings.IsFirstRun; - PreferenceSettings = migrator.PreferenceSettings; + migrator = DynamoMigratorBase.MigrateBetweenDynamoVersions(pathManager, dynamoLookup); + } + catch (Exception e) + { + Logger.Log(e.Message); + } + + if (migrator != null) + { + var isFirstRun = PreferenceSettings.IsFirstRun; + PreferenceSettings = migrator.PreferenceSettings; - // Preserve the preference settings for IsFirstRun as this needs to be set - // only by UsageReportingManager - PreferenceSettings.IsFirstRun = isFirstRun; + // Preserve the preference settings for IsFirstRun as this needs to be set + // only by UsageReportingManager + PreferenceSettings.IsFirstRun = isFirstRun; + } } - } - if (PreferenceSettings.IsFirstRun && !IsTestMode) - { - PreferenceSettings.AddDefaultTrustedLocations(); + if (PreferenceSettings.IsFirstRun && !IsTestMode) + { + PreferenceSettings.AddDefaultTrustedLocations(); + } } InitializePreferences(PreferenceSettings); diff --git a/src/DynamoWPFCLI/Program.cs b/src/DynamoWPFCLI/Program.cs index 37f962239b2..f027de445b4 100644 --- a/src/DynamoWPFCLI/Program.cs +++ b/src/DynamoWPFCLI/Program.cs @@ -4,7 +4,6 @@ using Dynamo.Applications; using Dynamo.Models; using Dynamo.ViewModels; -using Dynamo.Wpf.Utilities; using Dynamo.Wpf.ViewModels.Watch3D; using static System.Windows.Threading.Dispatcher; @@ -31,9 +30,10 @@ internal static void Main(string[] args) if (cmdLineArgs.KeepAlive) { - var thread = new Thread(() => RunKeepAlive(cmdLineArgs)); - - thread.Name = "DynamoModelKeepAlive"; + var thread = new Thread(() => RunKeepAlive(cmdLineArgs)) + { + Name = "DynamoModelKeepAlive" + }; thread.SetApartmentState(ApartmentState.STA); thread.Start(); if (!useConsole) @@ -86,7 +86,8 @@ private static DynamoViewModel StartupDaynamo(StartupUtils.CommandLineArguments model = Dynamo.Applications.StartupUtils.MakeCLIModel(String.IsNullOrEmpty(cmdLineArgs.ASMPath) ? string.Empty : cmdLineArgs.ASMPath, cmdLineArgs.UserDataFolder, cmdLineArgs.CommonDataFolder, - cmdLineArgs.AnalyticsInfo); + cmdLineArgs.AnalyticsInfo, + cmdLineArgs.ServiceMode); if (!string.IsNullOrEmpty(cmdLineArgs.CERLocation)) { From 1447c2c2837d67550df3d89e7261d7b982972777 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Fri, 6 Jan 2023 00:32:13 +0800 Subject: [PATCH 02/19] clean up --- src/DynamoApplications/StartupUtils.cs | 2 +- src/DynamoCore/Models/DynamoModel.cs | 123 ++++++++++++------------- 2 files changed, 61 insertions(+), 64 deletions(-) diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs index 254b6103efe..5fa659175a4 100644 --- a/src/DynamoApplications/StartupUtils.cs +++ b/src/DynamoApplications/StartupUtils.cs @@ -222,7 +222,7 @@ public static CommandLineArguments Parse(string[] args) .Add("pi=|PI=|parentId", "Identify Dynamo host analytics parent id", pi => parentId = pi) .Add("da|DA|disableAnalytics", "Disables analytics in Dynamo for the process liftime", da => disableAnalytics = da != null) .Add("cr=|CR=|cerLocation", "Specify the crash error report tool location on disk ", cr => cerLocation = cr) - .Add("s|S|service mode", "Service mode, by pass certain Dynamo launch steps for maximum startup performance", s => serviceMode = s != null); + .Add("s|S|service mode", "Service mode, bypass certain Dynamo launch steps for maximum startup performance", s => serviceMode = s != null); optionsSet.Parse(args); diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index ec8eb65cea4..6720ba32a3e 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -704,90 +704,87 @@ protected DynamoModel(IStartConfiguration config) // Do nothing for now } - // Bypass analytics initialization in service mode - if (!isServiceMode) + + // If user skipped analytics from assembly config, do not try to launch the analytics client + // or the feature flags client. + if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics && !isServiceMode) { - // If user skipped analytics from assembly config, do not try to launch the analytics client - // or the feature flags client. - if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics) + // Start the Analytics service only when a session is not present. + // In an integrator host, as splash screen can be closed without shutting down the ViewModel, the analytics service is not stopped. + // So we don't want to start it when splash screen or dynamo window is launched again. + if (Analytics.client == null) { - // Start the Analytics service only when a session is not present. - // In an integrator host, as splash screen can be closed without shutting down the ViewModel, the analytics service is not stopped. - // So we don't want to start it when splash screen or dynamo window is launched again. - if (Analytics.client == null) + AnalyticsService.Start(this, IsHeadless, IsTestMode); + } + else if (Analytics.client is DynamoAnalyticsClient dac) + { + if (dac.Session == null) { AnalyticsService.Start(this, IsHeadless, IsTestMode); } - else if (Analytics.client is DynamoAnalyticsClient dac) + } + + //run process startup/reading on another thread so we don't block dynamo startup. + //if we end up needing to control aspects of dynamo model or view startup that we can't make + //event based/async then just run this on main thread - ie get rid of the Task.Run() + var mainThreadSyncContext = new SynchronizationContext(); + Task.Run(() => + { + try { - if (dac.Session == null) + //this will kill the CLI process after cacheing the flags in Dynamo process. + using (FeatureFlags = + new DynamoUtilities.DynamoFeatureFlagsManager( + AnalyticsService.GetUserIDForSession(), + mainThreadSyncContext, + IsTestMode)) { - AnalyticsService.Start(this, IsHeadless, IsTestMode); + FeatureFlags.MessageLogged += LogMessageWrapper; + //this will block task thread as it waits for data from feature flags process. + FeatureFlags.CacheAllFlags(); } } + catch (Exception e) { Logger.LogError($"could not start feature flags manager {e}"); }; + }); - //run process startup/reading on another thread so we don't block dynamo startup. - //if we end up needing to control aspects of dynamo model or view startup that we can't make - //event based/async then just run this on main thread - ie get rid of the Task.Run() - var mainThreadSyncContext = new SynchronizationContext(); - Task.Run(() => - { - try - { - //this will kill the CLI process after cacheing the flags in Dynamo process. - using (FeatureFlags = - new DynamoUtilities.DynamoFeatureFlagsManager( - AnalyticsService.GetUserIDForSession(), - mainThreadSyncContext, - IsTestMode)) - { - FeatureFlags.MessageLogged += LogMessageWrapper; - //this will block task thread as it waits for data from feature flags process. - FeatureFlags.CacheAllFlags(); - } - } - catch (Exception e) { Logger.LogError($"could not start feature flags manager {e}"); }; - }); + //TODO just a test of feature flag event, safe to remove at any time. + DynamoUtilities.DynamoFeatureFlagsManager.FlagsRetrieved += CheckFeatureFlagTest; - //TODO just a test of feature flag event, safe to remove at any time. - DynamoUtilities.DynamoFeatureFlagsManager.FlagsRetrieved += CheckFeatureFlagTest; + } - } + // TBD: Do we need setting migrator for service mode? If we config the docker correctly, this can be skipped I guess + if (!IsTestMode && PreferenceSettings.IsFirstRun && !isServiceMode) + { + DynamoMigratorBase migrator = null; - // TBD: Do we need setting migrator for service mode? If we config the docker correctly, this can be skipped I guess - if (!IsTestMode && PreferenceSettings.IsFirstRun) + try { - DynamoMigratorBase migrator = null; + var dynamoLookup = config.UpdateManager != null && config.UpdateManager.Configuration != null + ? config.UpdateManager.Configuration.DynamoLookUp : null; - try - { - var dynamoLookup = config.UpdateManager != null && config.UpdateManager.Configuration != null - ? config.UpdateManager.Configuration.DynamoLookUp : null; - - migrator = DynamoMigratorBase.MigrateBetweenDynamoVersions(pathManager, dynamoLookup); - } - catch (Exception e) - { - Logger.Log(e.Message); - } - - if (migrator != null) - { - var isFirstRun = PreferenceSettings.IsFirstRun; - PreferenceSettings = migrator.PreferenceSettings; - - // Preserve the preference settings for IsFirstRun as this needs to be set - // only by UsageReportingManager - PreferenceSettings.IsFirstRun = isFirstRun; - } + migrator = DynamoMigratorBase.MigrateBetweenDynamoVersions(pathManager, dynamoLookup); + } + catch (Exception e) + { + Logger.Log(e.Message); } - if (PreferenceSettings.IsFirstRun && !IsTestMode) + if (migrator != null) { - PreferenceSettings.AddDefaultTrustedLocations(); + var isFirstRun = PreferenceSettings.IsFirstRun; + PreferenceSettings = migrator.PreferenceSettings; + + // Preserve the preference settings for IsFirstRun as this needs to be set + // only by UsageReportingManager + PreferenceSettings.IsFirstRun = isFirstRun; } } + if (PreferenceSettings.IsFirstRun && !IsTestMode && !isServiceMode) + { + PreferenceSettings.AddDefaultTrustedLocations(); + } + InitializePreferences(PreferenceSettings); // At this point, pathManager.PackageDirectories only has 1 element which is the directory From 2cb80a68e20edfade36b280b45c0658462413157 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Fri, 6 Jan 2023 22:39:01 +0800 Subject: [PATCH 03/19] Update --- src/DynamoCore/Models/DynamoModel.cs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 6720ba32a3e..a1b990305b2 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -752,7 +752,7 @@ protected DynamoModel(IStartConfiguration config) } - // TBD: Do we need setting migrator for service mode? If we config the docker correctly, this can be skipped I guess + // TBD: Do we need settings migrator for service mode? If we config the docker correctly, this could be skipped I think if (!IsTestMode && PreferenceSettings.IsFirstRun && !isServiceMode) { DynamoMigratorBase migrator = null; @@ -815,7 +815,7 @@ protected DynamoModel(IStartConfiguration config) // 4) Set from OOTB hard-coded default template // If a custom python template path doesn't already exists in the DynamoSettings.xml - if (string.IsNullOrEmpty(PreferenceSettings.PythonTemplateFilePath) || !File.Exists(PreferenceSettings.PythonTemplateFilePath)) + if (string.IsNullOrEmpty(PreferenceSettings.PythonTemplateFilePath) || !File.Exists(PreferenceSettings.PythonTemplateFilePath) && !isServiceMode) { // To supply a custom python template host integrators should supply a 'DefaultStartConfiguration' config file // or create a new struct that inherits from 'DefaultStartConfiguration' making sure to set the 'PythonTemplatePath' @@ -855,9 +855,12 @@ protected DynamoModel(IStartConfiguration config) pathManager.Preferences = PreferenceSettings; PreferenceSettings.RequestUserDataFolder += pathManager.GetUserDataFolder; - SearchModel = new NodeSearchModel(Logger); - SearchModel.ItemProduced += - node => ExecuteCommand(new CreateNodeCommand(node, 0, 0, true, true)); + //if (!isServiceMode) + { + SearchModel = new NodeSearchModel(Logger); + SearchModel.ItemProduced += + node => ExecuteCommand(new CreateNodeCommand(node, 0, 0, true, true)); + } NodeFactory = new NodeFactory(); NodeFactory.MessageLogged += LogMessage; @@ -1444,7 +1447,7 @@ private void InitializeIncludedNodes() NodeFactory.AddTypeFactoryAndLoader(outputData.Type); NodeFactory.AddAlsoKnownAs(outputData.Type, outputData.AlsoKnownAs); - SearchModel.Add(new CodeBlockNodeSearchElement(cbnData, LibraryServices)); + SearchModel?.Add(new CodeBlockNodeSearchElement(cbnData, LibraryServices)); var symbolSearchElement = new NodeModelSearchElement(symbolData) { @@ -1462,8 +1465,8 @@ private void InitializeIncludedNodes() outputSearchElement.IsVisibleInSearch = isVisible; }; - SearchModel.Add(symbolSearchElement); - SearchModel.Add(outputSearchElement); + SearchModel?.Add(symbolSearchElement); + SearchModel?.Add(outputSearchElement); } internal static bool IsDisabledPath(string packagesDirectory, IPreferences preferences) @@ -3115,7 +3118,7 @@ private void AddNodeTypeToSearch(TypeLoadData typeLoadData) return; } - SearchModel.Add(new NodeModelSearchElement(typeLoadData)); + SearchModel?.Add(new NodeModelSearchElement(typeLoadData)); } /// @@ -3162,7 +3165,7 @@ private void AddZeroTouchNodeToSearch(FunctionDescriptor functionDescriptor) { if (functionDescriptor.IsVisibleInLibrary) { - SearchModel.Add(new ZeroTouchSearchElement(functionDescriptor)); + SearchModel?.Add(new ZeroTouchSearchElement(functionDescriptor)); } } From bc3434d051f66452954a60d2e28bf3779888cef8 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Mon, 9 Jan 2023 23:42:48 +0800 Subject: [PATCH 04/19] Diable SearchModel in Service Mode --- src/DynamoCore/Models/DynamoModel.cs | 19 ++++--- .../ViewModels/Core/NodeViewModel.cs | 2 +- .../ViewModels/Core/WorkspaceViewModel.cs | 22 +++++---- .../Handlers/NodeItemDataProvider.cs | 4 +- .../LibraryViewController.cs | 49 ++++++++++--------- 5 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index a1b990305b2..83ded73f855 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -208,6 +208,11 @@ public string Version /// public HostAnalyticsInfo HostAnalyticsInfo { get; set; } + /// + /// Boolean indicating if Dynamo is running in service model, mostly leveraged by CLI or WPF CLI + /// + public bool IsServiceMode { get; set; } + /// /// UpdateManager to handle automatic upgrade to higher version. /// @@ -638,14 +643,14 @@ protected DynamoModel(IStartConfiguration config) Context = config.Context; // This condition is TBD - var isServiceMode = config.Context.Equals("Service"); + IsServiceMode = config.Context.Equals("Service"); IsTestMode = config.StartInTestMode; IsHeadless = config.IsHeadless; DebugSettings = new DebugSettings(); Logger = new DynamoLogger(DebugSettings, pathManager.LogDirectory, IsTestMode, CLIMode); - if (!isServiceMode) + if (!IsServiceMode) { foreach (var exception in exceptions) { @@ -707,7 +712,7 @@ protected DynamoModel(IStartConfiguration config) // If user skipped analytics from assembly config, do not try to launch the analytics client // or the feature flags client. - if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics && !isServiceMode) + if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics && !IsServiceMode) { // Start the Analytics service only when a session is not present. // In an integrator host, as splash screen can be closed without shutting down the ViewModel, the analytics service is not stopped. @@ -753,7 +758,7 @@ protected DynamoModel(IStartConfiguration config) } // TBD: Do we need settings migrator for service mode? If we config the docker correctly, this could be skipped I think - if (!IsTestMode && PreferenceSettings.IsFirstRun && !isServiceMode) + if (!IsTestMode && PreferenceSettings.IsFirstRun && !IsServiceMode) { DynamoMigratorBase migrator = null; @@ -780,7 +785,7 @@ protected DynamoModel(IStartConfiguration config) } } - if (PreferenceSettings.IsFirstRun && !IsTestMode && !isServiceMode) + if (PreferenceSettings.IsFirstRun && !IsTestMode && !IsServiceMode) { PreferenceSettings.AddDefaultTrustedLocations(); } @@ -815,7 +820,7 @@ protected DynamoModel(IStartConfiguration config) // 4) Set from OOTB hard-coded default template // If a custom python template path doesn't already exists in the DynamoSettings.xml - if (string.IsNullOrEmpty(PreferenceSettings.PythonTemplateFilePath) || !File.Exists(PreferenceSettings.PythonTemplateFilePath) && !isServiceMode) + if (string.IsNullOrEmpty(PreferenceSettings.PythonTemplateFilePath) || !File.Exists(PreferenceSettings.PythonTemplateFilePath) && !IsServiceMode) { // To supply a custom python template host integrators should supply a 'DefaultStartConfiguration' config file // or create a new struct that inherits from 'DefaultStartConfiguration' making sure to set the 'PythonTemplatePath' @@ -855,7 +860,7 @@ protected DynamoModel(IStartConfiguration config) pathManager.Preferences = PreferenceSettings; PreferenceSettings.RequestUserDataFolder += pathManager.GetUserDataFolder; - //if (!isServiceMode) + if (!IsServiceMode) { SearchModel = new NodeSearchModel(Logger); SearchModel.ItemProduced += diff --git a/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs index 27fa340d85f..8347cccf4a4 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs @@ -851,7 +851,7 @@ public NodeViewModel(WorkspaceViewModel workspaceViewModel, NodeModel logic) ZIndex = ++StaticZIndex; ++NoteViewModel.StaticZIndex; - if (workspaceViewModel.InCanvasSearchViewModel.TryGetNodeIcon(this, out ImageSource imgSource)) + if (workspaceViewModel.InCanvasSearchViewModel != null && workspaceViewModel.InCanvasSearchViewModel.TryGetNodeIcon(this, out ImageSource imgSource)) { ImageSource = imgSource; } diff --git a/src/DynamoCoreWpf/ViewModels/Core/WorkspaceViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/WorkspaceViewModel.cs index 6449f9e3775..158c86c7016 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/WorkspaceViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/WorkspaceViewModel.cs @@ -489,21 +489,23 @@ public WorkspaceViewModel(WorkspaceModel model, DynamoViewModel dynamoViewModel) // InCanvasSearchViewModel needs to happen before the nodes are created // as we rely upon it to retrieve node icon images - InCanvasSearchViewModel = new SearchViewModel(DynamoViewModel) + if (!dynamoViewModel.Model.IsServiceMode) { - Visible = true - }; + InCanvasSearchViewModel = new SearchViewModel(DynamoViewModel) + { + Visible = true + }; + NodeAutoCompleteSearchViewModel = new NodeAutoCompleteSearchViewModel(DynamoViewModel) + { + Visible = true + }; + } // sync collections foreach (NodeModel node in Model.Nodes) Model_NodeAdded(node); foreach (NoteModel note in Model.Notes) Model_NoteAdded(note); foreach (AnnotationModel annotation in Model.Annotations) Model_AnnotationAdded(annotation); foreach (ConnectorModel connector in Model.Connectors) Connectors_ConnectorAdded(connector); - - NodeAutoCompleteSearchViewModel = new NodeAutoCompleteSearchViewModel(DynamoViewModel) - { - Visible = true - }; } /// /// This event is triggered from Workspace Model. Used in instrumentation @@ -552,8 +554,8 @@ public override void Dispose() Connectors.Clear(); Errors.Clear(); Annotations.Clear(); - InCanvasSearchViewModel.Dispose(); - NodeAutoCompleteSearchViewModel.Dispose(); + InCanvasSearchViewModel?.Dispose(); + NodeAutoCompleteSearchViewModel?.Dispose(); } internal void ZoomInInternal() diff --git a/src/LibraryViewExtensionWebView2/Handlers/NodeItemDataProvider.cs b/src/LibraryViewExtensionWebView2/Handlers/NodeItemDataProvider.cs index 25b54644151..5a88f77c198 100644 --- a/src/LibraryViewExtensionWebView2/Handlers/NodeItemDataProvider.cs +++ b/src/LibraryViewExtensionWebView2/Handlers/NodeItemDataProvider.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -60,7 +60,7 @@ public override Stream GetResource(string url, out string extension) { extension = "json"; //pass false to keep original icon urls - return GetNodeItemDataStream(model.SearchEntries, false); + return GetNodeItemDataStream(model?.SearchEntries, false); } /// diff --git a/src/LibraryViewExtensionWebView2/LibraryViewController.cs b/src/LibraryViewExtensionWebView2/LibraryViewController.cs index d1e48ed60e3..af84520602a 100644 --- a/src/LibraryViewExtensionWebView2/LibraryViewController.cs +++ b/src/LibraryViewExtensionWebView2/LibraryViewController.cs @@ -155,20 +155,22 @@ internal void RefreshLibraryView(WebView2 browser) { string layoutSpecsjson = String.Empty; string loadedTypesjson = String.Empty; - - dynamoWindow.Dispatcher.BeginInvoke( - new Action(() => + if (!dynamoViewModel.Model.IsServiceMode) { - var ext1 = string.Empty; - var ext2 = string.Empty; - var reader = new StreamReader(nodeProvider.GetResource(null, out ext1)); - var loadedTypes = reader.ReadToEnd(); + dynamoWindow.Dispatcher.BeginInvoke( + new Action(() => + { + var ext1 = string.Empty; + var ext2 = string.Empty; + var reader = new StreamReader(nodeProvider.GetResource(null, out ext1)); + var loadedTypes = reader.ReadToEnd(); - var reader2 = new StreamReader(layoutProvider.GetResource(null, out ext2)); - var layoutSpec = reader2.ReadToEnd(); + var reader2 = new StreamReader(layoutProvider.GetResource(null, out ext2)); + var layoutSpec = reader2.ReadToEnd(); - ExecuteScriptFunctionAsync(browser, "refreshLibViewFromData", loadedTypes, layoutSpec); - })); + ExecuteScriptFunctionAsync(browser, "refreshLibViewFromData", loadedTypes, layoutSpec); + })); + } } #endregion @@ -461,18 +463,21 @@ internal static IDisposable SetupSearchModelEventsObserver(WebView2 webview, Nod }; Action onRemove = e => handler(null); - //Set up the event callback - model.EntryAdded += handler; - model.EntryRemoved += onRemove; - model.EntryUpdated += handler; - - //Set up the dispose event handler - observer.Disposed += () => + if (model != null) { - model.EntryAdded -= handler; - model.EntryRemoved -= onRemove; - model.EntryUpdated -= handler; - }; + //Set up the event callback + model.EntryAdded += handler; + model.EntryRemoved += onRemove; + model.EntryUpdated += handler; + + //Set up the dispose event handler + observer.Disposed += () => + { + model.EntryAdded -= handler; + model.EntryRemoved -= onRemove; + model.EntryUpdated -= handler; + }; + } return observer; } From e015a9c26b5a0341d8ad0bfe0b7867a5799480c2 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Tue, 10 Jan 2023 21:05:56 +0800 Subject: [PATCH 05/19] add console output --- src/DynamoCore/Models/DynamoModel.cs | 1 - src/DynamoWPFCLI/Program.cs | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 83ded73f855..009ac054b6a 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -709,7 +709,6 @@ protected DynamoModel(IStartConfiguration config) // Do nothing for now } - // If user skipped analytics from assembly config, do not try to launch the analytics client // or the feature flags client. if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics && !IsServiceMode) diff --git a/src/DynamoWPFCLI/Program.cs b/src/DynamoWPFCLI/Program.cs index f027de445b4..f6be0ffad4b 100644 --- a/src/DynamoWPFCLI/Program.cs +++ b/src/DynamoWPFCLI/Program.cs @@ -27,7 +27,10 @@ internal static void Main(string[] args) { Dynamo.Logging.Analytics.DisableAnalytics = true; } - + if(cmdLineArgs.ServiceMode) + { + Console.WriteLine("Starting DynamoWPFCLI in service mode"); + } if (cmdLineArgs.KeepAlive) { var thread = new Thread(() => RunKeepAlive(cmdLineArgs)) From 344c1d7888717c4f4b9dad8c4b9912eb74677b32 Mon Sep 17 00:00:00 2001 From: reddyashish <43763136+reddyashish@users.noreply.github.com> Date: Thu, 12 Jan 2023 00:13:28 -0500 Subject: [PATCH 06/19] [DNM] DAAS draft (#13677) * Removing CanToggleLoginState (#13657) * Dyn 5488 add horizontal scroll bar (#13661) * DYN-5488-Add-Horizontal-Scrollbar When showing the documentation for packages the PackageDetailView extension was not showing the horizontal scroll bar then I added a change so that will be shown when the content is bigger than the usual width. * DYN-5488-Add-Horizontal-Scrollbar The HorizontalScrollBar will be shown only in the DataGrid due that if is shown in the complete SideBar is showing a weird white box. * Disable loading extensions and view extensions in service mode. Co-authored-by: filipeotero <89042471+filipeotero@users.noreply.github.com> Co-authored-by: Roberto T <61755417+RobertGlobant20@users.noreply.github.com> --- src/DynamoCore/Core/AuthenticationManager.cs | 8 -------- src/DynamoCore/Models/DynamoModel.cs | 2 +- .../ViewModels/Core/DynamoViewModel.cs | 9 +++++++-- .../Core/DynamoViewModelDelegateCommands.cs | 13 +++++++++---- .../ViewModels/Menu/PreferencesViewModel.cs | 7 +++++-- src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs | 17 ++++++++++------- .../PackageDetailsView.xaml | 7 +++++-- .../AuthenticationManagerTests.cs | 9 --------- 8 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/DynamoCore/Core/AuthenticationManager.cs b/src/DynamoCore/Core/AuthenticationManager.cs index d316c8c7974..7e54ddfe4ef 100644 --- a/src/DynamoCore/Core/AuthenticationManager.cs +++ b/src/DynamoCore/Core/AuthenticationManager.cs @@ -86,14 +86,6 @@ internal void ToggleLoginState(object o) } } - /// - /// Check if able to toggle login state - /// - internal bool CanToggleLoginState() - { - return this.LoginState == LoginState.LoggedOut || this.LoginState == LoginState.LoggedIn; - } - internal void Login() { if (!HasAuthProvider) return; diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 009ac054b6a..7cf044ea594 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -932,7 +932,7 @@ protected DynamoModel(IStartConfiguration config) DynamoModel.OnRequestUpdateLoadBarStatus(new SplashScreenLoadEventArgs(Resources.SplashScreenLoadNodeLibrary, 50)); InitializeNodeLibrary(); - if (extensions.Any()) + if (!IsServiceMode && extensions.Any()) { var startupParams = new StartupParams(this); diff --git a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs index e5d04ee2c4e..9042fb889f8 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs @@ -687,7 +687,12 @@ protected DynamoViewModel(StartConfiguration startConfiguration) UsageReportingManager.Instance.InitializeCore(this); this.WatchHandler = startConfiguration.WatchHandler; var pmExtension = model.GetPackageManagerExtension(); - this.PackageManagerClientViewModel = new PackageManagerClientViewModel(this, pmExtension.PackageManagerClient); + + if (pmExtension != null) + { + this.PackageManagerClientViewModel = new PackageManagerClientViewModel(this, pmExtension.PackageManagerClient); + } + this.SearchViewModel = null; // Start page should not show up during test mode. @@ -2129,7 +2134,7 @@ internal void ShowPackageManagerSearch(object parameters) internal bool CanShowPackageManagerSearch(object parameters) { - return true; + return !model.IsServiceMode; } /// diff --git a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelDelegateCommands.cs b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelDelegateCommands.cs index 99dd2c8f195..3fbfcf66124 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelDelegateCommands.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelDelegateCommands.cs @@ -65,12 +65,17 @@ private void InitializeDelegateCommands() DisplayInteractiveGuideCommand = new DelegateCommand(DisplayStartPage, CanDisplayInteractiveGuide); GettingStartedGuideCommand = new DelegateCommand(StartGettingStartedGuide, CanStartGettingStartedGuide); ShowPackageManagerSearchCommand = new DelegateCommand(ShowPackageManagerSearch, CanShowPackageManagerSearch); - PublishNewPackageCommand = new DelegateCommand(PackageManagerClientViewModel.PublishNewPackage, PackageManagerClientViewModel.CanPublishNewPackage); ShowInstalledPackagesCommand = new DelegateCommand(o => { }, o => true); ManagePackagePathsCommand = new DelegateCommand(o => { }, o => true); - PublishCurrentWorkspaceCommand = new DelegateCommand(PackageManagerClientViewModel.PublishCurrentWorkspace, PackageManagerClientViewModel.CanPublishCurrentWorkspace); - PublishSelectedNodesCommand = new DelegateCommand(PackageManagerClientViewModel.PublishSelectedNodes, PackageManagerClientViewModel.CanPublishSelectedNodes); - PublishCustomNodeCommand = new DelegateCommand(PackageManagerClientViewModel.PublishCustomNode, PackageManagerClientViewModel.CanPublishCustomNode); + + if (PackageManagerClientViewModel != null) + { + PublishNewPackageCommand = new DelegateCommand(PackageManagerClientViewModel.PublishNewPackage, PackageManagerClientViewModel.CanPublishNewPackage); + PublishCurrentWorkspaceCommand = new DelegateCommand(PackageManagerClientViewModel.PublishCurrentWorkspace, PackageManagerClientViewModel.CanPublishCurrentWorkspace); + PublishSelectedNodesCommand = new DelegateCommand(PackageManagerClientViewModel.PublishSelectedNodes, PackageManagerClientViewModel.CanPublishSelectedNodes); + PublishCustomNodeCommand = new DelegateCommand(PackageManagerClientViewModel.PublishCustomNode, PackageManagerClientViewModel.CanPublishCustomNode); + } + SelectNeighborsCommand = new DelegateCommand(SelectNeighbors, CanSelectNeighbors); ClearLogCommand = new DelegateCommand(ClearLog, CanClearLog); PanCommand = new DelegateCommand(Pan, CanPan); diff --git a/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs b/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs index d6ff1b2f390..df70e2658db 100644 --- a/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs @@ -1098,8 +1098,11 @@ public PreferencesViewModel(DynamoViewModel dynamoViewModel) this.preferenceSettings = dynamoViewModel.PreferenceSettings; this.pythonScriptEditorTextOptions = dynamoViewModel.PythonScriptEditorTextOptions; this.dynamoViewModel = dynamoViewModel; - this.installedPackagesViewModel = new InstalledPackagesViewModel(dynamoViewModel, - dynamoViewModel.PackageManagerClientViewModel.PackageManagerExtension.PackageLoader); + + if (dynamoViewModel.PackageManagerClientViewModel != null) + { + installedPackagesViewModel = new InstalledPackagesViewModel(dynamoViewModel, dynamoViewModel.PackageManagerClientViewModel.PackageManagerExtension.PackageLoader); + } // Scan for engines AddPythonEnginesOptions(); diff --git a/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs b/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs index ec2ded6d658..9c0c72eea13 100644 --- a/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs +++ b/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs @@ -911,15 +911,18 @@ private void DynamoViewModelRequestViewOperation(ViewOperationEventArgs e) private void DynamoLoadedViewExtensionHandler(ViewLoadedParams loadedParams, IEnumerable extensions) { - foreach (var ext in extensions) + if (!dynamoViewModel.Model.IsServiceMode) { - try + foreach (var ext in extensions) { - ext.Loaded(loadedParams); - } - catch (Exception exc) - { - Log(ext.Name + ": " + exc.Message); + try + { + ext.Loaded(loadedParams); + } + catch (Exception exc) + { + Log(ext.Name + ": " + exc.Message); + } } } } diff --git a/src/PackageDetailsViewExtension/PackageDetailsView.xaml b/src/PackageDetailsViewExtension/PackageDetailsView.xaml index 762fca4da40..3c979e17594 100644 --- a/src/PackageDetailsViewExtension/PackageDetailsView.xaml +++ b/src/PackageDetailsViewExtension/PackageDetailsView.xaml @@ -137,14 +137,17 @@ - + - + diff --git a/test/DynamoCoreTests/AuthenticationManagerTests.cs b/test/DynamoCoreTests/AuthenticationManagerTests.cs index c0d9f7a532f..c087ed4a5e2 100644 --- a/test/DynamoCoreTests/AuthenticationManagerTests.cs +++ b/test/DynamoCoreTests/AuthenticationManagerTests.cs @@ -74,15 +74,6 @@ public void ToggleLoginState() Assert.True(loginCalled); } - [Test] - public void CanToggleLoginState() - { - var authProviderMock = new Mock(); - var authManager = new AuthenticationManager(authProviderMock.Object); - - Assert.IsTrue(authManager.CanToggleLoginState()); - } - #endregion #region Properties From 22cb690ad32a2a81eb416eecc83ebb5b9fa419ac Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Fri, 13 Jan 2023 20:52:37 +0800 Subject: [PATCH 07/19] Clean up --- src/DynamoApplications/StartupUtils.cs | 19 +++++++++++++------ src/DynamoCore/Models/DynamoModel.cs | 7 ++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs index 5fa659175a4..07ca2036f86 100644 --- a/src/DynamoApplications/StartupUtils.cs +++ b/src/DynamoApplications/StartupUtils.cs @@ -283,6 +283,10 @@ private static void ShowHelp(OptionSet opSet) public bool DisableAnalytics { get; set; } public HostAnalyticsInfo AnalyticsInfo { get; set; } public string CERLocation { get; set; } + + /// + /// Boolean indication of launching Dynamo in service mode, this mode it optimized for minimal launch time + /// public bool ServiceMode { get; set; } } @@ -332,7 +336,8 @@ private static IUpdateManager InitializeUpdateManager() /// /// Path to directory containing geometry library binaries /// Path to be used by PathResolver for UserDataFolder - /// Path to be used by PathResolver for CommonDataFolder + /// Path to be used by PathResolver for CommonDataFolder + /// Host analytics info specifying Dynamo launching host related information. /// public static DynamoModel MakeCLIModel(string asmPath, string userDataFolder, string commonDataFolder, HostAnalyticsInfo info = new HostAnalyticsInfo()) { @@ -349,7 +354,9 @@ private static IUpdateManager InitializeUpdateManager() /// /// Path to directory containing geometry library binaries /// Path to be used by PathResolver for UserDataFolder - /// Path to be used by PathResolver for CommonDataFolder + /// Path to be used by PathResolver for CommonDataFolder + /// Host analytics info specifying Dynamo launching host related information. + /// Boolean indication of launching Dynamo in service mode, this mode it optimized for minimal launch time. /// public static DynamoModel MakeCLIModel(string asmPath, string userDataFolder, string commonDataFolder, HostAnalyticsInfo info = new HostAnalyticsInfo(), bool isServiceMode = false) { @@ -381,7 +388,7 @@ public static DynamoModel MakeModel(bool CLImode, string asmPath = "", string ho /// /// CLI mode starts the model in test mode and uses a separate path resolver. /// Path to directory containing geometry library binaries - /// Host analytics info + /// Host analytics info specifying Dynamo launching host related information. /// public static DynamoModel MakeModel(bool CLImode, string asmPath = "", HostAnalyticsInfo info = new HostAnalyticsInfo()) { @@ -490,9 +497,9 @@ private static DynamoModel StartDynamoWithDefaultConfig(bool CLImode, UpdateManager = CLImode ? null : OSHelper.IsWindows() ? InitializeUpdateManager() : null, StartInTestMode = CLImode, PathResolver = CLImode ? new CLIPathResolver(preloaderLocation, userDataFolder, commonDataFolder) as IPathResolver : new SandboxPathResolver(preloaderLocation) as IPathResolver, - // Update Default start config to include IsServiceMode so DynamoModel can initialize with that flag. If set later, it might be too late. - // TBD, do we want to reuse the old Context property? - Context = "Service" + // TODO: Dynamo 3.0 + // Update Default start config to include IsServiceMode so DynamoModel can be initialize with that flag. For now, reuse the legacy Context property + Context = isServiceMode ? "Service": string.Empty }; var model = DynamoModel.Start(config); diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 7cf044ea594..c83341ae276 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -209,7 +209,7 @@ public string Version public HostAnalyticsInfo HostAnalyticsInfo { get; set; } /// - /// Boolean indicating if Dynamo is running in service model, mostly leveraged by CLI or WPF CLI + /// Boolean indication of launching Dynamo in service mode, this mode it optimized for minimal launch time, mostly leveraged by CLI or WPF CLI. /// public bool IsServiceMode { get; set; } @@ -642,7 +642,7 @@ protected DynamoModel(IStartConfiguration config) pathManager.EnsureDirectoryExistence(exceptions); Context = config.Context; - // This condition is TBD + // This condition could be updated later depending on if we reuse the legacy Context property IsServiceMode = config.Context.Equals("Service"); IsTestMode = config.StartInTestMode; IsHeadless = config.IsHeadless; @@ -652,9 +652,10 @@ protected DynamoModel(IStartConfiguration config) if (!IsServiceMode) { + // Log all exceptions as part of directories check. foreach (var exception in exceptions) { - Logger.Log(exception); // Log all exceptions. + Logger.Log(exception); } } From 7d5d73bdee7896f192886aacc1937e9b292969d6 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Fri, 13 Jan 2023 22:15:31 +0800 Subject: [PATCH 08/19] Clean up and skip more steps --- src/DynamoCore/Extensions/StartupParams.cs | 4 +- src/DynamoCore/Models/DynamoModel.cs | 43 +++++++++++++--------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/DynamoCore/Extensions/StartupParams.cs b/src/DynamoCore/Extensions/StartupParams.cs index 0ad98fb72ce..657074dd3b9 100644 --- a/src/DynamoCore/Extensions/StartupParams.cs +++ b/src/DynamoCore/Extensions/StartupParams.cs @@ -1,4 +1,4 @@ -using System; +using System; using Dynamo.Graph.Nodes.CustomNodes; using Dynamo.Interfaces; using Dynamo.Library; @@ -111,7 +111,7 @@ public StartupParams(IAuthProvider provider, IPathManager pathManager, /// internal StartupParams(DynamoModel dynamoModel) { - this.authProvider = dynamoModel.AuthenticationManager.AuthProvider; + this.authProvider = dynamoModel.AuthenticationManager?.AuthProvider; this.pathManager = dynamoModel.PathManager; this.libraryLoader = new ExtensionLibraryLoader(dynamoModel); this.customNodeManager = dynamoModel.CustomNodeManager; diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index c83341ae276..eda9cb51ac8 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -693,25 +693,28 @@ protected DynamoModel(IStartConfiguration config) } bool areAnalyticsDisabledFromConfig = false; - try - { - // Dynamo, behind a proxy server, has been known to have issues loading the Analytics binaries. - // Using the "DisableAnalytics" configuration setting, a user can skip loading analytics binaries altogether. - var assemblyConfig = ConfigurationManager.OpenExeConfiguration(GetType().Assembly.Location); - if (assemblyConfig != null) + if (!IsServiceMode) + { // Skip getting the value for areAnalyticsDisabledFromConfig because analytics is disabled for searvice mode anyway + try { - var disableAnalyticsValue = assemblyConfig.AppSettings.Settings["DisableAnalytics"]; - if (disableAnalyticsValue != null) - bool.TryParse(disableAnalyticsValue.Value, out areAnalyticsDisabledFromConfig); + // Dynamo, behind a proxy server, has been known to have issues loading the Analytics binaries. + // Using the "DisableAnalytics" configuration setting, a user can skip loading analytics binaries altogether. + var assemblyConfig = ConfigurationManager.OpenExeConfiguration(GetType().Assembly.Location); + if (assemblyConfig != null) + { + var disableAnalyticsValue = assemblyConfig.AppSettings.Settings["DisableAnalytics"]; + if (disableAnalyticsValue != null) + bool.TryParse(disableAnalyticsValue.Value, out areAnalyticsDisabledFromConfig); + } + } + catch (Exception) + { + // Do nothing for now } - } - catch (Exception) - { - // Do nothing for now } // If user skipped analytics from assembly config, do not try to launch the analytics client - // or the feature flags client. + // or the feature flags client for web traffic reason. if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics && !IsServiceMode) { // Start the Analytics service only when a session is not present. @@ -875,7 +878,10 @@ protected DynamoModel(IStartConfiguration config) extensionManager.MessageLogged += LogMessage; var extensions = config.Extensions ?? LoadExtensions(); - LinterManager = new LinterManager(this.ExtensionManager); + if (!IsServiceMode) + { + LinterManager = new LinterManager(this.ExtensionManager); + } // when dynamo is ready, alert the loaded extensions DynamoReady += (readyParams) => @@ -919,10 +925,13 @@ protected DynamoModel(IStartConfiguration config) AddHomeWorkspace(); - AuthenticationManager = new AuthenticationManager(config.AuthProvider); + if (!IsServiceMode) + { + AuthenticationManager = new AuthenticationManager(config.AuthProvider); + } UpdateManager.Log += UpdateManager_Log; - if (!IsTestMode && !IsHeadless) + if (!IsTestMode && !IsHeadless && !IsServiceMode) { DefaultUpdateManager.CheckForProductUpdate(UpdateManager); } From 90006840d567261393c2bf7c18cc134fac7d070a Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Fri, 13 Jan 2023 23:48:46 +0800 Subject: [PATCH 09/19] clean up --- src/DynamoCore/Models/DynamoModel.cs | 5 ++--- .../PackageManager/PackageManagerClientViewModel.cs | 11 +++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index eda9cb51ac8..e865682f3b9 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -942,14 +942,13 @@ protected DynamoModel(IStartConfiguration config) DynamoModel.OnRequestUpdateLoadBarStatus(new SplashScreenLoadEventArgs(Resources.SplashScreenLoadNodeLibrary, 50)); InitializeNodeLibrary(); - if (!IsServiceMode && extensions.Any()) + if (extensions.Any()) { var startupParams = new StartupParams(this); foreach (var ext in extensions) { - var logSource = ext as ILogSource; - if (logSource != null) + if (ext is ILogSource logSource) logSource.MessageLogged += LogMessage; try diff --git a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs index 12ad50a1c93..00178196ffb 100644 --- a/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/PackageManager/PackageManagerClientViewModel.cs @@ -260,11 +260,14 @@ internal PackageManagerClientViewModel(DynamoViewModel dynamoViewModel, PackageM this.ToggleLoginStateCommand = new DelegateCommand(ToggleLoginState, CanToggleLoginState); - AuthenticationManager.LoginStateChanged += (loginState) => + if (AuthenticationManager != null) { - RaisePropertyChanged("LoginState"); - RaisePropertyChanged("Username"); - }; + AuthenticationManager.LoginStateChanged += (loginState) => + { + RaisePropertyChanged("LoginState"); + RaisePropertyChanged("Username"); + }; + } } private void ToggleLoginState() From a4212487e162d576eb5599914d56a615e922177c Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Sat, 14 Jan 2023 00:41:27 +0800 Subject: [PATCH 10/19] clean up --- src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs b/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs index 9c0c72eea13..ec2ded6d658 100644 --- a/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs +++ b/src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs @@ -911,18 +911,15 @@ private void DynamoViewModelRequestViewOperation(ViewOperationEventArgs e) private void DynamoLoadedViewExtensionHandler(ViewLoadedParams loadedParams, IEnumerable extensions) { - if (!dynamoViewModel.Model.IsServiceMode) + foreach (var ext in extensions) { - foreach (var ext in extensions) + try { - try - { - ext.Loaded(loadedParams); - } - catch (Exception exc) - { - Log(ext.Name + ": " + exc.Message); - } + ext.Loaded(loadedParams); + } + catch (Exception exc) + { + Log(ext.Name + ": " + exc.Message); } } } From c10b1a544fe61848a10cdee52b34747513b34b90 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Sat, 14 Jan 2023 01:10:45 +0800 Subject: [PATCH 11/19] clean up --- src/DynamoCore/Models/DynamoModel.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index e865682f3b9..b2b619db2c2 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -876,7 +876,11 @@ protected DynamoModel(IStartConfiguration config) //Initialize the ExtensionManager with the CommonDataDirectory so that extensions found here are checked first for dll's with signed certificates extensionManager = new ExtensionManager(new[] { PathManager.CommonDataDirectory }); extensionManager.MessageLogged += LogMessage; - var extensions = config.Extensions ?? LoadExtensions(); + var extensions = config.Extensions; + if (extensions == null && !IsServiceMode) + { + LoadExtensions(); + } if (!IsServiceMode) { @@ -942,7 +946,7 @@ protected DynamoModel(IStartConfiguration config) DynamoModel.OnRequestUpdateLoadBarStatus(new SplashScreenLoadEventArgs(Resources.SplashScreenLoadNodeLibrary, 50)); InitializeNodeLibrary(); - if (extensions.Any()) + if (!IsServiceMode && extensions.Any()) { var startupParams = new StartupParams(this); From 9fbf63c4a1c432a98436296c4f540561899ee9d5 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Sat, 14 Jan 2023 20:43:25 +0800 Subject: [PATCH 12/19] clean up --- src/DynamoApplications/StartupUtils.cs | 6 +++--- src/DynamoCore/Models/DynamoModel.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs index 07ca2036f86..e5494f1148d 100644 --- a/src/DynamoApplications/StartupUtils.cs +++ b/src/DynamoApplications/StartupUtils.cs @@ -222,7 +222,7 @@ public static CommandLineArguments Parse(string[] args) .Add("pi=|PI=|parentId", "Identify Dynamo host analytics parent id", pi => parentId = pi) .Add("da|DA|disableAnalytics", "Disables analytics in Dynamo for the process liftime", da => disableAnalytics = da != null) .Add("cr=|CR=|cerLocation", "Specify the crash error report tool location on disk ", cr => cerLocation = cr) - .Add("s|S|service mode", "Service mode, bypass certain Dynamo launch steps for maximum startup performance", s => serviceMode = s != null); + .Add("s|S|service mode", "Service mode, bypasses certain Dynamo launch steps for maximum startup performance", s => serviceMode = s != null); optionsSet.Parse(args); @@ -285,7 +285,7 @@ private static void ShowHelp(OptionSet opSet) public string CERLocation { get; set; } /// - /// Boolean indication of launching Dynamo in service mode, this mode it optimized for minimal launch time + /// Boolean indication of launching Dynamo in service mode, this mode is optimized for minimal launch time /// public bool ServiceMode { get; set; } } @@ -356,7 +356,7 @@ private static IUpdateManager InitializeUpdateManager() /// Path to be used by PathResolver for UserDataFolder /// Path to be used by PathResolver for CommonDataFolder /// Host analytics info specifying Dynamo launching host related information. - /// Boolean indication of launching Dynamo in service mode, this mode it optimized for minimal launch time. + /// Boolean indication of launching Dynamo in service mode, this mode is optimized for minimal launch time. /// public static DynamoModel MakeCLIModel(string asmPath, string userDataFolder, string commonDataFolder, HostAnalyticsInfo info = new HostAnalyticsInfo(), bool isServiceMode = false) { diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index b2b619db2c2..4d4e0f41f55 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -209,9 +209,9 @@ public string Version public HostAnalyticsInfo HostAnalyticsInfo { get; set; } /// - /// Boolean indication of launching Dynamo in service mode, this mode it optimized for minimal launch time, mostly leveraged by CLI or WPF CLI. + /// Boolean indication of launching Dynamo in service mode, this mode is optimized for minimal launch time, mostly leveraged by CLI or WPF CLI. /// - public bool IsServiceMode { get; set; } + internal bool IsServiceMode { get; set; } /// /// UpdateManager to handle automatic upgrade to higher version. From 2cf3f74a4b312fe9353e7bcde59bd9df0ff72fb4 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Sat, 14 Jan 2023 21:22:53 +0800 Subject: [PATCH 13/19] Fix Unit tests --- src/DynamoCore/Models/DynamoModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 4d4e0f41f55..77a427800f4 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -876,7 +876,7 @@ protected DynamoModel(IStartConfiguration config) //Initialize the ExtensionManager with the CommonDataDirectory so that extensions found here are checked first for dll's with signed certificates extensionManager = new ExtensionManager(new[] { PathManager.CommonDataDirectory }); extensionManager.MessageLogged += LogMessage; - var extensions = config.Extensions; + var extensions = config.Extensions ?? new List(); if (extensions == null && !IsServiceMode) { LoadExtensions(); From aede87773f4d0ea09605296e0f4e5eb317097306 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Sat, 14 Jan 2023 21:30:42 +0800 Subject: [PATCH 14/19] Clean up --- src/DynamoApplications/StartupUtils.cs | 4 +--- src/DynamoCore/Models/DynamoModel.cs | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs index e5494f1148d..fbb1d33632c 100644 --- a/src/DynamoApplications/StartupUtils.cs +++ b/src/DynamoApplications/StartupUtils.cs @@ -497,9 +497,7 @@ private static DynamoModel StartDynamoWithDefaultConfig(bool CLImode, UpdateManager = CLImode ? null : OSHelper.IsWindows() ? InitializeUpdateManager() : null, StartInTestMode = CLImode, PathResolver = CLImode ? new CLIPathResolver(preloaderLocation, userDataFolder, commonDataFolder) as IPathResolver : new SandboxPathResolver(preloaderLocation) as IPathResolver, - // TODO: Dynamo 3.0 - // Update Default start config to include IsServiceMode so DynamoModel can be initialize with that flag. For now, reuse the legacy Context property - Context = isServiceMode ? "Service": string.Empty + IsServiceMode = isServiceMode }; var model = DynamoModel.Start(config); diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 77a427800f4..aa6606b5802 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -556,6 +556,7 @@ public struct DefaultStartConfiguration : IStartConfiguration public IEnumerable Extensions { get; set; } public TaskProcessMode ProcessMode { get; set; } public bool IsHeadless { get; set; } + public bool IsServiceMode { get; set; } public string PythonTemplatePath { get; set; } /// /// Default Python script engine @@ -621,6 +622,7 @@ protected DynamoModel(IStartConfiguration config) // TODO: This fact should probably be revisited in 3.0. DefaultPythonEngine = defaultStartConfig.DefaultPythonEngine; CLIMode = defaultStartConfig.CLIMode; + IsServiceMode = defaultStartConfig.IsServiceMode; } if (config is IStartConfigCrashReporter cerConfig) @@ -642,8 +644,6 @@ protected DynamoModel(IStartConfiguration config) pathManager.EnsureDirectoryExistence(exceptions); Context = config.Context; - // This condition could be updated later depending on if we reuse the legacy Context property - IsServiceMode = config.Context.Equals("Service"); IsTestMode = config.StartInTestMode; IsHeadless = config.IsHeadless; From 935794ad6edf38a24fb6aa528759e2eb67c8aa4c Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Mon, 16 Jan 2023 16:29:04 +0800 Subject: [PATCH 15/19] Unit tests --- src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs | 2 +- src/DynamoPackagesWPF/PackageManagerViewExtension.cs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs index 9042fb889f8..d5200bc0772 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs @@ -1081,7 +1081,7 @@ void CollectInfoManager_PropertyChanged(object sender, PropertyChangedEventArgs private void SelectionOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs) { - PublishSelectedNodesCommand.RaiseCanExecuteChanged(); + PublishSelectedNodesCommand?.RaiseCanExecuteChanged(); AlignSelectedCommand.RaiseCanExecuteChanged(); DeleteCommand.RaiseCanExecuteChanged(); UngroupModelCommand.RaiseCanExecuteChanged(); diff --git a/src/DynamoPackagesWPF/PackageManagerViewExtension.cs b/src/DynamoPackagesWPF/PackageManagerViewExtension.cs index 212adb6a1bf..4b2d1441e22 100644 --- a/src/DynamoPackagesWPF/PackageManagerViewExtension.cs +++ b/src/DynamoPackagesWPF/PackageManagerViewExtension.cs @@ -79,7 +79,10 @@ event Action INotificationSource.NotificationLogged public void Dispose() { - packageManager.PackageLoader.PackgeLoaded -= packageLoadedHandler; + if (packageManager != null) + { + packageManager.PackageLoader.PackgeLoaded -= packageLoadedHandler; + } } public void Loaded(ViewLoadedParams viewLoadedParams) From 761c0a68d8778c63afa0547e7ad9a458b5eeeb85 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Mon, 16 Jan 2023 22:46:17 +0800 Subject: [PATCH 16/19] unit tests --- src/DynamoCore/Models/DynamoModel.cs | 2 +- .../ViewModels/Menu/PreferencesViewModel.cs | 2 +- src/DynamoPackagesWPF/PackageManagerViewExtension.cs | 3 ++- .../WorkspaceDependencyViewExtension.cs | 12 +++++++----- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index aa6606b5802..6346d884293 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -877,7 +877,7 @@ protected DynamoModel(IStartConfiguration config) extensionManager = new ExtensionManager(new[] { PathManager.CommonDataDirectory }); extensionManager.MessageLogged += LogMessage; var extensions = config.Extensions ?? new List(); - if (extensions == null && !IsServiceMode) + if (!extensions.Any() && !IsServiceMode) { LoadExtensions(); } diff --git a/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs b/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs index df70e2658db..24491d6fcf8 100644 --- a/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs +++ b/src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs @@ -1375,7 +1375,7 @@ internal void InitPackagePathsForInstall() /// internal void InitPackageListFilters() { - installedPackagesViewModel.PopulateFilters(); + installedPackagesViewModel?.PopulateFilters(); } /// diff --git a/src/DynamoPackagesWPF/PackageManagerViewExtension.cs b/src/DynamoPackagesWPF/PackageManagerViewExtension.cs index 4b2d1441e22..bf489892b5a 100644 --- a/src/DynamoPackagesWPF/PackageManagerViewExtension.cs +++ b/src/DynamoPackagesWPF/PackageManagerViewExtension.cs @@ -87,7 +87,7 @@ public void Dispose() public void Loaded(ViewLoadedParams viewLoadedParams) { - RequestLoadLayoutSpecs(packageManager.PackageLoader.LocalPackages); + RequestLoadLayoutSpecs(packageManager?.PackageLoader.LocalPackages); var packagesToCheck = packageManager?.PackageLoader.LocalPackages; if(packagesToCheck != null) { @@ -162,6 +162,7 @@ private void RaisePackageHostNotifications(IEnumerable packages) private void RequestLoadLayoutSpecs(IEnumerable packages) { + if (packages == null) return; foreach(var package in packages) { //only load layout specs for built in packages. diff --git a/src/WorkspaceDependencyViewExtension/WorkspaceDependencyViewExtension.cs b/src/WorkspaceDependencyViewExtension/WorkspaceDependencyViewExtension.cs index dff9002591d..85d428a275f 100644 --- a/src/WorkspaceDependencyViewExtension/WorkspaceDependencyViewExtension.cs +++ b/src/WorkspaceDependencyViewExtension/WorkspaceDependencyViewExtension.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Windows.Controls; using Dynamo.Core; @@ -84,11 +84,13 @@ public override void Loaded(ViewLoadedParams viewLoadedParams) // as we may have installed a missing package. DependencyView.CustomNodeManager = (CustomNodeManager)viewLoadedParams.StartupParams.CustomNodeManager; - - pmExtension.PackageLoader.PackgeLoaded += (package) => + if (pmExtension != null) { - DependencyView.DependencyRegen(viewLoadedParams.CurrentWorkspaceModel as WorkspaceModel, true); - }; + pmExtension.PackageLoader.PackgeLoaded += (package) => + { + DependencyView.DependencyRegen(viewLoadedParams.CurrentWorkspaceModel as WorkspaceModel, true); + }; + } // Adding a button in view menu to refresh and show manually workspaceReferencesMenuItem = new MenuItem { Header = Resources.MenuItemString, IsCheckable = true, IsChecked = false }; From 1634b707ef177fc03d4c7a6f1db8aaf5caa80032 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Thu, 19 Jan 2023 20:23:47 +0800 Subject: [PATCH 17/19] Fix Unit tests --- src/DynamoCore/Models/DynamoModel.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 6346d884293..eb1065d5449 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -715,7 +715,7 @@ protected DynamoModel(IStartConfiguration config) // If user skipped analytics from assembly config, do not try to launch the analytics client // or the feature flags client for web traffic reason. - if (!areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics && !IsServiceMode) + if (!IsServiceMode && !areAnalyticsDisabledFromConfig && !Dynamo.Logging.Analytics.DisableAnalytics) { // Start the Analytics service only when a session is not present. // In an integrator host, as splash screen can be closed without shutting down the ViewModel, the analytics service is not stopped. @@ -761,7 +761,7 @@ protected DynamoModel(IStartConfiguration config) } // TBD: Do we need settings migrator for service mode? If we config the docker correctly, this could be skipped I think - if (!IsTestMode && PreferenceSettings.IsFirstRun && !IsServiceMode) + if (!IsServiceMode && !IsTestMode && PreferenceSettings.IsFirstRun) { DynamoMigratorBase migrator = null; @@ -788,7 +788,7 @@ protected DynamoModel(IStartConfiguration config) } } - if (PreferenceSettings.IsFirstRun && !IsTestMode && !IsServiceMode) + if (!IsServiceMode && PreferenceSettings.IsFirstRun && !IsTestMode) { PreferenceSettings.AddDefaultTrustedLocations(); } @@ -879,9 +879,8 @@ protected DynamoModel(IStartConfiguration config) var extensions = config.Extensions ?? new List(); if (!extensions.Any() && !IsServiceMode) { - LoadExtensions(); + extensions = LoadExtensions(); } - if (!IsServiceMode) { LinterManager = new LinterManager(this.ExtensionManager); From f48f25fc45619d7784bcb5fb5d7175a675d7f5c4 Mon Sep 17 00:00:00 2001 From: "Aaron (Qilong)" <173288704@qq.com> Date: Thu, 19 Jan 2023 21:47:16 +0800 Subject: [PATCH 18/19] Comments --- .../ViewModels/Core/DynamoViewModelDelegateCommands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelDelegateCommands.cs b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelDelegateCommands.cs index 3fbfcf66124..4bbcad337ad 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelDelegateCommands.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelDelegateCommands.cs @@ -68,7 +68,7 @@ private void InitializeDelegateCommands() ShowInstalledPackagesCommand = new DelegateCommand(o => { }, o => true); ManagePackagePathsCommand = new DelegateCommand(o => { }, o => true); - if (PackageManagerClientViewModel != null) + if (PackageManagerClientViewModel != null && !Model.IsServiceMode) { PublishNewPackageCommand = new DelegateCommand(PackageManagerClientViewModel.PublishNewPackage, PackageManagerClientViewModel.CanPublishNewPackage); PublishCurrentWorkspaceCommand = new DelegateCommand(PackageManagerClientViewModel.PublishCurrentWorkspace, PackageManagerClientViewModel.CanPublishCurrentWorkspace); From 1c04c3a79ae05ea9dc3dc9e6eabc0675e6324c3a Mon Sep 17 00:00:00 2001 From: Craig Long Date: Wed, 15 Feb 2023 11:45:33 -0500 Subject: [PATCH 19/19] Service mode changes (#13739) * Add ServiceMode to Linux * Load extensions in service mode * Do not load preference setting file in ServiceMode --------- Co-authored-by: Craig Long --- src/DynamoApplications/StartupUtils.cs | 5 ++++- src/DynamoCore/Models/DynamoModel.cs | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/DynamoApplications/StartupUtils.cs b/src/DynamoApplications/StartupUtils.cs index d773eea35c4..62ca831c3df 100644 --- a/src/DynamoApplications/StartupUtils.cs +++ b/src/DynamoApplications/StartupUtils.cs @@ -63,6 +63,8 @@ internal class CMDLineOptions public string SessionId { get; set; } = String.Empty; [Option("CERLocation", Required = false, HelpText = "Specify the crash error report tool location on disk.")] public string CERLocation { get; set; } = String.Empty; + [Option("ServiceMode", Required = false, HelpText = "Specify the service mode startup.")] + public bool ServiceMode { get; set; } } #endif @@ -144,7 +146,8 @@ public static CommandLineArguments Parse(string[] args) CommonDataFolder = cmdArgs.CommonDataFolder, DisableAnalytics = cmdArgs.DisableAnalytics, AnalyticsInfo = new HostAnalyticsInfo() { HostName = cmdArgs.HostName, ParentId = cmdArgs.ParentId, SessionId = cmdArgs.SessionId }, - CERLocation = cmdArgs.CERLocation + CERLocation = cmdArgs.CERLocation, + ServiceMode = cmdArgs.ServiceMode }; }, errs => new CommandLineArguments()); #else diff --git a/src/DynamoCore/Models/DynamoModel.cs b/src/DynamoCore/Models/DynamoModel.cs index 1bf1702dbe9..1605368c6e6 100644 --- a/src/DynamoCore/Models/DynamoModel.cs +++ b/src/DynamoCore/Models/DynamoModel.cs @@ -945,7 +945,7 @@ protected DynamoModel(IStartConfiguration config) DynamoModel.OnRequestUpdateLoadBarStatus(new SplashScreenLoadEventArgs(Resources.SplashScreenLoadNodeLibrary, 50)); InitializeNodeLibrary(); - if (!IsServiceMode && extensions.Any()) + if (extensions.Any()) { var startupParams = new StartupParams(this); @@ -1641,6 +1641,10 @@ private IPreferences CreateOrLoadPreferences(IPreferences preferences) if (preferences != null) // If there is preference settings provided... return preferences; + //Skip file handling in service mode. + if (IsServiceMode) + return new PreferenceSettings(); + // Is order for test cases not to interfere with the regular preference // settings xml file, a test case usually specify a temporary xml file // path from where preference settings are to be loaded. If that value