Inheritance: IDisposable
示例#1
0
		public static void FinishCurrent(PooledSocket socket)
		{
			string response = socket.ReadResponse();

			if (String.Compare(response, "END", StringComparison.Ordinal) != 0)
				throw new MemcachedClientException("No END was received.");
		}
示例#2
0
		public override void Dispose()
		{
			if (this.socket != null)
			{
				((IDisposable)this.socket).Dispose();
				this.socket = null;
			}

			base.Dispose();
		}
示例#3
0
			public AsyncSocketHelper(PooledSocket socket)
			{
				this.socket = socket;
				this.asyncBuffer = new SlidingBuffer(ChunkSize);

				this.readEvent = new SocketAsyncEventArgs();
				this.readEvent.Completed += new EventHandler<SocketAsyncEventArgs>(AsyncReadCompleted);
				this.readEvent.SetBuffer(new byte[ChunkSize], 0, ChunkSize);

				this.readInProgressEvent = new ManualResetEvent(false);
			}
        public override void Dispose()
        {
            GC.SuppressFinalize(this);

            if (this.socket != null)
            {
                ((IDisposable)this.socket).Dispose();
                this.socket = null;
            }

            base.Dispose();
        }
        public override void Dispose()
        {
            GC.SuppressFinalize(this);

            if (this.socket != null)
            {
                ((IDisposable)this.socket).Dispose();
                this.socket = null;
            }

            base.Dispose();
        }
        protected override bool ExecuteAction()
        {
            PooledSocket socket = this.Socket;

            if (socket == null)
            {
                return(false);
            }

            socket.SendCommand("delete " + this.HashedKey);

            return(String.Compare(socket.ReadResponse(), "DELETED", StringComparison.Ordinal) == 0);
        }
示例#7
0
 protected internal virtual PooledSocket CreateSocket()
 {
     try
     {
         var ps = new PooledSocket(this.endPoint, this.config.ConnectionTimeout, this.config.ReceiveTimeout, _logger);
         ps.Connect();
         return(ps);
     }
     catch (Exception ex)
     {
         _logger.LogError(ex, $"Create {nameof(PooledSocket)}");
         throw;
     }
 }
示例#8
0
        /// <summary>
        /// Sends the command to the server. The trailing \r\n is automatically appended.
        /// </summary>
        /// <param name="value">The command to be sent to the server.</param>
        public void SendCommand(string value)
        {
            this.CheckDisposed();
            //this.CheckThread();

            if (log.IsDebugEnabled)
            {
                log.Debug("SendCommand: " + value);
            }

            // send the whole command with only one Write
            // since Nagle is disabled on the socket this is more efficient than
            // Write(command), Write("\r\n")
            this.Write(PooledSocket.GetCommandBuffer(value));
        }
示例#9
0
        protected internal virtual async Task <PooledSocket> CreateSocketAsync()
        {
            try
            {
                var ps = new PooledSocket(this.endPoint, this.config.ConnectionTimeout, this.config.ReceiveTimeout, _logger);
                await ps.ConnectAsync();

                return(ps);
            }
            catch (Exception ex)
            {
                _logger.LogError(new EventId(this.GetHashCode(), nameof(MemcachedNode)), ex, $"Create {nameof(PooledSocket)}");
                throw;
            }
        }
示例#10
0
        protected override bool ExecuteAction()
        {
            foreach (MemcachedNode server in this.ServerPool.WorkingServers)
            {
                using (PooledSocket ps = server.Acquire())
                {
                    if (ps != null)
                    {
                        ps.SendCommand("flush_all");
                    }
                }
            }

            return(true);
        }
示例#11
0
            /// <summary>
            /// Releases an item back into the pool
            /// </summary>
            /// <param name="socket"></param>
            private void ReleaseSocket(PooledSocket socket)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Releasing socket " + socket.InstanceId);
                    log.Debug("Are we alive? " + this.isAlive);
                }

                if (this.isAlive)
                {
                    // is it still working (i.e. the server is still connected)
                    if (socket.IsAlive)
                    {
                        // mark the item as free
                        this.freeItems.Push(socket);
                    }
                    else
                    {
                        // kill this item
                        //socket.Destroy();
                        socket.Dispose();

                        // mark ourselves as not working for a while
                        this.MarkAsDead();
                    }
                }
                else
                {
                    // one of our previous sockets has died, so probably all of them
                    // are dead. so, kill the socket (this will eventually clear the pool as well)
                    //socket.Destroy();
                    socket.Dispose();
                }

                // In any event, we want to let any waiters know that we can create a new
                // socket:
                if (semaphore != null)
                {
                    try
                    {
                        semaphore.Release();
                    }
                    catch (ObjectDisposedException e)
                    {
                        log.Error(e);
                    }
                }
            }
