예제 #1
0
        /// <summary>
        /// 清理所有存在的连接
        /// 然后重新创建
        /// </summary>
        public void Clear()
        {
            poolState = POOL_SUSPENDED;
            PoolEntry poolEntry = null;

            //清理资源
            while (true)
            {
                if (connectionBag.TryPop(out poolEntry))
                {
                    CloseConnection(poolEntry.Close());
                }
                else if (connectionBag.IsEmpty)
                {
                    break;
                }
                else
                {
                    continue;
                }
            }
            size = 0;
            //
            keepingExecutor.Clear(); //清除
            poolState = POOL_NORMAL;
            resetEvent.Set();        //恢复等待;
        }
예제 #2
0
        /// <summary>
        /// 初始化创建
        /// </summary>
        private void CheckFailFast()
        {
            long initializationTimeout = config.InitializationFailTimeout;

            if (initializationTimeout < 0)
            {
                return;
            }

            long startTime = DateTime.Now.Ticks;

            do
            {
                PoolEntry poolEntry = CreatePoolEntry();
                if (poolEntry != null)
                {
                    if (config.MinimumIdle > 0)
                    {
                        connectionBag.Push(poolEntry);

                        Logger.Singleton.DebugFormat("{0} - Added connection {1}", poolName, poolEntry);
                    }
                }
                startTime = (DateTime.Now.Ticks - startTime) / TicksMs;
            } while (startTime < initializationTimeout);
        }
예제 #3
0
        /// <summary>
        /// 清除所有监测对象
        /// </summary>
        public void Clear()
        {
            PoolEntry poolEntry = null;

            while (true)
            {
                userQueue.TryDequeue(out poolEntry);
                if (userQueue.IsEmpty || poolEntry == null)
                {
                    break;
                }
            }
            //
            while (true)
            {
                maxLiveQueue.TryDequeue(out poolEntry);
                if (maxLiveQueue.IsEmpty || poolEntry == null)
                {
                    break;
                }
            }

            //
            while (true)
            {
                idleTimeQueue.TryDequeue(out poolEntry);
                if (idleTimeQueue.IsEmpty || poolEntry == null)
                {
                    break;
                }
            }
        }
예제 #4
0
        /// <summary>
        /// 创建池中数据对象
        ///
        /// </summary>
        /// <returns></returns>
        protected PoolEntry NewPoolEntry()
        {
            PoolEntry poolEntry = new PoolEntry(NewConnection(), this);

            if (poolEntry != null)
            {
                poolEntry.ID = Interlocked.Increment(ref entryid);
                Interlocked.Increment(ref size);
            }
            return(poolEntry);
        }
예제 #5
0
 /// <summary>
 /// 创建代理对象
 /// </summary>
 /// <param name="poolEntry"></param>
 /// <param name="connection"></param>
 /// <param name="now"></param>
 /// <returns></returns>
 internal static IDbConnection GetProxyConnection(PoolEntry poolEntry, IDbConnection connection, long now)
 {
     try
     {
         return(new HikariConnection(poolEntry, connection, now));
     }
     catch (Exception ex)
     {
         throw new Exception("获取失败78:" + ex.Message);
     }
 }
예제 #6
0
 public ProxyConnection(PoolEntry poolEntry, IDbConnection connection, long now)
 {
     try
     {
         this.poolEntry   = poolEntry;
         this.delegateCon = connection;
         this.lastAccess  = now;
         // Init();
     }
     catch (Exception ex)
     {
         throw new Exception("获取失败56:" + ex.Message);
     }
 }
예제 #7
0
 /// <summary>
 /// 释放使用
 /// </summary>
 /// <param name="poolEntry"></param>
 internal void Recycle(PoolEntry poolEntry)
 {
     if (poolEntry.State == IConcurrentBagEntry.STATE_REMOVED)
     {
         //已经标记移除的不能再加入,集合也不允许
         CloseConnection(poolEntry.Close());
         return;
     }
     if (!connectionBag.Push(poolEntry))
     {
         CloseConnection(poolEntry.Close());
     }
     else
     {
         //监视空闲
         keepingExecutor.ScheduleIdleTimeout(poolEntry);
     }
 }
