示例#1
0
        /// <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();
        }
示例#2
0
        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));
        }
示例#3
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);
        }
示例#4
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();
                }
            }
        }
示例#5
0
        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));
        }
示例#6
0
        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);
        }
示例#7
0
        /// <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));
        }
示例#8
0
        //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);
        }
示例#11
0
 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;
 }