示例#12
0
        protected internal virtual async Task <PooledSocket> CreateSocketAsync()
        {
            try
            {
                var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger);
                await ps.ConnectAsync();

                return(ps);
            }
            catch (Exception ex)
            {
                var endPointStr = _endPoint.ToString().Replace("Unspecified/", string.Empty);
                _logger.LogError(ex, $"Failed to {nameof(CreateSocketAsync)} to {endPointStr}");
                throw;
            }
        }
示例#13
0
		public static GetResponse ReadItem(PooledSocket socket)
		{
			string description = socket.ReadResponse();

			if (String.Compare(description, "END", StringComparison.Ordinal) == 0)
				return null;

			if (description.Length < 6 || String.Compare(description, 0, "VALUE ", 0, 6, StringComparison.Ordinal) != 0)
				throw new MemcachedClientException("No VALUE response received.\r\n" + description);

			ulong cas = 0;
			string[] parts = description.Split(' ');

			// response is:
			// VALUE <key> <flags> <bytes> [<cas unique>]
			// 0     1     2       3       4
			//
			// cas only exists in 1.2.4+
			//
			if (parts.Length == 5)
			{
				if (!UInt64.TryParse(parts[4], out cas))
					throw new MemcachedClientException("Invalid CAS VALUE received.");

			}
			else if (parts.Length < 4)
			{
				throw new MemcachedClientException("Invalid VALUE response received: " + description);
			}

			ushort flags = UInt16.Parse(parts[2], CultureInfo.InvariantCulture);
			int length = Int32.Parse(parts[3], CultureInfo.InvariantCulture);

			byte[] allData = new byte[length];
			byte[] eod = new byte[2];

			socket.Read(allData, 0, length);
			socket.Read(eod, 0, 2); // data is terminated by \r\n

			GetResponse retval = new GetResponse(parts[1], flags, cas, allData);

			if (log.IsDebugEnabled)
				log.DebugFormat("Received value. Data type: {0}, size: {1}.", retval.Item.Flag, retval.Item.Data.Count);

			return retval;
		}
        protected override bool ExecuteAction()
        {
            PooledSocket socket = this.Socket;

            if (socket == null)
            {
                return(false);
            }

            socket.SendCommand(String.Concat("incr ", this.HashedKey, " ", this.amount.ToString(CultureInfo.InvariantCulture)));

            string response = socket.ReadResponse();

            //maybe we should throw an exception when the item is not found?
            if (String.Compare(response, "NOT_FOUND", StringComparison.Ordinal) == 0)
            {
                return(false);
            }

            return(UInt32.TryParse(response, out this.result));
        }
示例#15
0
        protected override bool ExecuteAction()
        {
            PooledSocket socket = this.Socket;

            if (socket == null)
            {
                return(false);
            }

            socket.SendCommand("get " + this.HashedKey);

            GetResponse r = GetHelper.ReadItem(this.Socket);

            if (r != null)
            {
                this.result = this.ServerPool.Transcoder.Deserialize(r.Item);
                GetHelper.FinishCurrent(this.Socket);
            }

            return(true);
        }
            /// <summary>
            /// Releases an item back into the pool
            /// </summary>
            /// <param name="socket"></param>
            private void ReleaseSocket(PooledSocket socket)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug("Releasing socket " + socket.InstanceId);
                    Log.Debug("Are we alive? " + isAlive);
                }

                if (isAlive)
                {
                    // is it still working (i.e. the server is still connected)
                    if (socket.IsAlive)
                    {
                        // mark the item as free
                        freeItems.Enqueue(socket);

                        // there can be a race condition (see the count check in acquire)
                        // not sure what to do about it
                        Interlocked.Decrement(ref workingCount);

                        // signal the event so if someone is waiting for it can reuse this item
                        itemReleasedEvent.Set();
                    }
                    else
                    {
                        // kill this item
                        socket.Destroy();

                        // mark ourselves as not working for a while
                        MarkAsDead();
                    }
                }
                else
                {
                    // one of our previous sockets has died, so probably all of them are dead
                    // kill the socket thus clearing the pool, and after we become alive
                    // we'll fill the pool with working sockets
                    socket.Destroy();
                }
            }
