示例#1
0
        public static ICachedumpOperationResult Cachedump(this MemcachedClient client, int slab = 1, int limit = 0)
        {
            #region 反射获取 IServerPool 属性值
            Type         t                   = client.GetType();
            PropertyInfo prop_Pool           = t.GetProperty("Pool", BindingFlags.Instance | BindingFlags.NonPublic);
            PropertyInfo prop_KeyTransformer = t.GetProperty("KeyTransformer", BindingFlags.Instance | BindingFlags.NonPublic);

            IServerPool pool = prop_Pool.GetValue(client) as IServerPool;
            IMemcachedKeyTransformer keyTransformer = prop_KeyTransformer.GetValue(client) as IMemcachedKeyTransformer;
            #endregion

            string key = string.Format("{0} {1}", slab, limit);

            var hashedKey = keyTransformer.Transform(key.Replace(" ", "_"));
            var node      = pool.Locate(hashedKey);

            ICachedumpOperationResultFactory CachedumpOperationResultFactory = new DefaultCachedumpOperationResultFactory();
            var result = CachedumpOperationResultFactory.Create();

            if (node != null)
            {
                var command       = new CachedumpOperation(key);
                var commandResult = node.Execute(command);

                if (commandResult.Success)
                {
                    result.Value = new Dictionary <string, string>();

                    command.Result.ForEach(item =>
                    {
                        //item is:
                        //ITEM testKey2 [3 b; 1600335168 s]
                        //ITEM key_name [value_length b; expire_time | access_time s]
                        // 0     1      2             3  4                         5
                        //1.2.2- 访问时间(timestamp)
                        //1.2.4+ 过期时间(timestamp)
                        //如果是永不过期的key,expire_time会显示为服务器启动的时间

                        string[] parts = item.Split(' ');
                        result.Value.Add(parts[1], string.Join(" ", parts, 2, parts.Length - 2));
                    });
                    result.Pass();
                    return(result);
                }
                else
                {
                    commandResult.Combine(result);
                    return(result);
                }
            }
            result.Fail("Unable to locate node");
            return(result);
        }
示例#2
0
        protected override bool ExecuteAction()
        {
            // {hashed key -> normal key}: will be used when mapping the returned items back to the original keys
            Dictionary <string, string> hashedToReal = new Dictionary <string, string>(StringComparer.Ordinal);

            // {normal key -> hashed key}: we have to hash all keys anyway, so we better cache them to improve performance instead of doing the hashing later again
            Dictionary <string, string> realToHashed = new Dictionary <string, string>(StringComparer.Ordinal);

            IMemcachedKeyTransformer transformer = ServerPool.KeyTransformer;

            // and store them with the originals so we can map the returned items
            // to the original keys
            foreach (string s in keys)
            {
                string hashed = transformer.Transform(s);

                hashedToReal[hashed] = s;
                realToHashed[s]      = hashed;
            }

            // map each key to the appropriate server in the pool
            IDictionary <MemcachedNode, IList <string> > splitKeys = ServerPool.SplitKeys(keys);

            // we'll open 1 socket for each server
            List <PooledSocket> sockets = new List <PooledSocket>();

            try
            {
                // send a 'gets' to each server
                foreach (KeyValuePair <MemcachedNode, IList <string> > kp in splitKeys)
                {
                    // gets <keys>
                    //
                    // keys: key key key key
                    string[] command = new string[kp.Value.Count + 1];
                    command[0] = "gets";
                    kp.Value.CopyTo(command, 1);

                    for (int i = 1; i < command.Length; i++)
                    {
                        command[i] = realToHashed[command[i]];
                    }

                    PooledSocket socket = kp.Key.Acquire();
                    if (socket == null)
                    {
                        continue;
                    }

                    sockets.Add(socket);
                    socket.SendCommand(String.Join(" ", command));
                }

                Dictionary <string, object> retval = new Dictionary <string, object>(StringComparer.Ordinal);
                Dictionary <string, ulong>  cas    = new Dictionary <string, ulong>(StringComparer.Ordinal);

                // process each response and build a dictionary from the results
                foreach (PooledSocket socket in sockets)
                {
                    try
                    {
                        GetResponse r;

                        while ((r = GetHelper.ReadItem(socket)) != null)
                        {
                            string originalKey = hashedToReal[r.Key];

                            retval[originalKey] = ServerPool.Transcoder.Deserialize(r.Item);
                            cas[originalKey]    = r.CasValue;
                        }
                    }
                    catch (NotSupportedException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        log.Error(e);
                    }
                }

                result    = retval;
                casValues = cas;
            }
            finally
            {
                foreach (PooledSocket socket in sockets)
                {
                    ((IDisposable)socket).Dispose();
                }
            }

            return(true);
        }