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)); }
/// <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(); }
internal void Execute(SocketPool pool, UseSocket use) { PooledSocket 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(); } } }
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; }