示例#17
0
            /// <summary>
            /// Releases an item back into the pool
            /// </summary>
            /// <param name="socket"></param>
            private void ReleaseSocket(PooledSocket socket)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Releasing socket " + socket.InstanceId);
                    log.Debug("Are we alive? " + this.isAlive);
                }

                if (this.isAlive)
                {
                    // is it still working (i.e. the server is still connected)
                    if (socket.IsAlive)
                    {
                        // mark the item as free
                        this.freeItems.Push(socket);

                        // signal the event so if someone is waiting for it can reuse this item
                        this.semaphore.Release();
                    }
                    else
                    {
                        // kill this item
                        socket.Destroy();

                        // mark ourselves as not working for a while
                        this.MarkAsDead();

                        // make sure to signal the Acquire so it can create a new conenction
                        // if the failure policy keeps the pool alive
                        this.semaphore.Release();
                    }
                }
                else
                {
                    // one of our previous sockets has died, so probably all of them
                    // are dead. so, kill the socket (this will eventually clear the pool as well)
                    socket.Destroy();
                }
            }
        protected override IOperationResult ReadResponse(PooledSocket socket)
        {
            var response = new ObserveResponse();
            var result = new ObserveOperationResult();
            var retval = false;

            if (response.Read(socket))
            {
                retval = true;
                result.Cas = response.Cas;
                result.StatusCode = StatusCode;
                result.Key = response.Key;
                result.KeyState = response.KeyState;
                result.PersistenceStats = response.PersistenceStats;
                result.ReplicationStats = response.ReplicationStats;
            }

            this.StatusCode = response.StatusCode.ToStatusCode();

            result.PassOrFail(retval, ResultHelper.ProcessResponseData(response.Data, "Failed: "));
            return result;
        }
            /// <summary>
            /// Releases an item back into the pool
            /// </summary>
            /// <param name="socket"></param>
            void ReleaseSocket(PooledSocket socket)
            {
                if (this._logger.IsEnabled(LogLevel.Trace))
                {
                    this._logger.LogDebug($"Releasing socket ({socket.InstanceID}) - Alive: {this.IsAlive}");
                }

                if (this.IsAlive)
                {
                    // is it still working (i.e. the server is still connected)
                    if (socket.IsAlive)
                    {
                        // mark the item as free
                        this._freeItems.Push(socket);

                        // signal the event so if someone is waiting for it can reuse this item
                        this._semaphore.Release();
                    }
                    else
                    {
                        // kill this item
                        socket.Destroy();

                        // mark ourselves as not working for a while
                        this.MarkAsDead();

                        // make sure to signal the Acquire so it can create a new conenction
                        // if the failure policy keeps the pool alive
                        this._semaphore.Release();
                    }
                }
                else
                {
                    // one of our previous sockets has died, so probably all of them
                    // are dead. so, kill the socket (this will eventually clear the pool as well)
                    socket.Destroy();
                }
            }
示例#20
0
            /// <summary>
            /// Acquires a new item from the sockIOPool
            /// </summary>
            /// <returns>An <see cref="T:PooledSocket"/> instance which is connected to the memcached server, or <value>null</value> if the sockIOPool is dead.</returns>
            public PooledSocket Acquire()
            {
                bool hasDebug = log.IsDebugEnabled;

                if (hasDebug)
                {
                    log.Debug("Acquiring stream from pool. " + this.endPoint);
                }

                if (!this.isAlive || this.isDisposed)
                {
                    if (hasDebug)
                    {
                        log.Debug("Pool is dead or disposed, returning null. " + this.endPoint);
                    }

                    return(null);
                }

                PooledSocket retval = null;

                if (!this.semaphore.WaitOne(this.config.QueueTimeout))
                {
                    if (hasDebug)
                    {
                        log.Debug("Pool is full, timeouting. " + this.endPoint);
                    }

                    // everyone is so busy
                    throw new TimeoutException();
                }

                // maybe we died while waiting
                if (!this.isAlive)
                {
                    if (hasDebug)
                    {
                        log.Debug("Pool is dead, returning null. " + this.endPoint);
                    }

                    return(null);
                }

                // do we have free items?
                if (this.freeItems.Dequeue(out retval))
                {
                    #region [ get it from the sockIOPool         ]

                    try
                    {
                        retval.Reset();

                        if (hasDebug)
                        {
                            log.Debug("Socket was reset. " + retval.InstanceId);
                        }

                        return(retval);
                    }
                    catch (Exception e)
                    {
                        log.Error("Failed to reset an acquired socket.", e);

                        this.MarkAsDead();

                        return(null);
                    }

                    #endregion
                }

                // free item sockIOPool is empty
                if (hasDebug)
                {
                    log.Debug("Could not get a socket from the pool, Creating a new item. " + this.endPoint);
                }

                try
                {
                    // okay, create the new item
                    retval = this.CreateSocket();
                }
                catch (Exception e)
                {
                    log.Error("Failed to create socket. " + this.endPoint, e);
                    this.MarkAsDead();

                    return(null);
                }

                if (hasDebug)
                {
                    log.Debug("Done.");
                }

                return(retval);
            }
