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

Address loading of packages with inter-dependencies #9736

Merged
merged 24 commits into from
Jun 14, 2019
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ee6c734
refactor package loading
aparajit-pratap May 23, 2019
464b6c9
change method name
aparajit-pratap May 23, 2019
217d94c
refactor import packages during install
aparajit-pratap May 28, 2019
49fd77f
add import library step into VM after ImportLibrary is called
aparajit-pratap May 29, 2019
cbafa86
fixes in library services resolve assembly
aparajit-pratap May 31, 2019
6e2b5c5
try sending failure messages to notification view extension
aparajit-pratap Jun 3, 2019
d7b9e30
resolve merge conflicts
aparajit-pratap Jun 5, 2019
2f0c2e0
surface package load exception to notifications view extension
aparajit-pratap Jun 5, 2019
569391d
clear notifications from logger after adding them to notifications ex…
aparajit-pratap Jun 6, 2019
59ea808
surface more library load failed exceptions to notification view exte…
aparajit-pratap Jun 6, 2019
cf2439d
address review comments
aparajit-pratap Jun 7, 2019
ca83965
revert unchanged file
aparajit-pratap Jun 7, 2019
d84b635
obsolete public API's no longer used and to be removed in 3.0
aparajit-pratap Jun 7, 2019
280427d
remove ReadyParams property
aparajit-pratap Jun 10, 2019
ba5f018
cleanup
aparajit-pratap Jun 10, 2019
3f1ae10
correct for importing library from assembly info in old xml formatted…
aparajit-pratap Jun 10, 2019
cfb1069
more cleanup
aparajit-pratap Jun 10, 2019
a3169ce
refactor LibraryServices methods
aparajit-pratap Jun 10, 2019
07dadd0
code cleanup, documentation
aparajit-pratap Jun 10, 2019
496da7a
add reasons for obsoleting methods
aparajit-pratap Jun 11, 2019
3b4581e
add test for loading interdependent packages
aparajit-pratap Jun 13, 2019
19f584b
cleanup
aparajit-pratap Jun 13, 2019
3540348
update failing tests from self-serve
aparajit-pratap Jun 14, 2019
2ca9f52
revert unchanged file
aparajit-pratap Jun 14, 2019
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
17 changes: 15 additions & 2 deletions src/DynamoCore/Extensions/ExtensionLibraryLoader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Dynamo.Engine;
using Dynamo.Library;
using Dynamo.Models;

Expand All @@ -7,7 +10,7 @@ namespace Dynamo.Extensions
/// <summary>
/// Provides functionality for loading node's DLLs
/// </summary>
public class ExtensionLibraryLoader : ILibraryLoader
public class ExtensionLibraryLoader : ILibraryLoader
{
private readonly DynamoModel model;

Expand All @@ -28,5 +31,15 @@ public void LoadNodeLibrary(Assembly library)
{
model.LoadNodeLibrary(library);
}

/// <summary>
/// Loads packages for import into VM and for node search.
/// </summary>
/// <param name="assemblies"></param>
public void LoadPackages(IEnumerable<Assembly> assemblies)
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved
{
var libraryPaths = assemblies.Select(x => x.Location);
model.LibraryServices.OnLibrariesImported(new LibraryServices.LibraryLoadedEventArgs(libraryPaths));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
Expand Down
6 changes: 5 additions & 1 deletion src/DynamoCore/Library/ILibraryLoader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reflection;
using System.Collections.Generic;
using System.Reflection;

namespace Dynamo.Library
{
Expand All @@ -11,5 +12,8 @@ public interface ILibraryLoader
/// Loads node's library
/// </summary>
void LoadNodeLibrary(Assembly library);

//TODO: Add LoadPackages to interface in 3.0
//void LoadPackages(IEnumerable<Assembly> assemblies);
}
}
85 changes: 59 additions & 26 deletions src/DynamoCore/Library/LibraryServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
using Dynamo.Configuration;
using Dynamo.Exceptions;
Expand All @@ -17,6 +18,7 @@
using ProtoCore.Namespace;
using ProtoCore.Utils;
using ProtoFFI;
using MethodAttributes = ProtoCore.AST.AssociativeAST.MethodAttributes;
using Operator = ProtoCore.DSASM.Operator;

namespace Dynamo.Engine
Expand Down Expand Up @@ -72,20 +74,6 @@ public UpgradeHint()
private readonly Dictionary<string, UpgradeHint> priorNameHints =
new Dictionary<string, UpgradeHint>();

/// <summary>
/// Copy properties from the liveCore
/// The properties to copy are only those used by the library core
/// </summary>
internal void UpdateLibraryCoreData()
{
// If a liverunner core is provided, sync the library core data
if (liveRunnerCore != null)
{
LibraryManagementCore.ProcTable = new ProtoCore.DSASM.ProcedureTable(liveRunnerCore.ProcTable);
LibraryManagementCore.ClassTable = new ProtoCore.DSASM.ClassTable(liveRunnerCore.ClassTable);
}
}

/// <summary>
/// Initializes a new instance of the <see cref="LibraryServices"/> class.
/// </summary>
Expand All @@ -111,6 +99,34 @@ public LibraryServices(ProtoCore.Core libraryManagementCore, IPathManager pathMa
PopulateOperators();
PopulatePreloadLibraries();
LibraryLoadFailed += new EventHandler<LibraryLoadFailedEventArgs>(LibraryLoadFailureHandler);

AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
}

private Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
var assemblyName = new AssemblyName(args.Name).Name + ".dll";
var assemblyPath = assemblyName;
try
{
if (pathManager.ResolveLibraryPath(ref assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}

foreach (var packagesDirectory in pathManager.PackagesDirectories)
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved
{
assemblyPath = Path.Combine(packagesDirectory, assemblyName);
if (File.Exists(assemblyPath))
return Assembly.LoadFrom(assemblyPath);
}

return null;
}
catch (Exception ex)
{
throw new Exception(string.Format("The location of the assembly, {0} could not be resolved for loading.", assemblyName), ex);
}
}

/// <summary>
Expand All @@ -121,6 +137,8 @@ public void Dispose()
builtinFunctionGroups.Clear();
importedFunctionGroups.Clear();
importedLibraries.Clear();

AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssembly;
}

