Example #1
0
        public static async Task <GetResponse> ReadItemAsync(PooledSocket socket, CancellationToken cancellationToken = default)
        {
            var description = await TextSocketHelper.ReadResponseAsync(socket, cancellationToken).ConfigureAwait(false);

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

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

            // response is:
            // VALUE <key> <flags> <bytes> [<cas unique>]
            // 0     1     2       3       4
            //
            // cas only exists in 1.2.4+
            //

            ulong cas   = 0;
            var   parts = description.Split(' ');

            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);
            }

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

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

            await socket.ReceiveAsync(allData, 0, length, cancellationToken).ConfigureAwait(false);

            await socket.ReceiveAsync(eod, 0, 2, cancellationToken).ConfigureAwait(false);             // data is terminated by \r\n

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

            GetHelper.Logger = GetHelper.Logger ?? Caching.Logger.CreateLogger(typeof(GetHelper));
            if (GetHelper.Logger.IsEnabled(LogLevel.Debug))
            {
                GetHelper.Logger.LogDebug("Received value. Data type: {0}, size: {1}.", result.Item.Flags, result.Item.Data.Count);
            }

            return(result);
        }
Example #2
0
        /// <summary>
        /// Reads the response from the socket asynchronously.
        /// </summary>
        /// <param name="socket">The socket to read from.</param>
        /// <param name="next">The delegate which will continue processing the response. This is only called if the read completes asynchronoulsy.</param>
        /// <param name="ioPending">Set to true if the read is still pending when ReadASync returns. In this case 'next' will be called when the read is finished.</param>
        /// <returns>
        /// If the socket is already dead, ReadAsync returns false, next is not called, ioPending = false
        /// If the read completes synchronously (e.g. data is received from the buffer), it returns true/false depending on the StatusCode, and ioPending is set to true, 'next' will not be called.
        /// It returns true if it has to read from the socket, so the operation will complate asynchronously at a later time. ioPending will be true, and 'next' will be called to handle the data
        /// </returns>
        public bool ReadAsync(PooledSocket socket, Action <bool> next, out bool ioPending)
        {
            this.StatusCode  = -1;
            this._socket     = socket;
            this._nextAction = next;

            var asyncEvent = new AsyncIOArgs
            {
                Count = BinaryResponse.HeaderLength,
                Next  = this.DoDecodeHeaderAsync
            };

            this._shouldCallNext = true;
            if (socket.ReceiveAsync(asyncEvent))
            {
                ioPending = true;
                return(true);
            }

            ioPending            = false;
            this._shouldCallNext = false;

            return(asyncEvent.Fail
                                ? false
                                : this.DoDecodeHeader(asyncEvent, out ioPending));
        }
Example #3
0
        /// <summary>
        /// Reads the response from the socket asynchronously.
        /// </summary>
        /// <param name="socket">The socket to read from.</param>
        /// <param name="next">The delegate whihc will continue processing the response. This is only called if the read completes asynchronoulsy.</param>
        /// <param name="ioPending">Set totrue if the read is still pending when ReadASync returns. In this case 'next' will be called when the read is finished.</param>
        /// <returns>
        /// If the socket is already dead, ReadAsync returns false, next is not called, ioPending = false
        /// If the read completes synchronously (e.g. data is received from the buffer), it returns true/false depending on the StatusCode, and ioPending is set to true, 'next' will not be called.
        /// It returns true if it has to read from the socket, so the operation will complate asynchronously at a later time. ioPending will be true, and 'next' will be called to handle the data
        /// </returns>
        public bool ReadAsync(PooledSocket socket, Action <bool> next, out bool ioPending)
        {
            this.StatusCode    = -1;
            this.currentSocket = socket;
            this.next          = next;

            var asyncEvent = new AsyncIOArgs();

            asyncEvent.Count = HeaderLength;
            asyncEvent.Next  = this.DoDecodeHeaderAsync;

            this.shouldCallNext = true;

            if (socket.ReceiveAsync(asyncEvent))
            {
                ioPending = true;
                return(true);
            }

            ioPending           = false;
            this.shouldCallNext = false;

            return(asyncEvent.Fail
                                        ? false
                                        : this.DoDecodeHeader(asyncEvent, out ioPending));
        }
