ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From agoncha...@apache.org
Subject [01/34] ignite git commit: IGNITE-5356 .NET: Fix runtime dependency loading with peer deployment
Date Mon, 05 Jun 2017 09:05:37 GMT
Repository: ignite
Updated Branches:
  refs/heads/ignite-5267 b47db106d -> c6f6319ea


IGNITE-5356 .NET: Fix runtime dependency loading with peer deployment

This closes #2063


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/79d45e34
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/79d45e34
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/79d45e34

Branch: refs/heads/ignite-5267
Commit: 79d45e34335d2286bf382d7a8a49a71661f26f79
Parents: 34409fd
Author: Pavel Tupitsyn <ptupitsyn@apache.org>
Authored: Fri Jun 2 12:59:58 2017 +0300
Committer: Pavel Tupitsyn <ptupitsyn@apache.org>
Committed: Fri Jun 2 12:59:58 2017 +0300

----------------------------------------------------------------------
 .../Apache.Ignite.Core.Tests.TestDll.csproj     |  1 +
 .../TestExtensions.cs                           | 35 ++++++++++++++++++++
 .../Apache.Ignite.Core.Tests.csproj             |  1 +
 .../Deployment/PeerAssemblyLoadingTest.cs       | 13 ++++++++
 .../Deployment/RuntimeDependencyFunc.cs         | 34 +++++++++++++++++++
 .../Impl/Compute/ComputeJobHolder.cs            |  6 +++-
 .../Impl/Deployment/GetAssemblyFunc.cs          | 28 ++++++++++++++++
 .../Impl/Deployment/PeerAssemblyResolver.cs     | 26 ++++++++++++++-
 .../Apache.Ignite.Core/Impl/ExceptionUtils.cs   |  1 +
 9 files changed, 143 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Apache.Ignite.Core.Tests.TestDll.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Apache.Ignite.Core.Tests.TestDll.csproj
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Apache.Ignite.Core.Tests.TestDll.csproj
index db7a4d1..0f9e13b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Apache.Ignite.Core.Tests.TestDll.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/Apache.Ignite.Core.Tests.TestDll.csproj
@@ -42,6 +42,7 @@
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="TestClass.cs" />
+    <Compile Include="TestExtensions.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="Apache.Ignite.Core.Tests.TestDll.snk" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/TestExtensions.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/TestExtensions.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/TestExtensions.cs
new file mode 100644
index 0000000..65a1484
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.TestDll/TestExtensions.cs
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.TestDll
+{
+    using System.Linq;
+
+    /// <summary>
+    /// Extension methods for tests.
+    /// </summary>
+    public static class TestExtensions
+    {
+        /// <summary>
+        /// Reverses the string.
+        /// </summary>
+        public static string ReverseString(this string str)
+        {
+            return new string(str.Reverse().ToArray());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index d459d2a..12b0b6a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -120,6 +120,7 @@
     <Compile Include="Collections\ReadOnlyCollectionTest.cs" />
     <Compile Include="Collections\ReadOnlyDictionaryTest.cs" />
     <Compile Include="Common\IgniteGuidTest.cs" />
+    <Compile Include="Deployment\RuntimeDependencyFunc.cs" />
     <Compile Include="Log\ConcurrentMemoryTarget.cs" />
     <Compile Include="Log\DefaultLoggerTest.cs" />
     <Compile Include="Log\Log4NetLoggerTest.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/PeerAssemblyLoadingTest.cs
----------------------------------------------------------------------
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 27a2d65..8245333 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/PeerAssemblyLoadingTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/PeerAssemblyLoadingTest.cs
@@ -118,6 +118,19 @@ namespace Apache.Ignite.Core.Tests.Deployment
         }
 
         /// <summary>
+        /// Tests the runtime dependency: AssemblyResolve event fires during job execution,
+        /// not during deserialization. This happens with static classes, for example.
+        /// </summary>
+        [Test]
+        public void TestRuntimeDependency()
+        {
+            TestDeployment(remoteCompute =>
+            {
+                Assert.AreEqual("dcba", remoteCompute.Apply(new RuntimeDependencyFunc(),
"abcd"));
+            });
+        }
+
+        /// <summary>
         /// Tests the peer deployment.
         /// </summary>
         public static void TestDeployment(Action<ICompute> test, bool enablePeerDeployment
= true)

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/RuntimeDependencyFunc.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/RuntimeDependencyFunc.cs
b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/RuntimeDependencyFunc.cs
new file mode 100644
index 0000000..5b076a9
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Deployment/RuntimeDependencyFunc.cs
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Tests.Deployment
+{
+    using Apache.Ignite.Core.Compute;
+    using Apache.Ignite.Core.Tests.TestDll;
+
+    /// <summary>
+    /// Func with runtime dependency via extension method.
+    /// </summary>
+    public class RuntimeDependencyFunc : IComputeFunc<string, string>
+    {
+        /** <inheritdoc /> */
+        public string Invoke(string arg)
+        {
+            return arg.ReverseString();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
index 314814d..120d074 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Compute/ComputeJobHolder.cs
@@ -26,6 +26,7 @@ namespace Apache.Ignite.Core.Impl.Compute
     using Apache.Ignite.Core.Impl.Binary.IO;
     using Apache.Ignite.Core.Impl.Cluster;
     using Apache.Ignite.Core.Impl.Compute.Closure;
+    using Apache.Ignite.Core.Impl.Deployment;
     using Apache.Ignite.Core.Impl.Memory;
     using Apache.Ignite.Core.Impl.Resource;
 
@@ -102,7 +103,10 @@ namespace Apache.Ignite.Core.Impl.Compute
             object res;
             bool success;
 
-            Execute0(cancel, out res, out success);
+            using (PeerAssemblyResolver.GetInstance(_ignite, Guid.Empty))
+            {
+                Execute0(cancel, out res, out success);
+            }
 
             // 2. Try writing result to the stream.
             ClusterGroupImpl prj = _ignite.ClusterGroup;

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/GetAssemblyFunc.cs
----------------------------------------------------------------------
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 6d54dbf..8f0c266 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/GetAssemblyFunc.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/GetAssemblyFunc.cs
@@ -17,7 +17,10 @@
  
 namespace Apache.Ignite.Core.Impl.Deployment
 {
+    using System;
     using System.Diagnostics;
+    using System.IO;
+    using System.Reflection;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Common;
     using Apache.Ignite.Core.Compute;
@@ -58,6 +61,7 @@ namespace Apache.Ignite.Core.Impl.Deployment
                 return new AssemblyRequestResult(AssemblyLoader.GetAssemblyBytes(asm), null);
             }
 
+            // Try cached assemblies.
             var bytes = AssemblyLoader.GetAssemblyBytes(arg.AssemblyName);
 
             if (bytes != null)
@@ -65,6 +69,30 @@ namespace Apache.Ignite.Core.Impl.Deployment
                 return new AssemblyRequestResult(bytes, null);
             }
 
+            // Assembly may be present but not loaded - attempt to load into main context.
+            try
+            {
+                asm = Assembly.Load(arg.AssemblyName);
+
+                if (asm != null)
+                {
+                    return new AssemblyRequestResult(AssemblyLoader.GetAssemblyBytes(asm),
null);
+                }
+            }
+            catch (FileNotFoundException)
+            {
+                return null;
+            }
+            catch (FileLoadException ex)
+            {
+                return new AssemblyRequestResult(null, string.Format("Failed to load assembly:
{0} ({1})", asm, ex));
+            }
+
+            catch (BadImageFormatException ex)
+            {
+                return new AssemblyRequestResult(null, string.Format("Failed to load assembly:
{0} ({1})", asm, ex));
+            }
+
             return null;
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/PeerAssemblyResolver.cs
----------------------------------------------------------------------
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 607ca57..b81bbbc 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/PeerAssemblyResolver.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Deployment/PeerAssemblyResolver.cs
@@ -45,6 +45,8 @@ namespace Apache.Ignite.Core.Impl.Deployment
 
             _handler = (sender, args) => GetAssembly(ignite, args.Name, originNodeId);
 
+            // AssemblyResolve handler is called only when aseembly can't be found via normal
lookup,
+            // so we won't end up loading assemblies that are already present.
             AppDomain.CurrentDomain.AssemblyResolve += _handler;
         }
 
@@ -55,6 +57,19 @@ namespace Apache.Ignite.Core.Impl.Deployment
         }
 
         /// <summary>
+        /// Gets an instance of <see cref="PeerAssemblyResolver"/> when peer loading
is enabled; otherwise null.
+        /// </summary>
+        public static PeerAssemblyResolver GetInstance(Ignite ignite, Guid originNodeId)
+        {
+            if (ignite == null || ignite.Configuration.PeerAssemblyLoadingMode == PeerAssemblyLoadingMode.Disabled)
+            {
+                return null;
+            }
+
+            return new PeerAssemblyResolver(ignite, originNodeId);
+        }
+
+        /// <summary>
         /// Gets the assembly from remote nodes.
         /// </summary>
         /// <param name="typeName">Assembly-qualified type name.</param>
@@ -158,7 +173,10 @@ namespace Apache.Ignite.Core.Impl.Deployment
         /// </summary>
         private static IEnumerable<Guid> GetDotNetNodes(IIgnite ignite, Guid originNodeId)
         {
-            yield return originNodeId;
+            if (originNodeId != Guid.Empty)
+            {
+                yield return originNodeId;
+            }
 
             foreach (var node in ignite.GetCluster().ForDotNet().ForRemotes().GetNodes())
             {
@@ -184,6 +202,12 @@ namespace Apache.Ignite.Core.Impl.Deployment
                 // Normal situation: node has left.
                 return null;
             }
+            catch (AggregateException aex)
+            {
+                // Normal situation: node has left.
+                aex.Handle(e => e is ClusterGroupEmptyException);
+                return null;
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/79d45e34/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
index e2d61d7..dd70f5a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/ExceptionUtils.cs
@@ -75,6 +75,7 @@ namespace Apache.Ignite.Core.Impl
 
             // Cluster exceptions.
             Exs["org.apache.ignite.cluster.ClusterGroupEmptyException"] = (c, m, e, i) =>
new ClusterGroupEmptyException(m, e);
+            Exs["org.apache.ignite.internal.cluster.ClusterGroupEmptyCheckedException"] =
(c, m, e, i) => new ClusterGroupEmptyException(m, e);
             Exs["org.apache.ignite.cluster.ClusterTopologyException"] = (c, m, e, i) =>
new ClusterTopologyException(m, e);
 
             // Compute exceptions.


Mime
View raw message