You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2019/04/11 07:02:14 UTC
[ignite] branch master updated: IGNITE-11690 .NET: Fix peer
assembly loading endless loop when assembly can't be found on any node
This is an automated email from the ASF dual-hosted git repository.
ptupitsyn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 313ae88 IGNITE-11690 .NET: Fix peer assembly loading endless loop when assembly can't be found on any node
313ae88 is described below
commit 313ae8863b722dd06ed96c45595aee6244497705
Author: Aleksandr Shapkin <14...@users.noreply.github.com>
AuthorDate: Thu Apr 11 10:02:04 2019 +0300
IGNITE-11690 .NET: Fix peer assembly loading endless loop when assembly can't be found on any node
#6427
---
.../Deployment/PeerAssemblyLoadingTest.cs | 37 +++++++++++++++++
.../Impl/Deployment/GetAssemblyFunc.cs | 11 ++++--
.../Impl/Deployment/PeerAssemblyResolver.cs | 46 +++++++++++++++++++++-
3 files changed, 88 insertions(+), 6 deletions(-)
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/PeerAssemblyLoadingTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/PeerAssemblyLoadingTest.cs
index da896dd..23be6dc 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/PeerAssemblyLoadingTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/PeerAssemblyLoadingTest.cs
@@ -26,6 +26,7 @@ namespace Apache.Ignite.Core.Tests.Deployment
using Apache.Ignite.Core.Deployment;
using Apache.Ignite.Core.Impl;
using Apache.Ignite.Core.Impl.Common;
+ using Apache.Ignite.Core.Impl.Deployment;
using Apache.Ignite.Core.Tests.Process;
using Apache.Ignite.NLog;
using NUnit.Framework;
@@ -217,6 +218,42 @@ namespace Apache.Ignite.Core.Tests.Deployment
}
/// <summary>
+ /// Tests that we are not entering endless loop while resolving an assembly from one node to another
+ /// https://issues.apache.org/jira/browse/IGNITE-11690
+ /// </summary>
+ [Test]
+ public void TestMissingAssemblyResolutionWithEnabledPeerLoadingFlag()
+ {
+ // We need to simulate two nodes that will be interacted with each other.
+ Ignition.Start(GetConfig());
+ var ignite = Ignition.Start(GetConfig());
+
+ // Create separate thread in order to avoid program block due to the endless loop.
+ var workerThread = new Thread(() =>
+ {
+ PeerAssemblyResolver.LoadAssemblyAndGetType("Unavailable.Assembly, unavailable, Ver=1",
+ (IIgniteInternal) ignite, Guid.Empty);
+ });
+ workerThread.Start();
+
+ bool isAssemblyResolved = workerThread.Join(TimeSpan.FromSeconds(10));
+ if (!isAssemblyResolved)
+ {
+ // Ignite instances should be disposed in TearDown method.
+ workerThread.Abort();
+ }
+
+ Assert.IsTrue(isAssemblyResolved, "Execution cancelled by timeout.");
+ }
+
+ private static IgniteConfiguration GetConfig()
+ {
+ var cfg = TestUtils.GetTestConfiguration(null, Guid.NewGuid().ToString());
+ cfg.PeerAssemblyLoadingMode = PeerAssemblyLoadingMode.CurrentAppDomain;
+ return cfg;
+ }
+
+ /// <summary>
/// Tears down the test.
/// </summary>
[TearDown]
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/GetAssemblyFunc.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/GetAssemblyFunc.cs
index 8f0c266..38fa6e6 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/GetAssemblyFunc.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/GetAssemblyFunc.cs
@@ -72,11 +72,14 @@ namespace Apache.Ignite.Core.Impl.Deployment
// Assembly may be present but not loaded - attempt to load into main context.
try
{
- asm = Assembly.Load(arg.AssemblyName);
-
- if (asm != null)
+ using (PeerAssemblyResolver.Disable())
{
- return new AssemblyRequestResult(AssemblyLoader.GetAssemblyBytes(asm), null);
+ asm = Assembly.Load(arg.AssemblyName);
+
+ if (asm != null)
+ {
+ return new AssemblyRequestResult(AssemblyLoader.GetAssemblyBytes(asm), null);
+ }
}
}
catch (FileNotFoundException)
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/PeerAssemblyResolver.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/PeerAssemblyResolver.cs
index a9e07d9..f0c221d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/PeerAssemblyResolver.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/PeerAssemblyResolver.cs
@@ -43,9 +43,9 @@ namespace Apache.Ignite.Core.Impl.Deployment
{
Debug.Assert(ignite != null);
- _handler = (sender, args) => GetAssembly(ignite, args.Name, originNodeId);
+ _handler = (sender, args) => RemoteAssemblyLoadingBlock.IsActive ? null : GetAssembly(ignite, args.Name, originNodeId);
- // AssemblyResolve handler is called only when aseembly can't be found via normal lookup,
+ // AssemblyResolve handler is called only when assembly can't be found via normal lookup,
// so we won't end up loading assemblies that are already present.
AppDomain.CurrentDomain.AssemblyResolve += _handler;
}
@@ -210,5 +210,47 @@ namespace Apache.Ignite.Core.Impl.Deployment
return null;
}
}
+
+ /// <summary>
+ /// Special class that indicates that there is no need in remote assembly request.
+ /// </summary>
+ private sealed class RemoteAssemblyLoadingBlock : IDisposable
+ {
+ /** Block status. */
+ [ThreadStatic]
+ private static bool _isActive;
+
+ /// <summary>
+ /// Gets the block status.
+ /// </summary>
+ public static bool IsActive
+ {
+ get { return _isActive; }
+ }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ public RemoteAssemblyLoadingBlock()
+ {
+ _isActive = true;
+ }
+
+ /** <inheritdoc /> */
+ public void Dispose()
+ {
+ _isActive = false;
+ }
+ }
+
+ /// <summary>
+ /// Disable remote assembly loading, default functionality will be used instead.
+ /// This is useful to prevent cycled resolution, for sample consider <see cref="GetAssemblyFunc" />.
+ /// </summary>
+ /// <returns></returns>
+ public static IDisposable Disable()
+ {
+ return new RemoteAssemblyLoadingBlock();
+ }
}
}