Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id B1E0A200C5A for ; Tue, 18 Apr 2017 15:45:51 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id B0807160BC4; Tue, 18 Apr 2017 13:45:51 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 72CCC160BC5 for ; Tue, 18 Apr 2017 15:45:50 +0200 (CEST) Received: (qmail 37189 invoked by uid 500); 18 Apr 2017 13:45:49 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 36230 invoked by uid 99); 18 Apr 2017 13:45:47 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 18 Apr 2017 13:45:47 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 664E3E185A; Tue, 18 Apr 2017 13:45:47 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: agoncharuk@apache.org To: commits@ignite.apache.org Date: Tue, 18 Apr 2017 13:46:20 -0000 Message-Id: <61963d1a37484d5dbc914eb677747c4e@git.apache.org> In-Reply-To: <423a62809cc54308a60a142c82b25f2f@git.apache.org> References: <423a62809cc54308a60a142c82b25f2f@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [35/62] [abbrv] ignite git commit: IGNITE-4856 .NET: StopAll on AppDomain unload archived-at: Tue, 18 Apr 2017 13:45:51 -0000 IGNITE-4856 .NET: StopAll on AppDomain unload This closes #1732 Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/99842bf1 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/99842bf1 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/99842bf1 Branch: refs/heads/ignite-4938 Commit: 99842bf1986b4cafc7d15ddee7dd2322e65b9c10 Parents: 323e387 Author: Pavel Tupitsyn Authored: Tue Apr 18 10:41:19 2017 +0300 Committer: Pavel Tupitsyn Committed: Tue Apr 18 10:41:19 2017 +0300 ---------------------------------------------------------------------- .../ConsoleRedirectTest.cs | 5 +- .../IgniteConfigurationSerializerTest.cs | 3 +- .../IgniteStartStopTest.cs | 24 +++++++ .../Apache.Ignite.Core/IgniteConfiguration.cs | 13 ++++ .../IgniteConfigurationSection.xsd | 5 ++ .../dotnet/Apache.Ignite.Core/Ignition.cs | 67 ++++++++++++++++++-- 6 files changed, 107 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/99842bf1/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ConsoleRedirectTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ConsoleRedirectTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ConsoleRedirectTest.cs index 5a59a37..3ab5ed3 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ConsoleRedirectTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ConsoleRedirectTest.cs @@ -166,11 +166,12 @@ namespace Apache.Ignite.Core.Tests { public void Run() { - var ignite = Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) + Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) { IgniteInstanceName = "newDomainGrid" }); - Ignition.Stop(ignite.Name, true); + + // Will be stopped automatically on domain unload. } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/99842bf1/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs index cba5647..4a197e5 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs @@ -65,7 +65,7 @@ namespace Apache.Ignite.Core.Tests [Test] public void TestPredefinedXml() { - var xml = @" + var xml = @" 127.1.1.1 @@ -158,6 +158,7 @@ namespace Apache.Ignite.Core.Tests Assert.IsFalse(cfg.BinaryConfiguration.CompactFooter); Assert.AreEqual(new[] {42, EventType.TaskFailed, EventType.JobFinished}, cfg.IncludedEventTypes); Assert.AreEqual(@"c:\myconfig.xml", cfg.SpringConfigUrl); + Assert.IsTrue(cfg.AutoGenerateIgniteInstanceName); Assert.AreEqual("secondCache", cfg.CacheConfiguration.Last().Name); http://git-wip-us.apache.org/repos/asf/ignite/blob/99842bf1/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs index b863308..bc40f48 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteStartStopTest.cs @@ -20,6 +20,7 @@ namespace Apache.Ignite.Core.Tests using System; using System.Collections.Generic; using System.IO; + using System.Linq; using System.Threading; using System.Threading.Tasks; using Apache.Ignite.Core.Common; @@ -104,12 +105,15 @@ namespace Apache.Ignite.Core.Tests var grid1 = Ignition.Start(cfg); Assert.AreEqual("grid1", grid1.Name); + Assert.AreSame(grid1, Ignition.GetIgnite()); + Assert.AreSame(grid1, Ignition.GetAll().Single()); cfg.SpringConfigUrl = cfgs[1]; var grid2 = Ignition.Start(cfg); Assert.AreEqual("grid2", grid2.Name); + Assert.Throws(() => Ignition.GetIgnite()); cfg.SpringConfigUrl = cfgs[2]; @@ -124,9 +128,12 @@ namespace Apache.Ignite.Core.Tests Assert.AreSame(grid2, Ignition.TryGetIgnite("grid2")); Assert.AreSame(grid3, Ignition.GetIgnite(null)); + Assert.AreSame(grid3, Ignition.GetIgnite()); Assert.AreSame(grid3, Ignition.TryGetIgnite(null)); Assert.AreSame(grid3, Ignition.TryGetIgnite()); + Assert.AreEqual(new[] {grid3, grid1, grid2}, Ignition.GetAll().OrderBy(x => x.Name).ToArray()); + Assert.Throws(() => Ignition.GetIgnite("invalid_name")); Assert.IsNull(Ignition.TryGetIgnite("invalid_name")); @@ -187,6 +194,23 @@ namespace Apache.Ignite.Core.Tests } /// + /// Tests automatic grid name generation. + /// + [Test] + public void TestStartUniqueName() + { + var cfg = TestUtils.GetTestConfiguration(); + cfg.AutoGenerateIgniteInstanceName = true; + + Ignition.Start(cfg); + Assert.IsNotNull(Ignition.GetIgnite()); + + Ignition.Start(cfg); + Assert.Throws(() => Ignition.GetIgnite()); + Assert.AreEqual(2, Ignition.GetAll().Count); + } + + /// /// /// [Test] http://git-wip-us.apache.org/repos/asf/ignite/blob/99842bf1/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs index a22c568..24a4364 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs @@ -518,6 +518,7 @@ namespace Apache.Ignite.Core JvmInitialMemoryMb = cfg.JvmInitialMemoryMb; JvmMaxMemoryMb = cfg.JvmMaxMemoryMb; PluginConfigurations = cfg.PluginConfigurations; + AutoGenerateIgniteInstanceName = cfg.AutoGenerateIgniteInstanceName; } /// @@ -530,6 +531,18 @@ namespace Apache.Ignite.Core public string IgniteInstanceName { get; set; } /// + /// Gets or sets a value indicating whether unique should be generated. + /// + /// Set this to true in scenarios where new node should be started regardless of other nodes present within + /// current process. In particular, this setting is useful is ASP.NET and IIS environments, where AppDomains + /// are loaded and unloaded within a single process during application restarts. Ignite stops all nodes + /// on unload, however, IIS does not wait for previous AppDomain to unload before + /// starting up a new one, which may cause "Ignite instance with this name has already been started" errors. + /// This setting solves the issue. + /// + public bool AutoGenerateIgniteInstanceName { get; set; } + + /// /// Gets or sets optional local instance name. /// /// This name only works locally and has no effect on topology. http://git-wip-us.apache.org/repos/asf/ignite/blob/99842bf1/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd index b503338..1d2a948 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd @@ -1152,6 +1152,11 @@ Local Ignite instance name to be used with Ignition.GetIgnite. + + + Generate unique igniteInstanceName automatically. + + Path jvm.dll file. If not set, it's location will be determined using JAVA_HOME environment variable. If path is neither set nor determined automatically, an exception will be thrown. http://git-wip-us.apache.org/repos/asf/ignite/blob/99842bf1/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs index d2be92a..cdb1064 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Ignition.cs @@ -85,6 +85,7 @@ namespace Apache.Ignite.Core static Ignition() { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; + AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload; } /// @@ -231,6 +232,11 @@ namespace Apache.Ignite.Core var gridName = cfg.IgniteInstanceName; + if (cfg.AutoGenerateIgniteInstanceName) + { + gridName = (gridName ?? "ignite-instance-") + Guid.NewGuid(); + } + // 3. Create startup object which will guide us through the rest of the process. _startup = new Startup(cfg, cbs); @@ -576,15 +582,49 @@ namespace Apache.Ignite.Core } /// - /// Gets an instance of default no-name grid. Note that - /// caller of this method should not assume that it will return the same - /// instance every time. + /// Gets the default Ignite instance with null name, or an instance with any name when there is only one. + /// + /// Note that caller of this method should not assume that it will return the same instance every time. /// - /// An instance of default no-name grid. - /// When there is no Ignite instance with specified name. + /// Default Ignite instance. + /// When there is no matching Ignite instance. public static IIgnite GetIgnite() { - return GetIgnite(null); + lock (SyncRoot) + { + if (Nodes.Count == 0) + { + throw new IgniteException("Failed to get default Ignite instance: " + + "there are no instances started."); + } + + if (Nodes.Count == 1) + { + return Nodes.Single().Value; + } + + Ignite result; + + if (Nodes.TryGetValue(new NodeKey(null), out result)) + { + return result; + } + + throw new IgniteException(string.Format("Failed to get default Ignite instance: " + + "there are {0} instances started, and none of them has null name.", Nodes.Count)); + } + } + + /// + /// Gets all started Ignite instances. + /// + /// All Ignite instances. + public static ICollection GetAll() + { + lock (SyncRoot) + { + return Nodes.Values.ToArray(); + } } /// @@ -685,9 +725,22 @@ namespace Apache.Ignite.Core { return LoadedAssembliesResolver.Instance.GetAssembly(args.Name); } + + /// + /// Handles the DomainUnload event of the CurrentDomain control. + /// + /// The source of the event. + /// The instance containing the event data. + private static void CurrentDomain_DomainUnload(object sender, EventArgs e) + { + // If we don't stop Ignite.NET on domain unload, + // we end up with broken instances in Java (invalid callbacks, etc). + // IIS, in particular, is known to unload and reload domains within the same process. + StopAll(true); + } /// - /// Grid key. + /// Grid key. Workaround for non-null key requirement in Dictionary. /// private class NodeKey {