public IDataEngine GetEngine(string tenantId, string scopeId)
        {
            if (string.IsNullOrEmpty(tenantId))
            {
                throw new ArgumentNullException("tenantId");
            }

            if (string.IsNullOrEmpty(scopeId))
            {
                throw new ArgumentNullException("scopeId");
            }

            // avoid using GetOrAdd because it may invoke factory method multiple times
            ConcurrentDictionary<string, IDataEngine> tenantEngines;
            if (!m_engines.TryGetValue(tenantId, out tenantEngines))
            {
                lock (m_engines)
                {
                    if (!m_engines.TryGetValue(tenantId, out tenantEngines))
                    {
                        tenantEngines = new ConcurrentDictionary<string, IDataEngine>();
                        if (!m_engines.TryAdd(tenantId, tenantEngines))
                        {
                            throw new Exception("Failed to add tenant-specific cache of engines for tenant " + tenantId);
                        }
                    }

                    if (tenantEngines == null)
                    {
                        throw new Exception("tenantEngines is null, tenant " + tenantId);
                    }
                }
            }

            // avoid using GetOrAdd because it may invoke factory method multiple times
            IDataEngine engine;
            if (!tenantEngines.TryGetValue(scopeId, out engine))
            {
                lock (tenantEngines)
                {
                    if (!tenantEngines.TryGetValue(scopeId, out engine))
                    {
                        var engineCount = GetTotalEnginesCount();
                        if (engineCount > MaxTotalEnginesCount)
                        {
                            new Task(x => ForceExpireOneEngine((DataEngineCache) x), this).Start();
                        }

                        m_tracer.InfoFormat("Creating new engine for tenant {0}, scope {1}", tenantId, scopeId);
                        var factory = ObjectFactory.GetNamedInstance<IStorageDriverFactory>(m_storageDriverKey);
                        var storageDriver = factory.Create();
                        storageDriver.Initialize(m_tracer, GetDriverConnectionConfig(scopeId, factory));

                        engine = new DataEngine(m_tracer, m_instanceName, m_maxEngineConcurrency, storageDriver, RequireDescriptor(storageDriver));

                        if (!tenantEngines.TryAdd(scopeId, engine))
                        {
                            throw new Exception(string.Format("Failed to add new engine for tenant {0}, scope {1}", tenantId, scopeId));
                        }
                    }

                    if (engine == null)
                    {
                        throw new Exception(string.Format("Engine is null for tenant {0}, scope {1}", tenantId, scopeId));
                    }
                }
            }

            return engine;
        }
 public TestableEngineCache(DataEngine engine)
 {
     Engine = engine;
 }
Exemple #3
0
        public IDataEngine GetEngine(string tenantId, string scopeId)
        {
            if (string.IsNullOrEmpty(tenantId))
            {
                throw new ArgumentNullException("tenantId");
            }

            if (string.IsNullOrEmpty(scopeId))
            {
                throw new ArgumentNullException("scopeId");
            }

            // avoid using GetOrAdd because it may invoke factory method multiple times
            ConcurrentDictionary <string, IDataEngine> tenantEngines;

            if (!m_engines.TryGetValue(tenantId, out tenantEngines))
            {
                lock (m_engines)
                {
                    if (!m_engines.TryGetValue(tenantId, out tenantEngines))
                    {
                        tenantEngines = new ConcurrentDictionary <string, IDataEngine>();
                        if (!m_engines.TryAdd(tenantId, tenantEngines))
                        {
                            throw new Exception("Failed to add tenant-specific cache of engines for tenant " + tenantId);
                        }
                    }

                    if (tenantEngines == null)
                    {
                        throw new Exception("tenantEngines is null, tenant " + tenantId);
                    }
                }
            }

            // avoid using GetOrAdd because it may invoke factory method multiple times
            IDataEngine engine;

            if (!tenantEngines.TryGetValue(scopeId, out engine))
            {
                lock (tenantEngines)
                {
                    if (!tenantEngines.TryGetValue(scopeId, out engine))
                    {
                        var engineCount = GetTotalEnginesCount();
                        if (engineCount > MaxTotalEnginesCount)
                        {
                            new Task(x => ForceExpireOneEngine((DataEngineCache)x), this).Start();
                        }

                        m_tracer.InfoFormat("Creating new engine for tenant {0}, scope {1}", tenantId, scopeId);
                        var factory       = ObjectFactory.GetNamedInstance <IStorageDriverFactory>(m_storageDriverKey);
                        var storageDriver = factory.Create();
                        storageDriver.Initialize(m_tracer, GetDriverConnectionConfig(scopeId, factory));

                        engine = new DataEngine(m_tracer, m_instanceName, m_maxEngineConcurrency, storageDriver, RequireDescriptor(storageDriver));

                        if (!tenantEngines.TryAdd(scopeId, engine))
                        {
                            throw new Exception(string.Format("Failed to add new engine for tenant {0}, scope {1}", tenantId, scopeId));
                        }
                    }

                    if (engine == null)
                    {
                        throw new Exception(string.Format("Engine is null for tenant {0}, scope {1}", tenantId, scopeId));
                    }
                }
            }

            return(engine);
        }