예제 #8
0
 /// <summary>
 /// 开启线程监测连接
 /// </summary>
 private void CheckPool()
 {
     if (config.MinimumIdle == 0)
     {
         config.MinimumIdle = config.MaximumPoolSize;
         if (config.MinimumIdle > 2 * Environment.ProcessorCount)
         {
             config.MinimumIdle = Environment.ProcessorCount * 2;
         }
     }
     //isWaitAdd
     if (isWaitAdd)
     {
         isWaitAdd = false;
         Task.Factory.StartNew((Action)(() =>
         {
             int num = 10;//20s内的监测
             while (true)
             {
                 //挂满池中最小空闲
                 while (size < config.MaximumPoolSize && connectionBag.Count < config.MinimumIdle)
                 {
                     //迅速添加连接爬升,可以从池中获取
                     PoolEntry poolEntry = CreatePoolEntry();
                     if (poolEntry != null)
                     {
                         connectionBag.Push(poolEntry);
                     }
                 }
                 Thread.Sleep(2000);//延迟2秒,监测
                 num--;
                 if (num == 0)
                 {
                     break;
                 }
             }
             isWaitAdd = true;
         }));
     }
     //
 }
예제 #9
0
        /// <summary>
        /// 创建池中对象
        /// </summary>
        /// <returns></returns>
        private PoolEntry CreatePoolEntry()
        {
            try
            {
                PoolEntry poolEntry = NewPoolEntry();
                if (poolEntry == null)
                {
                    return(null);
                }
                long maxLifetime = config.MaxLifetime;
                if (maxLifetime > 0 && poolEntry != null)
                {
                    // variance up to 2.5% of the maxlifetime
                    Random random   = new Random();
                    long   variance = maxLifetime > 10_000 ? random.Next((int)maxLifetime / 40) : 0;
                    long   lifetime = maxLifetime - variance;
                    keepingExecutor.ScheduleMaxLive(poolEntry);
                }

                return(poolEntry);
            }
            catch (SQLException e)
            {
                if (poolState == POOL_NORMAL)
                { // we check POOL_NORMAL to avoid a flood of messages if shutdown() is running concurrently
                    Logger.Singleton.DebugFormat("{0} - Cannot acquire connection from data source", poolName);
                }
                Logger.Singleton.DebugFormat("{0} - Cannot acquire connection from data source,error:{1}", poolName, e);
                return(null);
            }
            catch (Exception e)
            {
                if (poolState == POOL_NORMAL)
                { // we check POOL_NORMAL to avoid a flood of messages if shutdown() is running concurrently
                    Logger.Singleton.ErrorFormat("{0} - Error thrown while acquiring connection from data source,{1}", poolName, e.Message);
                }
                return(null);
            }
        }
예제 #10
0
 /// <summary>
 /// 监视连接离开的池的对象
 /// </summary>
 /// <param name="poolEntry"></param>
 public void ScheduleUse(PoolEntry poolEntry)
 {
     userQueue.Enqueue(poolEntry);
 }
예제 #11
0
 /// <summary>
 /// 监视连接最大存活
 /// </summary>
 /// <param name="poolEntry"></param>
 public void ScheduleMaxLive(PoolEntry poolEntry)
 {
     maxLiveQueue.Enqueue(poolEntry);
 }
예제 #12
0
 /// <summary>
 /// 监测空闲的连接
 /// </summary>
 /// <param name="poolEntry"></param>
 public void ScheduleIdleTimeout(PoolEntry poolEntry)
 {
     idleTimeQueue.Enqueue(poolEntry);
 }
