/// <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); } } } }
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); }
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(); } } }
bool pool_OnAfterSocketCreateEvent(MSocket socket) { if (OnAuthEvent != null) { return(OnAuthEvent(socket)); } return(true); }
bool serverPool_OnAuthEvent(MSocket socket) { if (!Auth(socket.SocketPool.password, socket)) { Error.Throw("Auth password fail!"); } return(true); }
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); }
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); }
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); }
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); }
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); }
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()); }
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(); } } }
//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); } }
/// <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); } } } }
public RedisCommand(MSocket socket) { this.socket = socket; socket.Reset(); }
/// <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); } }
/// <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); } }
public RedisCommand(MSocket socket, int commandCount, string command) { this.socket = socket; Write(string.Format("*{0}\r\n", commandCount)); WriteKey(command); }