Example #4
0
        /// <summary>
        /// Reads the response from the socket
        /// </summary>
        /// <param name="socket"></param>
        /// <returns></returns>
        public async Task <bool> ReadAsync(PooledSocket socket, CancellationToken cancellationToken = default)
        {
            this.StatusCode = -1;

            if (!socket.IsAlive)
            {
                return(false);
            }

            try
            {
                var header = new byte[BinaryResponse.HeaderLength];
                await socket.ReceiveAsync(header, 0, header.Length, cancellationToken).ConfigureAwait(false);

                this.DeserializeHeader(header, out var dataLength, out var extraLength);

                if (dataLength > 0)
                {
                    var data = new byte[dataLength];
                    await socket.ReceiveAsync(data, 0, dataLength, cancellationToken).ConfigureAwait(false);

                    this.Extra = new ArraySegment <byte>(data, 0, extraLength);
                    this.Data  = new ArraySegment <byte>(data, extraLength, data.Length - extraLength);
                }

                return(this.StatusCode == 0);
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (Exception ex)
            {
                this._logger.LogError(ex, "ReadAsync: Error occurred while reading socket");
                throw;
            }
        }
Example #5
0
        /// <summary>
        /// Reads a line from the socket. A line is terninated by \r\n.
        /// </summary>
        /// <returns></returns>
        static async Task <string> ReadLineAsync(PooledSocket socket, CancellationToken cancellationToken = default(CancellationToken))
        {
            using (var stream = new MemoryStream(50))
            {
                var  gotR = false;
                byte data;

                while (true)
                {
                    data = await socket.ReceiveAsync(cancellationToken).ConfigureAwait(false);

                    if (data == 13)
                    {
                        gotR = true;
                        continue;
                    }

                    if (gotR)
                    {
                        if (data == 10)
                        {
                            break;
                        }

                        stream.WriteByte(13);

                        gotR = false;
                    }

                    stream.WriteByte(data);
                }

                var result = Encoding.ASCII.GetString(stream.ToArray(), 0, (int)stream.Length);

                Logger = Logger ?? Caching.Logger.CreateLogger(typeof(TextSocketHelper));
                if (Logger.IsEnabled(LogLevel.Debug))
                {
                    Logger.LogDebug("ReadLine (async): " + result);
                }

                return(result);
            }
        }
Example #6
0
        /// <summary>
        /// Reads the response from the socket asynchronously.
        /// </summary>
        /// <param name="socket">The socket to read from.</param>
        /// <param name="next">The delegate whihc will continue processing the response. This is only called if the read completes asynchronoulsy.</param>
        /// <param name="ioPending">Set totrue if the read is still pending when ReadASync returns. In this case 'next' will be called when the read is finished.</param>
        /// <returns>
        /// If the socket is already dead, ReadAsync returns false, next is not called, ioPending = false
        /// If the read completes synchronously (e.g. data is received from the buffer), it returns true/false depending on the StatusCode, and ioPending is set to true, 'next' will not be called.
        /// It returns true if it has to read from the socket, so the operation will complate asynchronously at a later time. ioPending will be true, and 'next' will be called to handle the data
        /// </returns>
        public bool ReadAsync(PooledSocket socket, Action<bool> next, out bool ioPending)
        {
            this.StatusCode = -1;
            this.currentSocket = socket;
            this.next = next;

            var asyncEvent = new AsyncIOArgs();

            asyncEvent.Count = HeaderLength;
            asyncEvent.Next = this.DoDecodeHeaderAsync;

            this.shouldCallNext = true;

            if (socket.ReceiveAsync(asyncEvent))
            {
                ioPending = true;
                return true;
            }

            ioPending = false;
            this.shouldCallNext = false;

            return asyncEvent.Fail
                    ? false
                    : this.DoDecodeHeader(asyncEvent, out ioPending);
        }