예제 #1
0
        internal int Clear()
        {
            // must be multi-thread safe with competing calls by Clear and Prune via background thread
            // will return the number of connections in the group after clearing has finished

            // First, note the old collection and create a new collection to be used
            ConcurrentDictionary <DbConnectionPoolIdentity, DbConnectionPool> oldPoolCollection = null;

            lock (this)
            {
                if (_poolCollection.Count > 0)
                {
                    oldPoolCollection = _poolCollection;
                    _poolCollection   = new ConcurrentDictionary <DbConnectionPoolIdentity, DbConnectionPool>();
                }
            }

            // Then, if a new collection was created, release the pools from the old collection
            if (oldPoolCollection != null)
            {
                foreach (var entry in oldPoolCollection)
                {
                    DbConnectionPool pool = entry.Value;
                    if (pool != null)
                    {
                        DbConnectionFactory connectionFactory = pool.ConnectionFactory;
                        connectionFactory.QueuePoolForRelease(pool, true);
                    }
                }
            }

            // Finally, return the pool collection count - this may be non-zero if something was added while we were clearing
            return(_poolCollection.Count);
        }
예제 #2
0
        internal bool Prune()
        {
            // must only call from DbConnectionFactory.PruneConnectionPoolGroups on background timer thread
            // must lock(DbConnectionFactory._connectionPoolGroups.SyncRoot) before calling ReadyToRemove
            //     to avoid conflict with DbConnectionFactory.CreateConnectionPoolGroup replacing pool entry
            lock (this)
            {
                if (_poolCollection.Count > 0)
                {
                    var newPoolCollection = new ConcurrentDictionary <DbConnectionPoolIdentity, DbConnectionPool>();

                    foreach (var entry in _poolCollection)
                    {
                        DbConnectionPool pool = entry.Value;
                        if (pool != null)
                        {
                            // Actually prune the pool if there are no connections in the pool and no errors occurred.
                            // Empty pool during pruning indicates zero or low activity, but
                            //  an error state indicates the pool needs to stay around to
                            //  throttle new connection attempts.
                            if ((!pool.ErrorOccurred) && (0 == pool.Count))
                            {
                                // Order is important here.  First we remove the pool
                                // from the collection of pools so no one will try
                                // to use it while we're processing and finally we put the
                                // pool into a list of pools to be released when they
                                // are completely empty.
                                DbConnectionFactory connectionFactory = pool.ConnectionFactory;

                                connectionFactory.QueuePoolForRelease(pool, false);
                            }
                            else
                            {
                                newPoolCollection.TryAdd(entry.Key, entry.Value);
                            }
                        }
                    }
                    _poolCollection = newPoolCollection;
                }

                // must be pruning thread to change state and no connections
                // otherwise pruning thread risks making entry disabled soon after user calls ClearPool
                if (0 == _poolCollection.Count)
                {
                    if (PoolGroupStateActive == _state)
                    {
                        _state = PoolGroupStateIdle;
                    }
                    else if (PoolGroupStateIdle == _state)
                    {
                        _state = PoolGroupStateDisabled;
                    }
                }
                return(PoolGroupStateDisabled == _state);
            }
        }
