Ejemplo n.º 1
0
        /// <summary>
        /// Worker thread that cleans up timed-out connections.
        /// </summary>
        static internal void ConnectionPoolWorkerThread()
        {
            bool shuttingDown = false;

//			Console.WriteLine("ConnectionPoolWorkerThread started");
            while (true)
            {
                bool      didWork = false;
                DateTime  now     = DateTime.Now;
                ArrayList pools   = null;

                // Wait on the lock for the pool of pools since
                // the ConnectionPoolManager.Get might have it and
                // is declaring its intent to get a slot from one of the pools.
                lock (poolOfConnectionPools)
                {
                    pools = new ArrayList(poolOfConnectionPools.Keys);
                    foreach (object obj in pools)
                    {
                        string         key  = (string)obj;                 // connection string
                        ConnectionPool pool =
                            (ConnectionPool)poolOfConnectionPools[key];
                        // if no active slots and no connecting
                        // and no inactive connections and too old
                        if (pool.IsTooOld(now))
                        {
                            // disconnect old, empty pool from the pool of pools
                            poolOfConnectionPools.Remove(key);
                        }
                    }

                    // Get a snapshot list of pools.  Other threads might
                    // be adding more pools to the pool of pools but we
                    // don't care; we'll catch on the next timer iteration.
                    // We are the only thread that removes pools so we
                    // the snapahot will be good for this iteration.
                    pools = new ArrayList(poolOfConnectionPools.Values);

                    // release our lock on the pool of pools
                }                  // end lock(poolOfConnectionPools)

                foreach (object obj in pools)
                {
                    ConnectionPool pool = (ConnectionPool)obj;
                    // We now have a pool that we can check for inactive
                    // physical connections that we can close physically.

                    while (true)                     // loop thru the connections in the pool
                    {
                        AdvanConnect advanConnect = null;

                        advanConnect = pool.GetPoolSlotExpired(shuttingDown);
                        if (advanConnect == null)
                        {
                            break;
                        }

                        try
                        {
//							Console.WriteLine("Closing connection physically"+
//								" by ConnectionPoolWorkerThread");
                            // Close the connection.  Do not hold any
                            // locks for the pool of pools or a pool since
                            // the I/O for the close may take a long time.
                            advanConnect.close();                              // close the connection
                        }
                        catch
                        {}
                        didWork = true;
                    }
                }

                if (didWork)                   // if we did something then restart the scan
                {
                    continue;
                }

                pools = null;                  // release the object to garbage collection

                if (shuttingDown)
                {
//					Console.WriteLine("ConnectionPoolWorkerThread returning");
                    return;
                }

                // sleep 10 seconds or until shutdown signaled
                shuttingDown = shuttingDownEvent.WaitOne(10000, false);
//				if (shuttingDown)
//					Console.WriteLine("ConnectionPoolWorkerThread ShuttingDown");

                //Thread.Sleep(10000);  // sleep 10 seconds
            }              // end while
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Find the correct connection pool based on connection string.
        /// Get an AdvanConnect connection from the pool or create
        /// the AdvanConnect if none is available.  Wait on pool if
        /// connection limit on pool would be exceeded.
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="providerConnection"></param>
        /// <param name="host"></param>
        /// <param name="config"></param>
        /// <param name="trace"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        static private AdvanConnect GetConnectionFromPool(
            string connectionString,
            IDbConnection providerConnection,
            String host,
            IConfig config,
            ITrace trace,
            int timeout)
        {
            string         strValue;
            AdvanConnect   advanConnect;
            ConnectionPool pool;
            int            minPoolSize       = 0;
            int            maxPoolSize       = 100;
            int            expirationSeconds = 60;   // inactive connection expiration

            // timespan before removal from pool

            if (trace == null)
            {
                trace = new TraceDV(DrvConst.DRV_TRACE_ID);                   // "drv"
            }
            // if 'Pooling=false' was specified, get a new connection
            string pooling = config.get(DrvConst.DRV_PROP_CLIENTPOOL);

            if (pooling != null &&
                (pooling.ToLower(CultureInfo.InvariantCulture) == "false" ||
                 pooling.ToLower(CultureInfo.InvariantCulture) == "no"))
            {
                advanConnect = new AdvanConnect(
                    providerConnection, host, config, trace, timeout);
                // leave advanConnect.CanBePooled == false so that
                // it does not go back into the pool and is physically closed later.
                return(advanConnect);
            }

            // Min Pool Size
            strValue = config.get(DrvConst.DRV_PROP_MINPOOLSIZE);
            if (strValue != null)
            {
                try
                { minPoolSize = Int32.Parse(strValue); }
                catch
                {}
            }

            // Max Pool Size
            strValue = config.get(DrvConst.DRV_PROP_MAXPOOLSIZE);
            if (strValue != null)
            {
                try
                { maxPoolSize = Int32.Parse(strValue); }
                catch
                {}
            }

            while (true)              // retry loop to get a pooled connection
            {
                // Get a pooled connection.
                // Wait on the lock for the pool of pools since
                // the ConnectionPoolWorkerThread might have it and
                // is busy cleaning up inactive pools.
                // This lock controls update of this list.  Do not
                // hold the lock for long (i.e. no DB access).
                lock (poolOfConnectionPools)                  // lock pool of pools and possibly wait
                {
                    // if first time, start the worker thread that cleans up connections
                    if (connectionPoolWorkerThread == null)
                    {
                        // create thread and fill in connectionPoolWorkerThread
                        CreateConnectionPoolWorkerThread();

                        // listen for AppDomain.DomainUnload event so we can
                        // tell the ConnectionPoolWorkerThread to gracefully
                        // shut down inactive connections in the pools.
                        ListenForAppDomainUnload();
                    }

                    // get a pooled connection for given connection string
                    pool = (ConnectionPool)poolOfConnectionPools[connectionString];

                    // if no pool for given connection string, build one
                    if (pool == null)
                    {
                        pool = new ConnectionPool(
                            providerConnection.ConnectionTimeout,
                            minPoolSize,
                            maxPoolSize,
                            expirationSeconds);
                        poolOfConnectionPools[connectionString] = pool; // insert
                    }                                                   // end if (pool == null)

                    pool.PrepareToGetPoolSlot();                        // mark pool for "connect-in-progress"
                }                                                       // end lock(poolOfConnectionPools)

                // Wait for and lock up a slot in the connection pool
                // and release the "connect-in-progress" indicator in the pool.
                // The pool.ConnectingCount will be > 0 and will prevent
                // the pool from being released while we wait for a slot.
                // We hold no locks on pool of pools nor individual pool while we wait.
                advanConnect = pool.GetPoolSlot(providerConnection);

                // if a physical connection was found in the pool then we're all done!
                if (advanConnect != null)
                {
                    if (advanConnect.msg.QuerySocketHealth() == true)                     // if still alive
                    {
                        return(advanConnect);
                    }
                    advanConnect.close();                         // close the bad connection
                    continue;                                     // retry to get a pooled connection
                }
                else
                {
                    break;  // no more available connections in pool
                }
            }               // retry loop to get a pooled connection


            // we own a slot in the pool
            // but we need to build a brand new connection
            try
            {
                // connect to the server
                advanConnect = new AdvanConnect(
                    providerConnection, host, config, trace, timeout);

                // at this point, we have a good connection
                advanConnect.connectionPool = pool;
                advanConnect.CanBePooled    = true;                  // we can pool good ones
            }
            catch (Exception)
            {
                pool.PutPoolSlot();                  // release our slot back into the pool
                throw;
            }
            return(advanConnect);
        }