示例#21
0
        protected override bool ReadResponseAsync(PooledSocket socket, Action<bool> next)
        {
            var response = new BinaryResponse();

            bool ioPending;
            var retval = response.ReadAsync(socket, (readSuccess) =>
                            {
                                if (readSuccess) this.DecodeResult(response.Data);
                                next(readSuccess);
                            }, out ioPending);

            if (!ioPending && retval)
                this.Result = this.DecodeResult(response.Data);

            return retval;
        }
示例#22
0
        protected internal virtual PooledSocket CreateSocket()
        {
            PooledSocket retval = new PooledSocket(this.endPoint, this.config.ConnectionTimeout, this.config.ReceiveTimeout);

            return(retval);
        }
 protected override bool ReadResponseAsync(PooledSocket socket, Action<bool> next)
 {
     throw new NotImplementedException();
 }
        protected override IOperationResult ReadResponse(PooledSocket socket)
        {
            var response = new BinaryResponse();
            var result = new BinaryOperationResult();

            if (response.Read(socket))
            {
                this.Result = DecodeResult(response.Data);

                result.Pass();
                return result;
            }

            result.Fail("Processing of response failed");
            return result;
        }
示例#25
0
        protected override bool ReadResponse(PooledSocket socket)
        {
            var response = new BinaryResponse();
            if (response.Read(socket))
            {
                this.Result = DecodeResult(response.Data);

                return true;
            }

            return false;
        }
示例#26
0
        protected override bool ExecuteAction()
        {
            Dictionary <IPEndPoint, Dictionary <string, string> > retval = new Dictionary <IPEndPoint, Dictionary <string, string> >();

            foreach (MemcachedNode server in this.ServerPool.WorkingServers)
            {
                using (PooledSocket ps = server.Acquire())
                {
                    if (ps == null)
                    {
                        continue;
                    }

                    ps.SendCommand("stats");

                    Dictionary <string, string> serverData = new Dictionary <string, string>(StringComparer.Ordinal);

                    while (true)
                    {
                        string line = ps.ReadResponse();

                        // stat values are terminated by END
                        if (String.Compare(line, "END", StringComparison.Ordinal) == 0)
                        {
                            break;
                        }

                        // expected response is STAT item_name item_value
                        if (line.Length < 6 || String.Compare(line, 0, "STAT ", 0, 5, StringComparison.Ordinal) != 0)
                        {
                            if (log.IsWarnEnabled)
                            {
                                log.Warn("Unknow response: " + line);
                            }

                            continue;
                        }

                        // get the key&value
                        string[] parts = line.Remove(0, 5).Split(' ');
                        if (parts.Length != 2)
                        {
                            if (log.IsWarnEnabled)
                            {
                                log.Warn("Unknow response: " + line);
                            }

                            continue;
                        }

                        // store the stat item
                        serverData[parts[0]] = parts[1];
                    }

                    retval[server.EndPoint] = serverData;
                }
            }

            this.results = new ServerStats(retval);

            return(true);
        }
