예제 #1
0
        public ServerPool(IMemcachedClientConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration", "Invalid or missing pool configuration. Check if the enyim.com/memcached section or your custom section presents in the app/web.config.");
            }

            this.configuration = configuration;
            this.isAliveTimer  = new Timer(callback_isAliveTimer, null, (int)this.configuration.SocketPool.DeadTimeout.TotalMilliseconds, (int)this.configuration.SocketPool.DeadTimeout.TotalMilliseconds);

            // create the key transformer instance
            Type t = this.configuration.KeyTransformer;

            this.keyTransformer = (t == null) ? new DefaultKeyTransformer() : (IMemcachedKeyTransformer)Activator.CreateInstance(t);

            // create the item transcoder instance
            t = this.configuration.Transcoder;
            this.transcoder = (t == null) ? new DefaultTranscoder() : (ITranscoder)Activator.CreateInstance(t);


            // initialize the server list
            ISocketPoolConfiguration ispc = configuration.SocketPool;

            foreach (IPEndPoint ip in configuration.Servers)
            {
                this.workingServers.Add(new MemcachedNode(ip, ispc));
            }

            // (re)creates the locator
            this.RebuildIndexes();
        }
        public ServerPool(IMemcachedClientConfiguration configuration)
        {
            if (configuration == null)
                throw new ArgumentNullException("configuration", "Invalid or missing pool configuration. Check if the enyim.com/memcached section or your custom section presents in the app/web.config.");

            this.configuration = configuration;
            this.isAliveTimer = new Timer(callback_isAliveTimer, null, (int)this.configuration.SocketPool.DeadTimeout.TotalMilliseconds, (int)this.configuration.SocketPool.DeadTimeout.TotalMilliseconds);

            // create the key transformer instance
            Type t = this.configuration.KeyTransformer;
            this.keyTransformer = (t == null) ? new DefaultKeyTransformer() : (IMemcachedKeyTransformer)Enyim.Reflection.FastActivator.CreateInstance(t);

            // create the item transcoder instance
            t = this.configuration.Transcoder;
            this.transcoder = (t == null) ? new DefaultTranscoder() : (ITranscoder)Enyim.Reflection.FastActivator.CreateInstance(t);

            // initialize the server list

            foreach (IPEndPoint ip in configuration.Servers)
            {
                this.workingServers.Add(MemcachedNode.Factory.Get(ip, configuration));
            }

            // (re)creates the locator
            this.RebuildIndexes();
        }
        private MemcachedClientApiConfiguration(
            IEnumerable <IPEndPoint> servers,
            ISocketPoolConfiguration socketPoolConfiguration,
            IMemcachedKeyTransformer keyTransformer,
            IMemcachedNodeLocator nodeLocator,
            Func <IMemcachedNodeLocator> nodeLocatorFactory,
            ITranscoder transcoder,
            IAuthenticationConfiguration authentication,
            MemcachedProtocol protocol,
            IPerformanceMonitor performanceMonitor)
        {
            Condition.Requires(socketPoolConfiguration, "socket pool configuration").IsNotNull();
            Condition.Requires(keyTransformer, "key transformer").IsNotNull();
            Condition.Requires(transcoder, "transcoder").IsNotNull();
            Condition.Requires(authentication, "authentication").IsNotNull();
            Condition.Requires(nodeLocator, "node locator")
            .Evaluate(!(nodeLocator == null && nodeLocatorFactory == null),
                      "Both node locator and node locator factory are not set. Requires only one to be set.");
            Condition.Requires(nodeLocator, "node locator")
            .Evaluate(!(nodeLocator == null && nodeLocatorFactory == null),
                      "Both node locator and node locator are set. Requires only one to be set.");
            Condition.Requires(servers, "servers").IsNotNull();

            _socketPoolConfiguration = socketPoolConfiguration;
            _keyTransformer          = keyTransformer;
            _nodeLocator             = nodeLocator;
            _nodeLocatorFactory      = nodeLocatorFactory;
            _transcoder        = transcoder;
            _authentication    = authentication;
            PerformanceMonitor = performanceMonitor;
            Protocol           = protocol;
            _servers           = servers.ToList();
        }
        private MemcachedClientApiConfiguration(
			IEnumerable<IPEndPoint> servers,
			ISocketPoolConfiguration socketPoolConfiguration,
			IMemcachedKeyTransformer keyTransformer, 
			IMemcachedNodeLocator nodeLocator, 
			Func<IMemcachedNodeLocator> nodeLocatorFactory, 
			ITranscoder transcoder, 
			IAuthenticationConfiguration authentication, 
			MemcachedProtocol protocol, 
			IPerformanceMonitor performanceMonitor)
        {
            Condition.Requires(socketPoolConfiguration, "socket pool configuration").IsNotNull();
            Condition.Requires(keyTransformer, "key transformer").IsNotNull();
            Condition.Requires(transcoder, "transcoder").IsNotNull();
            Condition.Requires(authentication, "authentication").IsNotNull();
            Condition.Requires(nodeLocator, "node locator")
                .Evaluate(!(nodeLocator == null && nodeLocatorFactory == null),
                "Both node locator and node locator factory are not set. Requires only one to be set.");
            Condition.Requires(nodeLocator, "node locator")
                .Evaluate(!(nodeLocator == null && nodeLocatorFactory == null),
                "Both node locator and node locator are set. Requires only one to be set.");
            Condition.Requires(servers, "servers").IsNotNull();

            _socketPoolConfiguration = socketPoolConfiguration;
            _keyTransformer = keyTransformer;
            _nodeLocator = nodeLocator;
            _nodeLocatorFactory = nodeLocatorFactory;
            _transcoder = transcoder;
            _authentication = authentication;
            PerformanceMonitor = performanceMonitor;
            Protocol = protocol;
            _servers = servers.ToList();
        }