/// <summary>
Expand Down Expand Up @@ -167,6 +185,7 @@ private void LibraryLoadFailureHandler(object sender, LibraryLoadFailedEventArgs
{
LibraryLoadFailedException ex = new LibraryLoadFailedException(args.LibraryPath, args.Reason);
Log(ex.Message, WarningLevel.Moderate);
Log(ex);

// NOTE: We do not want to throw an exception here if the failure was due
// to a missing library that was explicitly (attempted to be) loaded
Expand Down Expand Up @@ -521,7 +540,7 @@ private static bool TryGetFunctionGroup(
/// </summary>
/// <param name="library">The library to be loaded</param>
/// <param name="isExplicitlyImportedLib">Indicates if the library has been imported using the "File | ImportLibrary" command</param>
internal bool ImportLibrary(string library, bool isExplicitlyImportedLib = false)
internal bool LoadNodeLibrary(string library, bool isExplicitlyImportedLib)
{
if (null == library)
throw new ArgumentNullException();
Expand Down Expand Up @@ -579,7 +598,7 @@ internal bool ImportLibrary(string library, bool isExplicitlyImportedLib = false
foreach (ErrorEntry error in LibraryManagementCore.BuildStatus.Errors)
{
Log(error.Message, WarningLevel.Moderate);
errorMessage += error.Message + "\n";
errorMessage += Environment.NewLine + error.Message;
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved
}

throw new Exception(errorMessage);
Expand All @@ -605,14 +624,17 @@ internal bool ImportLibrary(string library, bool isExplicitlyImportedLib = false
throwOnFailure: !isExplicitlyImportedLib));
return false;
}
importedLibraries.Add(library);

OnLibraryLoaded(new LibraryLoadedEventArgs(library));

// After a library is loaded, update the library core data with the liveRunner core data
UpdateLibraryCoreData();
return true;
}

internal void ImportLibrary(string library, bool isExplicitlyImportedLib = false)
{
LoadNodeLibrary(library, isExplicitlyImportedLib);
OnLibrariesImported(new LibraryLoadedEventArgs(new List<string> {library}));
}


internal void LoadLibraryMigrations(string library)
{
Expand Down Expand Up @@ -874,7 +896,7 @@ private void PopulateOperators()
}

/// <summary>
/// Polulate preloaded libraries.
/// Populate preloaded libraries.
/// </summary>
private void PopulatePreloadLibraries()
{
Expand Down Expand Up @@ -1085,13 +1107,13 @@ private void OnLibraryLoadFailed(LibraryLoadFailedEventArgs e)
handler(this, e);
}

private void OnLibraryLoaded(LibraryLoadedEventArgs e)
internal void OnLibrariesImported(LibraryLoadedEventArgs e)
{
importedLibraries.Add(e.LibraryPath);

EventHandler<LibraryLoadedEventArgs> handler = LibraryLoaded;
var handler = LibraryLoaded;
if (handler != null)
{
handler(this, e);
}
}

public static class Categories
Expand Down Expand Up @@ -1133,12 +1155,23 @@ public LibraryLoadFailedEventArgs(string libraryPath, string reason, bool throwO

public class LibraryLoadedEventArgs : EventArgs
{
// TODO: Remove in 3.0
[Obsolete]
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved
public LibraryLoadedEventArgs(string libraryPath)
{
LibraryPath = libraryPath;
}

public string LibraryPath { get; private set; }
public LibraryLoadedEventArgs(IEnumerable<string> libraryPaths)
{
LibraryPaths = libraryPaths;
}

// TODO: Remove in 3.0
[Obsolete]
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved
public string LibraryPath { get; }

public IEnumerable<string> LibraryPaths { get; }
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved
}

public class LibraryLoadingEventArgs : EventArgs
Expand Down
36 changes: 35 additions & 1 deletion src/DynamoCore/Logging/DynamoLogger.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Dynamo.Configuration;
using Dynamo.Core;
using Dynamo.Exceptions;
using Dynamo.Interfaces;

namespace Dynamo.Logging
Expand Down Expand Up @@ -139,6 +141,16 @@ public string LogText
}
}

private List<NotificationMessage> notifications;
/// <summary>
/// Notifications logged during startup such as library load failures
/// that need to be displayed to user.
/// </summary>
public IEnumerable<NotificationMessage> StartupNotifications
{
get { return notifications; }
}

/// <summary>
/// Initializes a new instance of <see cref="DynamoLogger"/> class
/// with specified debug settings and directory where to write logs
Expand All @@ -155,6 +167,8 @@ public DynamoLogger(DebugSettings debugSettings, string logDirectory)
WarningLevel = WarningLevel.Mild;
Warning = "";

notifications = new List<NotificationMessage>();

StartLogging(logDirectory);
}
}
Expand Down Expand Up @@ -239,7 +253,14 @@ public void LogNotification(string sender,string title, string shortMessage, str
{
var notificationMessage = string.Format("{0}:{3} {1}: {3} {2}", title, shortMessage, detailedMessage,Environment.NewLine);
Log("notification",notificationMessage );
NotificationLogged(new NotificationMessage(sender, shortMessage, detailedMessage,title));
if (NotificationLogged != null)
{
NotificationLogged(new NotificationMessage(sender, shortMessage, detailedMessage, title));
}
else
{
notifications.Add(new NotificationMessage(sender, shortMessage, detailedMessage, title));
}
}


Expand Down Expand Up @@ -301,6 +322,14 @@ internal void ResetWarning()
}
}

