Example #1
0
 /// <summary>
 /// Returns a socket to the pool.
 /// If the socket is dead, it will be destroyed.
 /// If there are more than MaxPoolSize sockets in the pool, it will be destroyed.
 /// If there are less than MinPoolSize sockets in the pool, it will always be put back.
 /// If there are something inbetween those values, the age of the socket is checked.
 /// If it is older than the SocketRecycleAge, it is destroyed, otherwise it will be
 /// put back in the pool.
 /// </summary>
 internal void Return(MSocket socket)
 {
     //If the socket is dead, destroy it.
     if (!socket.IsAlive || hasDisponse)
     {
         Interlocked.Increment(ref DeadSocketsOnReturn);
         socket.Close();
     }
     else
     {
         //Clean up socket
         socket.Reset();
         //Check pool size.
         if (socketQueue.Count >= maxQueue)
         {
             //If the pool is full, destroy the socket.
             socket.Close();
         }
         else if (socketQueue.Count > minQueue && socket.CreateTime.AddMinutes(30) < DateTime.Now)
         {
             //socket 服务超过半小时的,也可以休息了,只保留最底个数。
             //If we have more than the minimum amount of sockets, but less than the max, and the socket is older than the recycle age, we destroy it.
             socket.Close();
         }
         else
         {
             //Put the socket back in the pool.
             lock (socketQueue)
             {
                 socketQueue.Enqueue(socket);
             }
         }
     }
 }
Example #2
0
        internal T Execute <T>(SocketPool pool, T defaultValue, UseSocket <T> use)
        {
            MSocket sock = null;

            try
            {
                //Acquire a socket
                sock = pool.Acquire();

                //Use the socket as a parameter to the delegate and return its result.
                if (sock != null)
                {
                    return(use(sock));
                }
            }
            catch (Exception e)
            {
                logger.Error("Error in Execute<T>: " + pool.Host, e);

                //Socket is probably broken
                if (sock != null)
                {
                    sock.Close();
                }
            }
            finally
            {
                if (sock != null)
                {
                    sock.Dispose();
                }
            }
            return(defaultValue);
        }
Example #3
0
        internal void Execute(SocketPool pool, UseSocket use)
        {
            MSocket sock = null;

            try
            {
                //Acquire a socket
                sock = pool.Acquire();

                //Use the socket as a parameter to the delegate and return its result.
                if (sock != null)
                {
                    use(sock);
                }
            }
            catch (Exception e)
            {
                logger.Error("Error in Execute: " + pool.Host, e);

                //Socket is probably broken
                if (sock != null)
                {
                    sock.Close();
                }
            }
            finally
            {
                if (sock != null)
                {
                    sock.Dispose();
                }
            }
        }
Example #4
0
 bool pool_OnAfterSocketCreateEvent(MSocket socket)
 {
     if (OnAuthEvent != null)
     {
         return(OnAuthEvent(socket));
     }
     return(true);
 }
Example #5
0
 bool serverPool_OnAuthEvent(MSocket socket)
 {
     if (!Auth(socket.SocketPool.password, socket))
     {
         Error.Throw("Auth password fail!");
     }
     return(true);
 }
Example #6
0
 bool hostServer_OnAuthEvent(MSocket socket)
 {
     if (!Auth(socket.HostNode.Password, socket))
     {
         string err = "Auth password fail : " + socket.HostNode.Password;
         socket.HostNode.Error = err;
         Error.Throw(err);
     }
     return(true);
 }
Example #7
0
        public RedisCommand(MSocket socket, int commandCount, string command)
        {
            this.socket = socket;
            this.socket.Reset();
            //Write(string.Format("*{0}\r\n", commandCount));
            //WriteKey(command);

            //听说redis verstion 2.8 不支持参数分开发送,所以打包一起发送。
            string cmd = string.Format("*{0}\r\n${1}\r\n{2}\r\n", commandCount, Encoding.UTF8.GetBytes(command).Length, command);

            Add(cmd);
        }
Example #8
0
 private bool Auth(string password, MSocket socket)
 {
     if (!string.IsNullOrEmpty(password))
     {
         using (RedisCommand cmd = new RedisCommand(socket, 2, "AUTH"))
         {
             cmd.WriteKey(password);
         }
         return(socket.ReadResponse().StartsWith("+OK"));
     }
     return(true);
 }
Example #9
0
 private bool Auth(string password, MSocket socket)
 {
     if (!string.IsNullOrEmpty(password))
     {
         using (RedisCommand cmd = new RedisCommand(socket, 2, "AUTH"))
         {
             cmd.AddKey(password);
         }
         string result = socket.ReadLine();
         return(result.StartsWith("+OK"));
     }
     return(true);
 }