예제 #13
0
        /// <summary>
        /// 开启监视
        /// </summary>
        private void Start()
        {
            Thread idle = new Thread(() =>
            {
                PoolEntry poolEntry = null;
                while (!IsStop)
                {
                    Thread.Sleep(idleTimeOut);
                    int num  = idleTimeQueue.Count;
                    long now = DateTime.Now.Ticks;
                    while (num > 0)
                    {
                        if (idleTimeQueue.TryDequeue(out poolEntry))
                        {
                            //超过空闲时间就不需要,标记移除
                            if ((now - poolEntry.AccessedTime) / TickMS > idleTimeOut)
                            {
                                poolEntry.CompareAndSetState(IConcurrentBagEntry.STATE_NOT_IN_USE, IConcurrentBagEntry.STATE_REMOVED);
                            }
                            num--;
                            if (poolEntry.State != IConcurrentBagEntry.STATE_REMOVED)
                            {
                                //已经标记移除的不再监测
                                idleTimeQueue.Enqueue(poolEntry);
                            }
                        }
                    }
                }
            });

            idle.Name         = PoolName + "_idle";
            idle.IsBackground = true;
            idle.Start();
            //
            Thread maxLeft = new Thread(() =>
            {
                PoolEntry poolEntry = null;
                while (!IsStop)
                {
                    Thread.Sleep(maxLeftTime);
                    int num  = maxLiveQueue.Count;
                    long now = DateTime.Now.Ticks;
                    while (num > 0)
                    {
                        if (maxLiveQueue.TryDequeue(out poolEntry))
                        {
                            if ((now - poolEntry.CreateTime) / TickMS > maxLeftTime)
                            {
                                poolEntry.CompareAndSetState(IConcurrentBagEntry.STATE_NOT_IN_USE, IConcurrentBagEntry.STATE_REMOVED);
                            }
                            num--;
                            if (poolEntry.State != IConcurrentBagEntry.STATE_REMOVED)
                            {
                                //已经标记移除的不再监测
                                maxLiveQueue.Enqueue(poolEntry);
                            }
                        }
                    }
                }
            });

            maxLeft.Name         = PoolName + "_left";
            maxLeft.IsBackground = true;
            maxLeft.Start();
            //
            Thread leakDetection = new Thread(() =>
            {
                PoolEntry poolEntry = null;
                int cout            = 10;//延迟10s没有设置就退出;
                while (!IsStop)
                {
                    Thread.Sleep(leakDetectionThreshold);
                    if (leakDetectionThreshold == 0)
                    {
                        Thread.Sleep(1000);//延迟1s;
                        cout--;
                        if (cout == 0)
                        {
                            break;
                        }
                        continue;
                    }
                    int num  = userQueue.Count;
                    long now = DateTime.Now.Ticks;
                    while (num > 0)
                    {
                        if (userQueue.TryDequeue(out poolEntry))
                        {
                            if (poolEntry.State == IConcurrentBagEntry.STATE_IN_USE)
                            {
                                if ((now - poolEntry.AccessedTime) / TickMS > leakDetectionThreshold)
                                {
                                    Logger.Singleton.Warn(string.Format("{0}-可能泄露,实体:{1}", PoolName, poolEntry.ID));
                                }
                            }
                            num--;
                            if (poolEntry.State == IConcurrentBagEntry.STATE_IN_USE)
                            {
                                //没有使用的不再监测
                                userQueue.Enqueue(poolEntry);
                            }
                        }
                    }
                }
            });

            leakDetection.Name         = PoolName + "_leakDetection";
            leakDetection.IsBackground = true;
            leakDetection.Start();
        }
예제 #14
0
        /// <summary>
        /// 超时获取
        /// </summary>
        /// <param name="hardTimeout">毫秒</param>
        /// <returns></returns>
        public IDbConnection GetConnection(long hardTimeout)
        {
            if (poolState == POOL_SHUTDOWN)
            {
                return(null);
            }
            if (poolState == POOL_SUSPENDED)
            {
                //挂起操作
                resetEvent.WaitOne();
            }

            long startTime = DateTime.Now.Ticks;

            try
            {
                long timeout = hardTimeout;
                do
                {
                    PoolEntry poolEntry = null;
                    if (connectionBag.TryPop(out poolEntry))
                    {
                        try
                        {
                            if (poolEntry.State == IConcurrentBagEntry.STATE_REMOVED)
                            {
                                //已经要移除的
                                CloseConnection(poolEntry.Close());
                                continue;//继续获取
                            }
                            keepingExecutor.ScheduleUse(poolEntry);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("获取失败:" + ex.Message);
                        }
                        //每次产生代理连接,代理连接在外面会关闭,返回连接池的对象
                        return(poolEntry.CreateProxyConnection(DateTime.Now.Ticks));
                    }
                    else
                    {
                        CheckPool();//监测连接
                        if (size < config.MaximumPoolSize)
                        {
                            //创建新的,不再进入集合
                            poolEntry = CreatePoolEntry();
                            if (poolEntry != null)
                            {
                                poolEntry.CompareAndSetState(IConcurrentBagEntry.STATE_NOT_IN_USE, IConcurrentBagEntry.STATE_IN_USE);
                                keepingExecutor.ScheduleUse(poolEntry);
                                return(poolEntry.CreateProxyConnection(DateTime.Now.Ticks));
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                    //计算获取的时间,转化成ms
                    timeout = timeout - (DateTime.Now.Ticks - startTime) / tickms;
                } while (timeout > 0L);
            }
            catch (Exception e)
            {
                throw new SQLException(poolName + " - Interrupted during connection acquisition", e);
            }
            finally
            {
            }
            return(null);
        }
예제 #15
0
 public HikariConnection(PoolEntry poolEntry, IDbConnection connection, long now) : base(poolEntry, connection, now)
 {
 }