예제 #3
0
 private bool ClearInternal(bool clearing)
 {
     lock (this)
     {
         HybridDictionary dictionary2 = this._poolCollection;
         if (0 < dictionary2.Count)
         {
             HybridDictionary dictionary = new HybridDictionary(dictionary2.Count, false);
             foreach (DictionaryEntry entry in dictionary2)
             {
                 if (entry.Value != null)
                 {
                     DbConnectionPool pool = (DbConnectionPool)entry.Value;
                     if (clearing || (!pool.ErrorOccurred && (pool.Count == 0)))
                     {
                         DbConnectionFactory connectionFactory = pool.ConnectionFactory;
                         connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Decrement();
                         connectionFactory.QueuePoolForRelease(pool, clearing);
                     }
                     else
                     {
                         dictionary.Add(entry.Key, entry.Value);
                     }
                 }
             }
             this._poolCollection = dictionary;
             this._poolCount      = dictionary.Count;
         }
         if (!clearing && (this._poolCount == 0))
         {
             if (1 == this._state)
             {
                 this._state = 2;
                 Bid.Trace("<prov.DbConnectionPoolGroup.ClearInternal|RES|INFO|CPOOL> %d#, Idle\n", this.ObjectID);
             }
             else if (2 == this._state)
             {
                 this._state = 4;
                 Bid.Trace("<prov.DbConnectionPoolGroup.ReadyToRemove|RES|INFO|CPOOL> %d#, Disabled\n", this.ObjectID);
             }
         }
         return(4 == this._state);
     }
 }
        internal int Clear()
        {
            // must be multi-thread safe with competing calls by Clear and Prune via background thread
            // will return the number of connections in the group after clearing has finished

            // First, note the old collection and create a new collection to be used
            ConcurrentDictionary <DbConnectionPoolIdentity, DbConnectionPool> oldPoolCollection = null;

            lock (this)
            {
                if (_poolCollection.Count > 0)
                {
                    oldPoolCollection = _poolCollection;
                    _poolCollection   = new ConcurrentDictionary <DbConnectionPoolIdentity, DbConnectionPool>();
                }
            }

            // Then, if a new collection was created, release the pools from the old collection
            if (oldPoolCollection != null)
            {
                foreach (var entry in oldPoolCollection)
                {
                    DbConnectionPool pool = entry.Value;
                    if (pool != null)
                    {
                        //  Pruning a pool while a connection is currently attempting to connect
                        //  will cause the pool to be prematurely abandoned. The only known effect so
                        //  far is that the errorWait throttling will be reset when this occurs.
                        //  We should be able to avoid this situation by not pruning the pool if
                        //  it's _waitCount is non-zero (i.e. no connections *in* the pool, but also
                        //  no connections attempting to be created for the pool).

                        DbConnectionFactory connectionFactory = pool.ConnectionFactory;
                        connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Decrement();
                        connectionFactory.QueuePoolForRelease(pool, true);
                    }
                }
            }

            // Finally, return the pool collection count - this may be non-zero if something was added while we were clearing
            return(_poolCollection.Count);
        }
예제 #5
0
        internal bool Prune()
        {
            // must only call from DbConnectionFactory.PruneConnectionPoolGroups on background timer thread
            // must lock(DbConnectionFactory._connectionPoolGroups.SyncRoot) before calling ReadyToRemove
            //     to avoid conflict with DbConnectionFactory.CreateConnectionPoolGroup replacing pool entry
            lock (this)
            {
                if (!_poolCollection.IsEmpty)
                {
                    var newPoolCollection = new ConcurrentDictionary <DbConnectionPoolIdentity, DbConnectionPool>();

                    foreach (var entry in _poolCollection)
                    {
                        DbConnectionPool pool = entry.Value;
                        if (pool != null)
                        {
                            //  Pruning a pool while a connection is currently attempting to connect
                            //  will cause the pool to be prematurely abandoned. The only known effect so
                            //  far is that the errorWait throttling will be reset when this occurs.
                            //  We should be able to avoid this situation by not pruning the pool if
                            //  it's _waitCount is non-zero (i.e. no connections *in* the pool, but also
                            //  no connections attempting to be created for the pool).

                            // Actually prune the pool if there are no connections in the pool and no errors occurred.
                            // Empty pool during pruning indicates zero or low activity, but
                            //  an error state indicates the pool needs to stay around to
                            //  throttle new connection attempts.
                            if ((!pool.ErrorOccurred) && (0 == pool.Count))
                            {
                                // Order is important here.  First we remove the pool
                                // from the collection of pools so no one will try
                                // to use it while we're processing and finally we put the
                                // pool into a list of pools to be released when they
                                // are completely empty.
                                DbConnectionFactory connectionFactory = pool.ConnectionFactory;

                                connectionFactory.PerformanceCounters.NumberOfActiveConnectionPools.Decrement();
                                connectionFactory.QueuePoolForRelease(pool, false);
                            }
                            else
                            {
                                newPoolCollection.TryAdd(entry.Key, entry.Value);
                            }
                        }
                    }
                    _poolCollection = newPoolCollection;
                }

                // must be pruning thread to change state and no connections
                // otherwise pruning thread risks making entry disabled soon after user calls ClearPool
                if (_poolCollection.IsEmpty)
                {
                    if (PoolGroupStateActive == _state)
                    {
                        _state = PoolGroupStateIdle;
                    }
                    else if (PoolGroupStateIdle == _state)
                    {
                        _state = PoolGroupStateDisabled;
                    }
                }
                return(PoolGroupStateDisabled == _state);
            }
        }