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 2016/11/18 17:33:00 UTC

ignite git commit: IGNITE-4246 .NET: Fix IgniteDbConfiguration initialization

Repository: ignite
Updated Branches:
  refs/heads/master a9715424c -> 3b01983c5


IGNITE-4246 .NET: Fix IgniteDbConfiguration initialization

This closes #1249


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

Branch: refs/heads/master
Commit: 3b01983c5f5e63b15101253f802331bd0072e31a
Parents: a971542
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Nov 18 20:32:47 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Nov 18 20:32:47 2016 +0300

----------------------------------------------------------------------
 .../EntityFrameworkCacheTest.cs                 |   9 +-
 .../IgniteDbConfiguration.cs                    | 108 ++++++++++++++++++-
 2 files changed, 111 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3b01983c/modules/platforms/dotnet/Apache.Ignite.EntityFramework.Tests/EntityFrameworkCacheTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.EntityFramework.Tests/EntityFrameworkCacheTest.cs b/modules/platforms/dotnet/Apache.Ignite.EntityFramework.Tests/EntityFrameworkCacheTest.cs
index 5fbd8fe..8b9f955 100644
--- a/modules/platforms/dotnet/Apache.Ignite.EntityFramework.Tests/EntityFrameworkCacheTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.EntityFramework.Tests/EntityFrameworkCacheTest.cs
@@ -662,7 +662,7 @@ namespace Apache.Ignite.EntityFramework.Tests
         [Category(TestUtils.CategoryIntensive)]
         public void TestOldEntriesCleanupMultithreaded()
         {
-            TestUtils.RunMultiThreaded(CreateRemoveBlog, 4, 20);
+            TestUtils.RunMultiThreaded(CreateRemoveBlog, 4, 10);
 
             // Wait for the cleanup to complete.
             Thread.Sleep(500);
@@ -822,7 +822,12 @@ namespace Apache.Ignite.EntityFramework.Tests
         {
             public MyDbConfiguration() : base(Ignition.GetIgnite(), null, null, Policy)
             {
-                // No-op.
+                var ex = Assert.Throws<ArgumentException>(() => InitializeIgniteCaching(
+                    this, Ignition.GetIgnite(), null, null, Policy));
+
+                Assert.IsTrue(ex.Message.StartsWith("'dbConfiguration' argument is invalid: " +
+                                                    "IgniteDbConfiguration.InitializeIgniteCaching should not " +
+                                                    "be called for IgniteDbConfiguration instance."), ex.Message);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b01983c/modules/platforms/dotnet/Apache.Ignite.EntityFramework/IgniteDbConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.EntityFramework/IgniteDbConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.EntityFramework/IgniteDbConfiguration.cs
index c467f94..55ecd40 100644
--- a/modules/platforms/dotnet/Apache.Ignite.EntityFramework/IgniteDbConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.EntityFramework/IgniteDbConfiguration.cs
@@ -17,11 +17,16 @@
 
 namespace Apache.Ignite.EntityFramework
 {
+    using System;
     using System.Configuration;
     using System.Data.Entity;
     using System.Data.Entity.Core.Common;
+    using System.Data.Entity.Infrastructure.DependencyResolution;
+    using System.Data.Entity.Infrastructure.Interception;
+    using System.Diagnostics;
     using System.Diagnostics.CodeAnalysis;
     using System.Globalization;
+    using System.Reflection;
     using Apache.Ignite.Core;
     using Apache.Ignite.Core.Cache.Configuration;
     using Apache.Ignite.Core.Common;
@@ -55,6 +60,18 @@ namespace Apache.Ignite.EntityFramework
         private const string DataCacheSuffix = "_data";
 
         /// <summary>
+        /// DbConfiguration.AddInterceptor method.
+        /// </summary>
+        private static readonly MethodInfo AddInterceptorMethodInfo = 
+            typeof(DbConfiguration).GetMethod("AddInterceptor", BindingFlags.Instance | BindingFlags.NonPublic);
+
+        /// <summary>
+        /// DbConfiguration.AddInterceptor delegate.
+        /// </summary>
+        private static readonly Action<object, IDbInterceptor> AddInterceptorDelegate =
+            (dbConfig, interceptor) => AddInterceptorMethodInfo.Invoke(dbConfig, new object[] {interceptor});
+
+        /// <summary>
         /// Initializes a new instance of the <see cref="IgniteDbConfiguration"/> class.
         /// <para />
         /// This constructor uses default Ignite instance (with null <see cref="IgniteConfiguration.GridName"/>) 
@@ -156,6 +173,67 @@ namespace Apache.Ignite.EntityFramework
         {
             IgniteArgumentCheck.NotNull(ignite, "ignite");
 
+            InitializeIgniteCachingInternal(this, ignite, metaCacheConfiguration, dataCacheConfiguration, policy);
+        }
+
+        /// <summary>
+        /// Initializes Ignite caching for specified <see cref="DbConfiguration"/>.
+        /// This method should be used when it is not possible to use or inherit <see cref="IgniteDbConfiguration"/>.
+        /// </summary>
+        /// <param name="dbConfiguration"><see cref="DbConfiguration"/> instance to be initialized
+        /// for Ignite caching.</param>
+        /// <param name="ignite">The ignite instance to use.</param>
+        /// <param name="metaCacheConfiguration">
+        /// Configuration of the metadata cache which holds entity set information. Null for default configuration. 
+        /// <para />
+        /// This cache holds small amount of data, but should not lose entries. At least one backup recommended.
+        /// </param>
+        /// <param name="dataCacheConfiguration">
+        /// Configuration of the data cache which holds query results. Null for default configuration.
+        /// <para />
+        /// This cache tolerates lost data and can have no backups.
+        /// </param>
+        /// <param name="policy">The caching policy. Null for default <see cref="DbCachingPolicy" />.</param>
+        public static void InitializeIgniteCaching(DbConfiguration dbConfiguration, IIgnite ignite,
+            CacheConfiguration metaCacheConfiguration, CacheConfiguration dataCacheConfiguration,
+            IDbCachingPolicy policy)
+        {
+            IgniteArgumentCheck.NotNull(ignite, "ignite");
+            IgniteArgumentCheck.NotNull(dbConfiguration, "configuration");
+
+            IgniteArgumentCheck.Ensure(!(dbConfiguration is IgniteDbConfiguration), "dbConfiguration",
+                "IgniteDbConfiguration.InitializeIgniteCaching should not be called for IgniteDbConfiguration " +
+                "instance. This method should be used only when IgniteDbConfiguration can't be inherited.");
+
+            InitializeIgniteCachingInternal(dbConfiguration, ignite, metaCacheConfiguration, dataCacheConfiguration, 
+                policy);
+        }
+
+        /// <summary>
+        /// Initializes Ignite caching for specified <see cref="DbConfiguration"/>.
+        /// This method should be used when it is not possible to use or inherit <see cref="IgniteDbConfiguration"/>.
+        /// </summary>
+        /// <param name="dbConfiguration"><see cref="DbConfiguration"/> instance to be initialized
+        /// for Ignite caching.</param>
+        /// <param name="ignite">The ignite instance to use.</param>
+        /// <param name="metaCacheConfiguration">
+        /// Configuration of the metadata cache which holds entity set information. Null for default configuration. 
+        /// <para />
+        /// This cache holds small amount of data, but should not lose entries. At least one backup recommended.
+        /// </param>
+        /// <param name="dataCacheConfiguration">
+        /// Configuration of the data cache which holds query results. Null for default configuration.
+        /// <para />
+        /// This cache tolerates lost data and can have no backups.
+        /// </param>
+        /// <param name="policy">The caching policy. Null for default <see cref="DbCachingPolicy" />.</param>
+        private static void InitializeIgniteCachingInternal(DbConfiguration dbConfiguration, IIgnite ignite, 
+            CacheConfiguration metaCacheConfiguration, CacheConfiguration dataCacheConfiguration, 
+            IDbCachingPolicy policy)
+        {
+            Debug.Assert(ignite != null);
+            Debug.Assert(dbConfiguration != null);
+
             metaCacheConfiguration = metaCacheConfiguration ?? GetDefaultMetaCacheConfiguration();
             dataCacheConfiguration = dataCacheConfiguration ?? GetDefaultDataCacheConfiguration();
 
@@ -163,11 +241,33 @@ namespace Apache.Ignite.EntityFramework
 
             var txHandler = new DbTransactionInterceptor(efCache);
 
-            AddInterceptor(txHandler);
+            AddInterceptorDelegate(dbConfiguration, txHandler);
+
+            RegisterProviderServicesReplacer(dbConfiguration, policy, efCache, txHandler);
+        }
+
+        /// <summary>
+        /// Registers the provider services replacer.
+        /// </summary>
+        private static void RegisterProviderServicesReplacer(DbConfiguration config, 
+            IDbCachingPolicy policy, DbCache efCache, DbTransactionInterceptor txHandler)
+        {
+            EventHandler<DbConfigurationLoadedEventArgs> onLoaded = null;
+
+            onLoaded = (sender, args) =>
+            {
+                // Replace provider services for specific instance only and unsubscribe.
+                if (ReferenceEquals(config, sender))
+                {
+                    // SetProviderServices is not suitable. We should replace whatever provider there is with our proxy.
+                    args.ReplaceService<DbProviderServices>(
+                        (services, a) => new DbProviderServicesProxy(services, policy, efCache, txHandler));
+
+                    Loaded -= onLoaded;
+                }
+            };
 
-            // SetProviderServices is not suitable. We should replace whatever provider there is with our proxy.
-            Loaded += (sender, args) => args.ReplaceService<DbProviderServices>(
-                (services, a) => new DbProviderServicesProxy(services, policy, efCache, txHandler));
+            Loaded += onLoaded;
         }
 
         /// <summary>