示例#27
0
            /// <summary>
            /// Acquires a new item from the pool
            /// </summary>
            /// <returns>An <see cref="T:PooledSocket"/> instance which is connected to the memcached server, or <value>null</value> if the pool is dead.</returns>
            public PooledSocket Acquire()
            {
                bool hasDebug = log.IsDebugEnabled;

                if (hasDebug)
                {
                    log.Debug("Acquiring stream from pool. " + this.endPoint);
                }

                if (!this.isAlive || this.isDisposed)
                {
                    if (hasDebug)
                    {
                        log.Debug("Pool is dead or disposed, returning null. " + this.endPoint);
                    }

                    return(null);
                }

                PooledSocket retval = null;

                if (!this.semaphore.WaitOne(this.queueTimeout))
                {
                    if (hasDebug)
                    {
                        log.Debug("Pool is full, timeouting. " + this.endPoint);
                    }

                    // everyone is so busy
                    throw new TimeoutException();
                }

                // maybe we died while waiting
                if (!this.isAlive)
                {
                    if (hasDebug)
                    {
                        log.Debug("Pool is dead, returning null. " + this.endPoint);
                    }

                    return(null);
                }

                // do we have free items?
                if (this.freeItems.TryPop(out retval))
                {
                    #region [ get it from the pool         ]

                    try
                    {
                        retval.Reset();

                        if (hasDebug)
                        {
                            log.Debug("Socket was reset. " + retval.InstanceId);
                        }

                        return(retval);
                    }
                    catch (Exception e)
                    {
                        log.Error("Failed to reset an acquired socket.", e);

                        this.MarkAsDead();

                        return(null);
                    }

                    #endregion
                }

                // free item pool is empty
                if (hasDebug)
                {
                    log.Debug("Could not get a socket from the pool, Creating a new item. " + this.endPoint);
                }

                try
                {
                    // okay, create the new item
                    retval = this.CreateSocket();
                }
                catch (Exception e)
                {
                    log.Error("Failed to create socket. " + this.endPoint, e);

                    // eventhough this item failed the failure policy may keep the pool alive
                    // so we need to make sure to release the semaphore, so new connections can be
                    // acquired or created (otherwise dead conenctions would "fill up" the pool
                    // while the FP pretends that the pool is healthy)
                    semaphore.Release();

                    this.MarkAsDead();

                    return(null);
                }

                if (hasDebug)
                {
                    log.Debug("Done.");
                }

                return(retval);
            }
示例#28
0
            /// <summary>
            /// Acquires a new item from the pool
            /// </summary>
            /// <returns>An <see cref="T:PooledSocket"/> instance which is connected to the memcached server, or <value>null</value> if the pool is dead.</returns>
            public IPooledSocketResult Acquire()
            {
                var result  = new PooledSocketResult();
                var message = string.Empty;

                if (_isDebugEnabled)
                {
                    _logger.LogDebug("Acquiring stream from pool. " + this.endPoint);
                }

                if (!this.isAlive || this.isDisposed)
                {
                    message = "Pool is dead or disposed, returning null. " + this.endPoint;
                    result.Fail(message);

                    if (_isDebugEnabled)
                    {
                        _logger.LogDebug(message);
                    }

                    return(result);
                }

                PooledSocket retval = null;

                if (!this.semaphore.WaitOne(this.queueTimeout))
                {
                    message = "Pool is full, timeouting. " + this.endPoint;
                    if (_isDebugEnabled)
                    {
                        _logger.LogDebug(message);
                    }
                    result.Fail(message, new TimeoutException());

                    // everyone is so busy
                    return(result);
                }

                // maybe we died while waiting
                if (!this.isAlive)
                {
                    message = "Pool is dead, returning null. " + this.endPoint;
                    if (_isDebugEnabled)
                    {
                        _logger.LogDebug(message);
                    }
                    result.Fail(message);

                    return(result);
                }

                // do we have free items?
                if (this.freeItems.TryPop(out retval))
                {
                    #region [ get it from the pool         ]

                    try
                    {
                        retval.Reset();

                        message = "Socket was reset. " + retval.InstanceId;
                        if (_isDebugEnabled)
                        {
                            _logger.LogDebug(message);
                        }

                        result.Pass(message);
                        result.Value = retval;
                        return(result);
                    }
                    catch (Exception e)
                    {
                        message = "Failed to reset an acquired socket.";
                        _logger.LogError(message, e);

                        this.MarkAsDead();
                        result.Fail(message, e);
                        return(result);
                    }

                    #endregion
                }

                // free item pool is empty
                message = "Could not get a socket from the pool, Creating a new item. " + this.endPoint;
                if (_isDebugEnabled)
                {
                    _logger.LogDebug(message);
                }


                try
                {
                    // okay, create the new item
                    var startTime = DateTime.Now;
                    retval = this.CreateSocket();
                    _logger.LogInformation("MemcachedAcquire-CreateSocket: {0}ms", (DateTime.Now - startTime).TotalMilliseconds);
                    result.Value = retval;
                    result.Pass();
                }
                catch (Exception e)
                {
                    message = "Failed to create socket. " + this.endPoint;
                    _logger.LogError(message, e);

                    // eventhough this item failed the failure policy may keep the pool alive
                    // so we need to make sure to release the semaphore, so new connections can be
                    // acquired or created (otherwise dead conenctions would "fill up" the pool
                    // while the FP pretends that the pool is healthy)
                    semaphore.Release();

                    this.MarkAsDead();
                    result.Fail(message);
                    return(result);
                }

                if (_isDebugEnabled)
                {
                    _logger.LogDebug("Done.");
                }

                return(result);
            }