Example #10
0
 internal int GetDBIndex(MSocket socket, uint hash)
 {
     if (AppConfig.Cache.RedisUseDBCount > 1 || AppConfig.Cache.RedisUseDBIndex > 0)
     {
         return(AppConfig.Cache.RedisUseDBIndex > 0 ? AppConfig.Cache.RedisUseDBIndex : (int)(hash % AppConfig.Cache.RedisUseDBCount));//默认分散在16个DB中。
         //if (socket.DB != db)
         //{
         //    socket.DB = db;
         //    return (int)db;
         //}
     }
     return(-1);
 }
Example #11
0
        public RedisCommand(MSocket socket, int commandCount, string command)
        {
            this.socket = socket;
            //Write(string.Format("*{0}\r\n", commandCount));
            //WriteKey(command);

            //听说redis verstion 2.8 不支持参数分开发送,所以打包一起发送。
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("*{0}\r\n", commandCount);
            sb.AppendFormat("${0}\r\n", Encoding.UTF8.GetBytes(command).Length);
            sb.Append(command);
            sb.Append("\r\n");
            Write(sb.ToString());
        }
Example #12
0
 internal void CheckDB(MSocket socket, uint hash)
 {
     if (AppConfig.Cache.RedisUseDBCount > 1 || AppConfig.Cache.RedisUseDBIndex > 0)
     {
         uint db = AppConfig.Cache.RedisUseDBIndex > 0 ? (uint)AppConfig.Cache.RedisUseDBIndex : (hash % (uint)AppConfig.Cache.RedisUseDBCount);//默认分散在16个DB中。
         if (socket.DB != db)
         {
             socket.DB = db;
             using (RedisCommand cmd = new RedisCommand(socket, 2, "Select"))
             {
                 cmd.WriteKey(db.ToString());
             }
             socket.SkipToEndOfLine();
         }
     }
 }
Example #13
0
        //Private method for reading results of the "get" command.
        private bool readValue(MSocket socket, out object value, out string key, out ulong unique)
        {
            string response = socket.ReadResponse();

            string[] parts = response.Split(' '); //Result line from server: "VALUE <key> <flags> <bytes> <cas unique>"
            if (parts[0] == "VALUE")
            {
                key = parts[1];
                SerializedType type  = (SerializedType)Enum.Parse(typeof(SerializedType), parts[2]);
                byte[]         bytes = new byte[Convert.ToUInt32(parts[3], CultureInfo.InvariantCulture)];
                if (parts.Length > 4)
                {
                    unique = Convert.ToUInt64(parts[4]);
                }
                else
                {
                    unique = 0;
                }
                socket.Read(bytes);
                socket.SkipToEndOfLine(); //Skip the trailing \r\n
                try
                {
                    value = Serializer.DeSerialize(bytes, type);
                }
                catch (Exception e)
                {
                    //If deserialization fails, return null
                    value = null;
                    logger.Error("Error deserializing object for key '" + key + "' of type " + type + ".", e);
                }
                return(true);
            }
            else
            {
                key    = null;
                value  = null;
                unique = 0;
                return(false);
            }
        }
Example #14
0
        /// <summary>
        /// Returns a socket to the pool.
        /// If the socket is dead, it will be destroyed.
        /// If there are more than MaxPoolSize sockets in the pool, it will be destroyed.
        /// If there are less than MinPoolSize sockets in the pool, it will always be put back.
        /// If there are something inbetween those values, the age of the socket is checked.
        /// If it is older than the SocketRecycleAge, it is destroyed, otherwise it will be
        /// put back in the pool.
        /// </summary>
        internal void Return(MSocket socket)
        {
            //If the socket is dead, destroy it.
            if (!socket.IsAlive)
            {
                Interlocked.Increment(ref deadsocketsonreturn);
                socket.Close();
            }
            else
            {
                //Clean up socket
                if (socket.Reset())
                {
                    Interlocked.Increment(ref dirtysocketsonreturn);
                }

                //Check pool size.
                if (queue.Count >= owner.MaxPoolSize)
                {
                    //If the pool is full, destroy the socket.
                    socket.Close();
                }
                else if (queue.Count > owner.MinPoolSize && DateTime.Now - socket.Created > owner.SocketRecycleAge)
                {
                    //If we have more than the minimum amount of sockets, but less than the max, and the socket is older than the recycle age, we destroy it.
                    socket.Close();
                }
                else
                {
                    //Put the socket back in the pool.
                    lock (queue)
                    {
                        queue.Enqueue(socket);
                    }
                }
            }
        }
Example #15
0
 public RedisCommand(MSocket socket)
 {
     this.socket = socket;
     socket.Reset();
 }
