/// <summary> /// Internal constructor. This method takes the array of hosts and sets up an internal list of socketpools. /// </summary> internal ServerPool(string[] hosts) { hostDictionary = new Dictionary <uint, SocketPool>(); List <SocketPool> pools = new List <SocketPool>(); List <uint> keys = new List <uint>(); foreach (string host in hosts) { //Create pool SocketPool pool = new SocketPool(this, host.Trim()); //Create 250 keys for this pool, store each key in the hostDictionary, as well as in the list of keys. for (int i = 0; i < 250; i++) { uint key = BitConverter.ToUInt32(new ModifiedFNV1_32().ComputeHash(Encoding.UTF8.GetBytes(host + "-" + i)), 0); if (!hostDictionary.ContainsKey(key)) { hostDictionary[key] = pool; keys.Add(key); } } pools.Add(pool); } //Hostlist should contain the list of all pools that has been created. hostList = pools.ToArray(); //Hostkeys should contain the list of all key for all pools that have been created. //This array forms the server key continuum that we use to lookup which server a //given item key hash should be assigned to. keys.Sort(); hostKeys = keys.ToArray(); }
public PooledSocket(SocketPool socketPool, IPEndPoint endPoint, int sendReceiveTimeout, int connectTimeout) { this.socketPool = socketPool; Created = DateTime.Now; //Set up the socket. socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, sendReceiveTimeout); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, sendReceiveTimeout); socket.ReceiveTimeout = sendReceiveTimeout; socket.SendTimeout = sendReceiveTimeout; //Do not use Nagle's Algorithm socket.NoDelay = true; //Establish connection asynchronously to enable connect timeout. IAsyncResult result = socket.BeginConnect(endPoint, null, null); bool success = result.AsyncWaitHandle.WaitOne(connectTimeout, false); if (!success) { try { socket.Close(); } catch { } throw new SocketException(); } socket.EndConnect(result); //Wraps two layers of streams around the socket for communication. stream = new BufferedStream(new NetworkStream(socket, false)); }
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(); } } }
public MSocket(SocketPool socketPool, IPEndPoint endPoint, int sendReceiveTimeout, int connectTimeout) { this.socketPool = socketPool; Created = DateTime.Now; //Set up the socket. socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, sendReceiveTimeout); socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, sendReceiveTimeout); socket.ReceiveTimeout = sendReceiveTimeout; socket.SendTimeout = sendReceiveTimeout; //socket.SendBufferSize = 1024 * 1024; //Do not use Nagle's Algorithm socket.NoDelay = true; //Establish connection asynchronously to enable connect timeout. IAsyncResult result = socket.BeginConnect(endPoint, null, null); bool success = result.AsyncWaitHandle.WaitOne(connectTimeout, false); if (!success) { try { socket.Close(); } catch { } throw new SocketException(); } socket.EndConnect(result); //Wraps two layers of streams around the socket for communication. stream = new BufferedStream(new NetworkStream(socket, false)); }
private Dictionary <string, string> stats(SocketPool pool) { if (pool == null) { return(null); } Dictionary <string, string> dic = new Dictionary <string, string>(); serverPool.Execute(pool, delegate(MSocket socket) { using (RedisCommand cmd = new RedisCommand(socket, 1, "info")) { } string result = socket.ReadResponse(); if (!string.IsNullOrEmpty(result) && result[0] == '$') { string line = null; while (true) { line = socket.ReadLine(); if (line == null) { break; } string[] s = line.Split(':'); dic.Add(s[0], s[1]); } } }); return(dic); }
/// <summary> /// This method executes the given delegate on a socket from the server that corresponds to the given hash. /// If anything causes an error, the given defaultValue will be returned instead. /// This method takes care of disposing the socket properly once the delegate has executed. /// </summary> internal T Execute <T>(uint hash, T defaultValue, UseSocket <T> use) { SocketPool pool = GetSocketPool(hash); if (pool.socketPoolBak == null && serverPoolBak != null) { //为主Socket池挂接备份的Socket池 pool.socketPoolBak = serverPoolBak.GetSocketPool(hash); } return(Execute(pool, defaultValue, use)); }
//private string clientName; /// <summary> /// Internal constructor. This method takes the array of hosts and sets up an internal list of socketpools. /// </summary> internal ServerPool(string[] hosts, CacheType serverType) { this.serverType = serverType;//服务的缓存类型(为了支持Redis的密码功能,在这里增加点依赖扩展。) hostDictionary = new Dictionary <uint, SocketPool>(); List <SocketPool> pools = new List <SocketPool>(); List <uint> keys = new List <uint>(); foreach (string hostItem in hosts)//遍历每一台主机。 { if (string.IsNullOrEmpty(hostItem)) { continue; } string[] items = hostItem.Split('-'); string pwd = ""; string host = items[0].Trim();; if (items.Length > 1) { pwd = items[1].Trim(); } //Create pool SocketPool pool = new SocketPool(this, host); pool.OnAfterSocketCreateEvent += new SocketPool.OnAfterSocketCreateDelegate(pool_OnAfterSocketCreateEvent); if (!string.IsNullOrEmpty(pwd)) { pool.password = pwd; } //Create 250 keys for this pool, store each key in the hostDictionary, as well as in the list of keys. for (int i = 0; i < 250; i++) { uint key = BitConverter.ToUInt32(new ModifiedFNV1_32().ComputeHash(Encoding.UTF8.GetBytes(host + "-" + i)), 0); if (!hostDictionary.ContainsKey(key)) { hostDictionary[key] = pool; keys.Add(key); } } pools.Add(pool); } //Hostlist should contain the list of all pools that has been created. hostList = pools.ToArray(); //Hostkeys should contain the list of all key for all pools that have been created. //This array forms the server key continuum that we use to lookup which server a //given item key hash should be assigned to. keys.Sort(); hostKeys = keys.ToArray(); }
private Dictionary <string, string> stats(SocketPool pool) { if (pool == null) { return(null); } Dictionary <string, string> result = new Dictionary <string, string>(); serverPool.Execute(pool, delegate(PooledSocket socket) { socket.Write("stats\r\n"); string line; while (!(line = socket.ReadResponse().TrimEnd('\0', '\r', '\n')).StartsWith("END")) { string[] s = line.Split(' '); result.Add(s[1], s[2]); } }); return(result); }
private object[] get(string command, string[] keys, bool keysAreChecked, uint[] hashes, out ulong[] uniques) { //Check arguments. if (keys == null || hashes == null) { throw new ArgumentException("Keys and hashes arrays must not be null."); } if (keys.Length != hashes.Length) { throw new ArgumentException("Keys and hashes arrays must be of the same length."); } uniques = new ulong[keys.Length]; //Avoid going through the server grouping if there's only one key. if (keys.Length == 1) { return(new object[] { get(command, keys[0], keysAreChecked, hashes[0], out uniques[0]) }); } //Check keys. if (!keysAreChecked) { for (int i = 0; i < keys.Length; i++) { checkKey(keys[i]); } } //Group the keys/hashes by server(pool) Dictionary <SocketPool, Dictionary <string, List <int> > > dict = new Dictionary <SocketPool, Dictionary <string, List <int> > >(); for (int i = 0; i < keys.Length; i++) { Dictionary <string, List <int> > getsForServer; SocketPool pool = serverPool.GetSocketPool(hashes[i]); if (!dict.TryGetValue(pool, out getsForServer)) { dict[pool] = getsForServer = new Dictionary <string, List <int> >(); } List <int> positions; if (!getsForServer.TryGetValue(keys[i], out positions)) { getsForServer[keyPrefix + keys[i]] = positions = new List <int>(); } positions.Add(i); } //Get the values object[] returnValues = new object[keys.Length]; ulong[] _uniques = new ulong[keys.Length]; foreach (KeyValuePair <SocketPool, Dictionary <string, List <int> > > kv in dict) { serverPool.Execute(kv.Key, delegate(PooledSocket socket) { //Build the get request StringBuilder getRequest = new StringBuilder(command); foreach (KeyValuePair <string, List <int> > key in kv.Value) { getRequest.Append(" "); getRequest.Append(key.Key); } getRequest.Append("\r\n"); //Send get request socket.Write(getRequest.ToString()); //Read values, one by one object gottenObject; string gottenKey; ulong unique; while (readValue(socket, out gottenObject, out gottenKey, out unique)) { foreach (int position in kv.Value[gottenKey]) { returnValues[position] = gottenObject; _uniques[position] = unique; } } }); } uniques = _uniques; return(returnValues); }
private Dictionary<string, string> stats(SocketPool pool) { if (pool == null) { return null; } Dictionary<string, string> result = new Dictionary<string, string>(); serverPool.Execute(pool, delegate(PooledSocket socket) { socket.Write("stats\r\n"); string line; while (!(line = socket.ReadResponse().TrimEnd('\0', '\r', '\n')).StartsWith("END")) { string[] s = line.Split(' '); result.Add(s[1], s[2]); } }); return result; }