/// <summary>
/// Clear any notifications after displaying them.
/// </summary>
public void ClearStartupNotifications()
{
notifications.Clear();
}

/// <summary>
/// Log a message
/// </summary>
Expand All @@ -316,6 +345,11 @@ public void Log(string message)
/// <param name="e">Exception to log</param>
public void Log(Exception e)
{
var le = e as LibraryLoadFailedException;
if (le != null)
{
LogNotification(le.Source, le.ToString(), le.Message, le.Reason);
}
Log(e.GetType() + ":", LogLevel.Console);
Log(e.Message, LogLevel.Console);
Log(e.StackTrace, LogLevel.Console);
Expand Down
11 changes: 6 additions & 5 deletions src/DynamoCore/Models/DynamoModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -966,10 +966,11 @@ void UpdateManager_Log(LogEventArgs args)
/// <param name="e"></param>
private void LibraryLoaded(object sender, LibraryServices.LibraryLoadedEventArgs e)
{
string newLibrary = e.LibraryPath;

// Load all functions defined in that library.
AddZeroTouchNodesToSearch(LibraryServices.GetFunctionGroups(newLibrary));
foreach (var newLibrary in e.LibraryPaths)
{
// Load all functions defined in that library.
AddZeroTouchNodesToSearch(LibraryServices.GetFunctionGroups(newLibrary));
}
}

/// <summary>
Expand Down Expand Up @@ -1252,7 +1253,7 @@ internal void LoadNodeLibrary(Assembly assem)
{
if (!NodeModelAssemblyLoader.ContainsNodeModelSubType(assem))
{
LibraryServices.ImportLibrary(assem.Location);
LibraryServices.LoadNodeLibrary(assem.Location, false);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ internal void DownloadAndInstall(PackageDownloadHandle packageDownloadHandle, st
if (packageDownloadHandle.Extract(DynamoViewModel.Model, downloadPath, out dynPkg))
{
var p = Package.FromDirectory(dynPkg.RootDirectory, DynamoViewModel.Model.Logger);
pmExtension.PackageLoader.Load(p);
pmExtension.PackageLoader.LoadPackages(new List<Package> {p});

packageDownloadHandle.DownloadState = PackageDownloadHandle.State.Installed;
}
Expand Down
Loading