Example #16
0
        /// <summary>
        /// Gets a socket from the pool.
        /// If there are no free sockets, a new one will be created. If something goes
        /// wrong while creating the new socket, this pool's endpoint will be marked as dead
        /// and all subsequent calls to this method will return null until the retry interval
        /// has passed.
        /// 这个方法扩展(备份链接池)
        /// </summary>
        internal MSocket Acquire()
        {
            //检测当前是否挂科,如果是(15分钟内),由备份服务器提供服务
            if (socketDeadTime.AddMinutes(15) >= DateTime.Now && socketPoolBak != null)
            {
                return(socketPoolBak.Acquire());
            }

            //Do we have free sockets in the pool?
            //if so - return the first working one.
            //if not - create a new one.
            Interlocked.Increment(ref acquired);
            lock (queue)
            {
                while (queue.Count > 0)
                {
                    MSocket socket = queue.Dequeue();
                    if (socket != null && socket.IsAlive)
                    {
                        Interlocked.Increment(ref reusedsockets);
                        return(socket);
                    }
                    Interlocked.Increment(ref deadsocketsinpool);
                }
            }

            Interlocked.Increment(ref newsockets);
            //If we know the endpoint is dead, check if it is time for a retry, otherwise return null.
            if (isEndPointDead)
            {
                if (DateTime.Now > deadEndPointRetryTime)
                {
                    //Retry
                    isEndPointDead = false;
                }
                else
                {
                    //Still dead
                    return(null);
                }
            }

            //Try to create a new socket. On failure, mark endpoint as dead and return null.
            try
            {
                MSocket socket = new MSocket(this, endPoint, owner.SendReceiveTimeout, owner.ConnectTimeout);
                //Reset retry timer on success.
                deadEndPointSecondsUntilRetry = 1;
                return(socket);
            }
            catch (Exception e)
            {
                Interlocked.Increment(ref failednewsockets);
                logger.Error("Error connecting to: " + endPoint.Address, e);
                //Mark endpoint as dead
                isEndPointDead = true;
                //Retry in 2 minutes
                deadEndPointRetryTime = DateTime.Now.AddSeconds(deadEndPointSecondsUntilRetry);
                if (deadEndPointSecondsUntilRetry < maxDeadEndPointSecondsUntilRetry)
                {
                    deadEndPointSecondsUntilRetry = deadEndPointSecondsUntilRetry * 2; //Double retry interval until next time
                }

                socketDeadTime = DateTime.Now;
                //返回备份的池
                if (socketPoolBak != null)
                {
                    return(socketPoolBak.Acquire());
                }
                return(null);
            }
        }
Example #17
0
        /// <summary>
        /// Gets a socket from the pool.
        /// If there are no free sockets, a new one will be created. If something goes
        /// wrong while creating the new socket, this pool's endpoint will be marked as dead
        /// and all subsequent calls to this method will return null until the retry interval
        /// has passed.
        /// 这个方法扩展(备份链接池)
        /// </summary>
        internal MSocket Acquire()
        {
            //检测当前是否挂科,如果是(15分钟内),由备份服务器提供服务
            if (socketDeadTime.AddMinutes(15) >= DateTime.Now && HostNodeBak != null)
            {
                return(HostNodeBak.Acquire());
            }

            //Do we have free sockets in the pool?
            //if so - return the first working one.
            //if not - create a new one.
            Interlocked.Increment(ref Acquired);
            lock (socketQueue)
            {
                while (socketQueue.Count > 0)
                {
                    MSocket socket = socketQueue.Dequeue();
                    if (socket != null && socket.IsAlive)
                    {
                        Interlocked.Increment(ref ReusedSockets);
                        return(socket);
                    }
                    Interlocked.Increment(ref DeadSocketsInPool);
                }
            }


            //If we know the endpoint is dead, check if it is time for a retry, otherwise return null.
            if (IsEndPointDead)
            {
                if (DateTime.Now > DeadEndPointRetryTime)
                {
                    //Retry
                    IsEndPointDead = false;
                }
                else
                {
                    //Still dead
                    return(null);
                }
            }

            //Try to create a new socket. On failure, mark endpoint as dead and return null.
            try
            {
                MSocket socket = new MSocket(this, Host);
                Interlocked.Increment(ref NewSockets);
                //Reset retry timer on success.
                //不抛异常,则正常链接。
                if (OnAfterSocketCreateEvent != null)
                {
                    OnAfterSocketCreateEvent(socket);
                }
                deadEndPointSecondsUntilRetry = 1;
                return(socket);
            }
            catch (Exception e)
            {
                Interlocked.Increment(ref FailedNewSockets);
                logger.Error("Error connecting to: " + Host, e);
                //Mark endpoint as dead
                IsEndPointDead = true;
                //Retry in 2 minutes
                DeadEndPointRetryTime = DateTime.Now.AddSeconds(deadEndPointSecondsUntilRetry);
                if (deadEndPointSecondsUntilRetry < maxDeadEndPointSecondsUntilRetry)
                {
                    deadEndPointSecondsUntilRetry = deadEndPointSecondsUntilRetry * 2; //Double retry interval until next time
                }

                socketDeadTime = DateTime.Now;
                //返回备份的池
                if (HostNodeBak != null)
                {
                    return(HostNodeBak.Acquire());
                }
                return(null);
            }
        }
Example #18
0
 public RedisCommand(MSocket socket, int commandCount, string command)
 {
     this.socket = socket;
     Write(string.Format("*{0}\r\n", commandCount));
     WriteKey(command);
 }