예제 #5
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);
        }
예제 #6
0
		public MemcachedClient(IServerPool pool, IMemcachedKeyTransformer keyTransformer, ITranscoder transcoder, IPerformanceMonitor performanceMonitor)
		{
			if (pool == null) throw new ArgumentNullException("pool");
			if (keyTransformer == null) throw new ArgumentNullException("keyTransformer");
			if (transcoder == null) throw new ArgumentNullException("transcoder");

			this.performanceMonitor = performanceMonitor;
			this.keyTransformer = keyTransformer;
			this.transcoder = transcoder;

			this.pool = pool;
			this.StartPool();
		}
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:MemcachedClient"/> using the specified configuration instance.
        /// </summary>
        /// <param name="configuration">The memcachedClient configuration.</param>
        public MemcachedClient(IMemcachedClientConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }

            this.keyTransformer     = configuration.CreateKeyTransformer() ?? new DefaultKeyTransformer();
            this.transcoder         = configuration.CreateTranscoder() ?? new DefaultTranscoder();
            this.performanceMonitor = configuration.CreatePerformanceMonitor();

            this.pool = configuration.CreatePool();
            this.pool.Start();
        }
예제 #8
0
		/// <summary>
		/// Initializes a new instance of the <see cref="T:MemcachedClient"/> using the specified configuration instance.
		/// </summary>
		/// <param name="configuration">The client configuration.</param>
		public MemcachedClient(IMemcachedClientConfiguration configuration)
		{
			if (configuration == null)
				throw new ArgumentNullException("configuration");

			this.keyTransformer = configuration.CreateKeyTransformer() ?? new DefaultKeyTransformer();
			this.transcoder = configuration.CreateTranscoder() ?? new DefaultTranscoder();
			this.performanceMonitor = configuration.CreatePerformanceMonitor();

			this.pool = configuration.CreatePool();
			this.pool.NodeFailed += (n) => { var f = this.NodeFailed; if (f != null) f(n); };
			this.StartPool();

			StoreOperationResultFactory = new DefaultStoreOperationResultFactory();
			GetOperationResultFactory = new DefaultGetOperationResultFactory();
			MutateOperationResultFactory = new DefaultMutateOperationResultFactory();
			ConcatOperationResultFactory = new DefaultConcatOperationResultFactory();
			RemoveOperationResultFactory = new DefaultRemoveOperationResultFactory();
		}
