Exemplo n.º 1
0
            /// <summary>
            /// Releases an item back into the pool
            /// </summary>
            /// <param name="socket"></param>
            private void ReleaseSocket(PooledSocket socket)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Releasing socket " + socket.InstanceId);
                    log.Debug("Are we alive? " + this.isAlive);
                }

                if (this.isAlive)
                {
                    // is it still working (i.e. the server is still connected)
                    if (socket.IsAlive)
                    {
                        // mark the item as free
                        this.freeItems.Push(socket);

                        // signal the event so if someone is waiting for it can reuse this item
                        this.semaphore.Release();
                    }
                    else
                    {
                        // kill this item
                        socket.Destroy();

                        // mark ourselves as not working for a while
                        this.MarkAsDead();

                        // make sure to signal the Acquire so it can create a new conenction
                        // if the failure policy keeps the pool alive
                        this.semaphore.Release();
                    }
                }
                else
                {
                    // one of our previous sockets has died, so probably all of them
                    // are dead. so, kill the socket (this will eventually clear the pool as well)
                    socket.Destroy();
                }
            }
Exemplo n.º 2
0
            /// <summary>
            /// Acquires a new item from the pool
            /// </summary>
            /// <returns>An <see cref="T:PooledSocket"/> instance which is connected to the memcached server, or <value>null</value> if the pool is dead.</returns>
            public IPooledSocketResult Acquire()
            {
                var result  = new PooledSocketResult();
                var message = string.Empty;

                bool hasDebug = log.IsDebugEnabled;

                if (hasDebug)
                {
                    log.Debug("Acquiring stream from pool. " + this.endPoint);
                }

                if (!this.isAlive || this.isDisposed)
                {
                    message = "Pool is dead or disposed, returning null. " + this.endPoint;
                    result.Fail(message);

                    if (hasDebug)
                    {
                        log.Debug(message);
                    }

                    return(result);
                }

                PooledSocket retval = null;

                if (!this.semaphore.WaitOne(this.queueTimeout))
                {
                    message = "Pool is full, timeouting. " + this.endPoint;
                    if (hasDebug)
                    {
                        log.Debug(message);
                    }
                    result.Fail(message, new TimeoutException());

                    // everyone is so busy
                    return(result);
                }

                // maybe we died while waiting
                if (!this.isAlive)
                {
                    message = "Pool is dead, returning null. " + this.endPoint;
                    if (hasDebug)
                    {
                        log.Debug(message);
                    }
                    result.Fail(message);

                    return(result);
                }

                // do we have free items?
                if (this.freeItems.TryPop(out retval))
                {
                    #region [ get it from the pool         ]

                    try
                    {
                        retval.Reset();

                        message = "Socket was reset. " + retval.InstanceId;
                        if (hasDebug)
                        {
                            log.Debug(message);
                        }

                        result.Pass(message);
                        result.Value = retval;
                        return(result);
                    }
                    catch (Exception e)
                    {
                        message = "Failed to reset an acquired socket.";
                        log.Error(message, e);

                        this.MarkAsDead();
                        result.Fail(message, e);
                        return(result);
                    }

                    #endregion
                }

                // free item pool is empty
                message = "Could not get a socket from the pool, Creating a new item. " + this.endPoint;
                if (hasDebug)
                {
                    log.Debug(message);
                }

                try
                {
                    // okay, create the new item
                    retval       = this.CreateSocket();
                    result.Value = retval;
                    result.Pass();
                }
                catch (Exception e)
                {
                    message = "Failed to create socket. " + this.endPoint;
                    log.Error(message, e);

                    // eventhough this item failed the failure policy may keep the pool alive
                    // so we need to make sure to release the semaphore, so new connections can be
                    // acquired or created (otherwise dead conenctions would "fill up" the pool
                    // while the FP pretends that the pool is healthy)
                    semaphore.Release();

                    this.MarkAsDead();
                    result.Fail(message);
                    return(result);
                }

                if (hasDebug)
                {
                    log.Debug("Done.");
                }

                return(result);
            }