示例#29
0
            /// <summary>
            /// Acquires a new item from the pool
            /// </summary>
            /// <returns>An <see cref="T:PooledSocket"/> instance which is connected to the memcached server, or <value>null</value> if the pool is dead.</returns>
            public PooledSocket Acquire()
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Acquiring stream from pool.");
                }

                if (!this.IsAlive)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Pool is dead, returning null.");
                    }

                    return(null);
                }

                // every release signals the event, so even if the pool becomes full in the meantime
                // the WaitOne will succeed, and more items will be in the pool than allowed,
                // so reset the event when an item is inserted
                this.itemReleasedEvent.Reset();

                PooledSocket retval = null;

                // do we have free items?
                if (this.freeItems.Dequeue(out retval))
                {
                    try
                    {
                        retval.Reset();

                        if (log.IsDebugEnabled)
                        {
                            log.Debug("Socket was reset. " + retval.InstanceId);
                        }

                        Interlocked.Increment(ref this.workingCount);

                        return(retval);
                    }
                    catch (Exception e)
                    {
                        log.Error("Failed to reset an acquired socket.", e);

                        this.MarkAsDead();

                        return(null);
                    }
                }
                else
                {
                    // free item pool is empty
                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Could not get a socket from the pool.");
                    }

                    // we are not allowed to create more, so wait for an item to be released back into the pool
                    if (this.workingCount >= this.maxItems)
                    {
                        if (log.IsDebugEnabled)
                        {
                            log.Debug("Pool is full, wait for a release.");
                        }

                        // wait on the event
                        if (!itemReleasedEvent.WaitOne(this.config.ConnectionTimeout, false))
                        {
                            if (log.IsDebugEnabled)
                            {
                                log.Debug("Pool is still full, timeouting.");
                            }

                            // everyone is working
                            throw new TimeoutException();
                        }
                    }

                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Creating a new item.");
                    }

                    try
                    {
                        // okay, create the new item
                        retval = this.CreateSocket();

                        Interlocked.Increment(ref this.workingCount);
                    }
                    catch (Exception e)
                    {
                        log.Error("Failed to create socket.", e);
                        this.MarkAsDead();

                        return(null);
                    }
                }

                if (log.IsDebugEnabled)
                {
                    log.Debug("Done.");
                }

                return(retval);
            }
        public unsafe bool Read(PooledSocket socket)
        {
            this.StatusCode = -1;

            if (!socket.IsAlive)
                return false;

            var header = new byte[HeaderLength];
            socket.Read(header, 0, header.Length);

            int dataLength, extraLength;

            DeserializeHeader(header, out dataLength, out extraLength);

            var keyHeader = new byte[4];
            socket.Read(keyHeader, 0, 4);
            var vbucket = BinaryConverter.DecodeUInt16(keyHeader, 0);
            var keylen = BinaryConverter.DecodeUInt16(keyHeader, 2);

            var keyData = new byte[keylen];
            socket.Read(keyData, 0, keylen);
            Key = BinaryConverter.DecodeKey(keyData);

            var keyStateData = new byte[1];
            socket.Read(keyStateData, 0, keyStateData.Length);
            KeyState = (ObserveKeyState)keyStateData[0];

            var casData = new byte[8];
            socket.Read(casData, 0, casData.Length);
            Cas = BinaryConverter.DecodeUInt64(casData, 0);

            return this.StatusCode == 0;
        }
示例#31
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 = this.ServerPool.KeyTransformer;

            // and store them with the originals so we can map the returned items
            // to the original keys
            foreach (string s in this.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 = this.ServerPool.SplitKeys(this.keys);

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

            try
            {
                string[] command;

                // send a 'gets' to each server
                foreach (KeyValuePair <MemcachedNode, IList <string> > kp in splitKeys)
                {
                    // gets <keys>
                    //
                    // keys: key key key key
                    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] = this.ServerPool.Transcoder.Deserialize(r.Item);
                            cas[originalKey]    = r.CasValue;
                        }
                    }
                    catch (NotSupportedException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        log.Error(e);
                    }
                }

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

            return(true);
        }
示例#32
0
 bool IMemcachedNode.Execute(PooledSocket socket, IOperation op)
 {
     return true;
 }