예제 #9
0
        public EasyCachingMemcachedClientConfiguration(
            string name,
            ILoggerFactory loggerFactory,
            MemcachedOptions optionsAccessor,
            IEnumerable <EasyCachingTranscoder> transcoders = null,
            IMemcachedKeyTransformer keyTransformer         = null)
        {
            this._name = name;
            if (optionsAccessor == null)
            {
                throw new ArgumentNullException(nameof(optionsAccessor));
            }

            _logger = loggerFactory.CreateLogger <EasyCachingMemcachedClientConfiguration>();

            var options = optionsAccessor.DBConfig;

            ConfigureServers(options);

            SocketPool = new SocketPoolConfiguration();
            if (options.SocketPool != null)
            {
                options.SocketPool.CheckPoolSize();
                options.SocketPool.CheckTimeout();

                SocketPool.MinPoolSize = options.SocketPool.MinPoolSize;
                _logger.LogInformation($"{nameof(SocketPool.MinPoolSize)}: {SocketPool.MinPoolSize}");

                SocketPool.MaxPoolSize = options.SocketPool.MaxPoolSize;
                _logger.LogInformation($"{nameof(SocketPool.MaxPoolSize)}: {SocketPool.MaxPoolSize}");

                SocketPool.ConnectionTimeout = options.SocketPool.ConnectionTimeout;
                _logger.LogInformation($"{nameof(SocketPool.ConnectionTimeout)}: {SocketPool.ConnectionTimeout}");

                SocketPool.ReceiveTimeout = options.SocketPool.ReceiveTimeout;
                _logger.LogInformation($"{nameof(SocketPool.ReceiveTimeout)}: {SocketPool.ReceiveTimeout}");

                SocketPool.DeadTimeout = options.SocketPool.DeadTimeout;
                _logger.LogInformation($"{nameof(SocketPool.DeadTimeout)}: {SocketPool.DeadTimeout}");

                SocketPool.QueueTimeout = options.SocketPool.QueueTimeout;
                _logger.LogInformation($"{nameof(SocketPool.QueueTimeout)}: {SocketPool.QueueTimeout}");

                SocketPool.InitPoolTimeout = options.SocketPool.InitPoolTimeout;
            }

            Protocol = options.Protocol;

            if (options.Authentication != null && !string.IsNullOrEmpty(options.Authentication.Type))
            {
                try
                {
                    var authenticationType = Type.GetType(options.Authentication.Type);
                    if (authenticationType != null)
                    {
                        _logger.LogDebug($"Authentication type is {authenticationType}.");

                        Authentication      = new AuthenticationConfiguration();
                        Authentication.Type = authenticationType;
                        foreach (var parameter in options.Authentication.Parameters)
                        {
                            Authentication.Parameters[parameter.Key] = parameter.Value;
                            _logger.LogDebug($"Authentication {parameter.Key} is '{parameter.Value}'.");
                        }
                    }
                    else
                    {
                        _logger.LogError($"Unable to load authentication type {options.Authentication.Type}.");
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(new EventId(), ex, $"Unable to load authentication type {options.Authentication.Type}.");
                }
            }

            if (keyTransformer != null)
            {
                this.KeyTransformer = keyTransformer;
                _logger.LogDebug($"Use KeyTransformer Type : '{keyTransformer.ToString()}'");
            }

            if (NodeLocator == null)
            {
                NodeLocator = options.Servers.Count > 1 ? typeof(DefaultNodeLocator) : typeof(SingleNodeLocator);
            }

            if (transcoders != null)
            {
                EasyCachingTranscoder coder = null;

                if (string.IsNullOrWhiteSpace(optionsAccessor.SerializerName))
                {
                    coder = transcoders.FirstOrDefault(x => x.Name.Equals(_name));
                }
                else
                {
                    coder = transcoders.FirstOrDefault(x => x.Name.Equals(optionsAccessor.SerializerName));
                }

                if (coder != null)
                {
                    this._transcoder = coder;
                    _logger.LogDebug($"Use Transcoder Type : '{coder.ToString()}'");
                }
            }

            if (options.NodeLocatorFactory != null)
            {
                NodeLocatorFactory = options.NodeLocatorFactory;
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="T:MemcachedClientConfiguration"/> class.
        /// </summary>
        public EasyCachingMemcachedClientConfiguration(
            ILoggerFactory loggerFactory,
            IOptionsMonitor <MemcachedOptions> optionsAccessor,
            ITranscoder transcoder = null,
            IMemcachedKeyTransformer keyTransformer = null)
        {
            if (optionsAccessor == null)
            {
                throw new ArgumentNullException(nameof(optionsAccessor));
            }

            _logger = loggerFactory.CreateLogger <EasyCachingMemcachedClientConfiguration>();

            var options = optionsAccessor.CurrentValue.DBConfig;

            Servers = new List <DnsEndPoint>();
            foreach (var server in options.Servers)
            {
                Servers.Add(new DnsEndPoint(server.Address, server.Port));
            }

            SocketPool = new SocketPoolConfiguration();
            if (options.SocketPool != null)
            {
                options.SocketPool.CheckPoolSize();
                options.SocketPool.CheckTimeout();

                SocketPool.MinPoolSize = options.SocketPool.MinPoolSize;
                _logger.LogInformation($"{nameof(SocketPool.MinPoolSize)}: {SocketPool.MinPoolSize}");

                SocketPool.MaxPoolSize = options.SocketPool.MaxPoolSize;
                _logger.LogInformation($"{nameof(SocketPool.MaxPoolSize)}: {SocketPool.MaxPoolSize}");

                SocketPool.ConnectionTimeout = options.SocketPool.ConnectionTimeout;
                _logger.LogInformation($"{nameof(SocketPool.ConnectionTimeout)}: {SocketPool.ConnectionTimeout}");

                SocketPool.ReceiveTimeout = options.SocketPool.ReceiveTimeout;
                _logger.LogInformation($"{nameof(SocketPool.ReceiveTimeout)}: {SocketPool.ReceiveTimeout}");

                SocketPool.DeadTimeout = options.SocketPool.DeadTimeout;
                _logger.LogInformation($"{nameof(SocketPool.DeadTimeout)}: {SocketPool.DeadTimeout}");

                SocketPool.QueueTimeout = options.SocketPool.QueueTimeout;
                _logger.LogInformation($"{nameof(SocketPool.QueueTimeout)}: {SocketPool.QueueTimeout}");
            }

            Protocol = options.Protocol;

            if (options.Authentication != null && !string.IsNullOrEmpty(options.Authentication.Type))
            {
                try
                {
                    var authenticationType = Type.GetType(options.Authentication.Type);
                    if (authenticationType != null)
                    {
                        _logger.LogDebug($"Authentication type is {authenticationType}.");

                        Authentication      = new AuthenticationConfiguration();
                        Authentication.Type = authenticationType;
                        foreach (var parameter in options.Authentication.Parameters)
                        {
                            Authentication.Parameters[parameter.Key] = parameter.Value;
                            _logger.LogDebug($"Authentication {parameter.Key} is '{parameter.Value}'.");
                        }
                    }
                    else
                    {
                        _logger.LogError($"Unable to load authentication type {options.Authentication.Type}.");
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(new EventId(), ex, $"Unable to load authentication type {options.Authentication.Type}.");
                }
            }

            if (keyTransformer != null)
            {
                this.KeyTransformer = keyTransformer;
                _logger.LogDebug($"Use KeyTransformer Type : '{keyTransformer.ToString()}'");
            }

            if (NodeLocator == null)
            {
                NodeLocator = options.Servers.Count > 1 ? typeof(DefaultNodeLocator) : typeof(SingleNodeLocator);
            }

            if (transcoder != null)
            {
                this._transcoder = transcoder;
                _logger.LogDebug($"Use Transcoder Type : '{transcoder.ToString()}'");
            }

            if (options.NodeLocatorFactory != null)
            {
                NodeLocatorFactory = options.NodeLocatorFactory;
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="T:MemcachedClientConfiguration"/> class.
        /// </summary>
        public MemcachedClientConfiguration(
            ILoggerFactory loggerFactory,
            IOptions <MemcachedClientOptions> optionsAccessor,
            IConfiguration configuration            = null,
            ITranscoder transcoder                  = null,
            IMemcachedKeyTransformer keyTransformer = null)
        {
            if (optionsAccessor == null)
            {
                throw new ArgumentNullException(nameof(optionsAccessor));
            }

            _logger = loggerFactory.CreateLogger <MemcachedClientConfiguration>();

            var options = optionsAccessor.Value;

            if ((options == null || options.Servers.Count == 0) && configuration != null)
            {
                var section = configuration.GetSection("enyimMemcached");
                if (section.Exists())
                {
                    section.Bind(options);
                }
                else
                {
                    _logger.LogWarning($"No enyimMemcached setting in appsetting.json. Use default configuration");
                    options.AddDefaultServer();
                }
            }

            ConfigureServers(options);

            SocketPool = new SocketPoolConfiguration();
            if (options.SocketPool != null)
            {
                options.SocketPool.CheckPoolSize();
                options.SocketPool.CheckTimeout();

                SocketPool.MinPoolSize = options.SocketPool.MinPoolSize;
                _logger.LogInformation($"{nameof(SocketPool.MinPoolSize)}: {SocketPool.MinPoolSize}");

                SocketPool.MaxPoolSize = options.SocketPool.MaxPoolSize;
                _logger.LogInformation($"{nameof(SocketPool.MaxPoolSize)}: {SocketPool.MaxPoolSize}");

                SocketPool.ConnectionTimeout = options.SocketPool.ConnectionTimeout;
                _logger.LogInformation($"{nameof(SocketPool.ConnectionTimeout)}: {SocketPool.ConnectionTimeout}");

                SocketPool.ReceiveTimeout = options.SocketPool.ReceiveTimeout;
                _logger.LogInformation($"{nameof(SocketPool.ReceiveTimeout)}: {SocketPool.ReceiveTimeout}");

                SocketPool.DeadTimeout = options.SocketPool.DeadTimeout;
                _logger.LogInformation($"{nameof(SocketPool.DeadTimeout)}: {SocketPool.DeadTimeout}");

                SocketPool.QueueTimeout = options.SocketPool.QueueTimeout;
                _logger.LogInformation($"{nameof(SocketPool.QueueTimeout)}: {SocketPool.QueueTimeout}");

                SocketPool.InitPoolTimeout = options.SocketPool.InitPoolTimeout;
            }

            Protocol = options.Protocol;

            if (options.Authentication != null && !string.IsNullOrEmpty(options.Authentication.Type))
            {
                try
                {
                    var authenticationType = Type.GetType(options.Authentication.Type);
                    if (authenticationType != null)
                    {
                        _logger.LogDebug($"Authentication type is {authenticationType}.");

                        Authentication      = new AuthenticationConfiguration();
                        Authentication.Type = authenticationType;
                        foreach (var parameter in options.Authentication.Parameters)
                        {
                            Authentication.Parameters[parameter.Key] = parameter.Value;
                            _logger.LogDebug($"Authentication {parameter.Key} is '{parameter.Value}'.");
                        }
                    }
                    else
                    {
                        _logger.LogError($"Unable to load authentication type {options.Authentication.Type}.");
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(new EventId(), ex, $"Unable to load authentication type {options.Authentication.Type}.");
                }
            }

            if (!string.IsNullOrEmpty(options.KeyTransformer))
            {
                try
                {
                    var keyTransformerType = Type.GetType(options.KeyTransformer);
                    if (keyTransformerType != null)
                    {
                        KeyTransformer = Activator.CreateInstance(keyTransformerType) as IMemcachedKeyTransformer;
                        _logger.LogDebug($"Use '{options.KeyTransformer}' KeyTransformer");
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(new EventId(), ex, $"Unable to load '{options.KeyTransformer}' KeyTransformer");
                }
            }
            else if (keyTransformer != null)
            {
                this._keyTransformer = keyTransformer;
                _logger.LogDebug($"Use KeyTransformer Type : '{keyTransformer.ToString()}'");
            }

            if (NodeLocator == null)
            {
                NodeLocator = options.Servers.Count > 1 ? typeof(DefaultNodeLocator) : typeof(SingleNodeLocator);
            }

            if (!string.IsNullOrEmpty(options.Transcoder))
            {
                try
                {
                    if (options.Transcoder == "BinaryFormatterTranscoder")
                    {
                        options.Transcoder = "Enyim.Caching.Memcached.Transcoders.BinaryFormatterTranscoder";
                    }

                    var transcoderType = Type.GetType(options.Transcoder);
                    if (transcoderType != null)
                    {
                        Transcoder = Activator.CreateInstance(transcoderType) as ITranscoder;
                        _logger.LogDebug($"Use '{options.Transcoder}'");
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(new EventId(), ex, $"Unable to load '{options.Transcoder}'");
                }
            }
            else if (transcoder != null)
            {
                this._transcoder = transcoder;
                _logger.LogDebug($"Use Transcoder Type : '{transcoder.ToString()}'");
            }

            if (options.NodeLocatorFactory != null)
            {
                NodeLocatorFactory = options.NodeLocatorFactory;
            }
        }
 public MemcachedClient(IServerPool pool, IMemcachedKeyTransformer keyTransformer, ITranscoder transcoder)
     : this(pool, keyTransformer, transcoder, null)
 {
 }
예제 #13
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);
        }