Ejemplo n.º 1
0
        public async Task <T> Read <T>() where T : new()
        {
            const int sizeSize = sizeof(int);
            const int codeSize = sizeof(byte);

            var buffer = _blockingBufferManager.GetBuffer();

            try
            {
                await GetConnectedSocket().ConfigureAwait(false);

                var headerBuffer = new ArraySegment <byte>(buffer.Array, buffer.Offset, sizeSize + codeSize);

                await ReceiveAsync(headerBuffer).ConfigureAwait(false);

                var messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(headerBuffer.Array, headerBuffer.Offset));
                var messageCode   = (MessageCode)headerBuffer.Array[headerBuffer.Offset + sizeSize];

                if (messageCode == MessageCode.ErrorResp)
                {
                    if (messageLength - codeSize < 1)
                    {
                        var error = new RpbErrorResp();
                        throw new RiakException(error.errcode, error.errmsg.FromRiakString(), false);
                    }

                    if (messageLength > buffer.Count)
                    {
                        throw new RiakInvalidDataException(0);
                    }

                    var errorBuffer = new ArraySegment <byte>(headerBuffer.Array, headerBuffer.Offset + sizeSize + codeSize, messageLength - codeSize);

                    await ReceiveAsync(errorBuffer).ConfigureAwait(false);

                    using (var stream = new MemoryStream(errorBuffer.Array, errorBuffer.Offset, errorBuffer.Count))
                    {
                        var error = Serializer.Deserialize <RpbErrorResp>(stream);
                        throw new RiakException(error.errcode, error.errmsg.FromRiakString(), false);
                    }
                }

                if (messageLength > buffer.Count)
                {
                    throw new RiakInvalidDataException(0);
                }

                if (!MessageCodeToTypeMap.ContainsKey(messageCode))
                {
                    throw new RiakInvalidDataException((byte)messageCode);
                }

                if (messageLength > buffer.Count)
                {
                    throw new RiakInvalidDataException(0);
                }
#if DEBUG
                // This message code validation is here to make sure that the caller
                // is getting exactly what they expect. This "could" be removed from
                // production code, but it's a good thing to have in here for dev.
                if (MessageCodeToTypeMap[messageCode] != typeof(T))
                {
                    throw new InvalidOperationException(
                              string.Format("Attempt to decode message to type '{0}' when received type '{1}'.",
                                            typeof(T).Name, MessageCodeToTypeMap[messageCode].Name));
                }
#endif

                if (messageLength - codeSize <= 1)
                {
                    return(new T());
                }

                var bodyBuffer = new ArraySegment <byte>(headerBuffer.Array, headerBuffer.Offset + sizeSize + codeSize, messageLength - codeSize);

                await ReceiveAsync(bodyBuffer).ConfigureAwait(false);

                using (var stream = new MemoryStream(bodyBuffer.Array, bodyBuffer.Offset, bodyBuffer.Count))
                {
                    var message = Serializer.Deserialize <T>(stream);
                    return(message);
                }
            }
            catch (RiakException)
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }
                throw;
            }
            catch (SocketException)
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }
                throw;
            }
            finally
            {
                _blockingBufferManager.ReleaseBuffer(buffer);
            }
        }
Ejemplo n.º 2
0
        public async Task <MessageCode> Read(MessageCode expectedCode)
        {
            const int sizeSize = sizeof(int);
            const int codeSize = sizeof(byte);

            var buffer = _blockingBufferManager.GetBuffer();

            try
            {
                await GetConnectedSocket().ConfigureAwait(false);

                var headerBuffer = new ArraySegment <byte>(buffer.Array, buffer.Offset, sizeSize + codeSize);

                await ReceiveAsync(headerBuffer).ConfigureAwait(false);

                var messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(headerBuffer.Array, headerBuffer.Offset));
                var messageCode   = (MessageCode)headerBuffer.Array[headerBuffer.Offset + sizeSize];

                if (messageCode == MessageCode.ErrorResp)
                {
                    if (messageLength - codeSize < 1)
                    {
                        var error = new RpbErrorResp();
                        throw new RiakException(error.errcode, error.errmsg.FromRiakString(), false);
                    }

                    var errorBuffer = new ArraySegment <byte>(headerBuffer.Array, headerBuffer.Offset + sizeSize + codeSize, messageLength - codeSize);

                    await ReceiveAsync(errorBuffer).ConfigureAwait(false);

                    using (var stream = new MemoryStream(errorBuffer.Array, errorBuffer.Offset, errorBuffer.Count))
                    {
                        var error = Serializer.Deserialize <RpbErrorResp>(stream);
                        throw new RiakException(error.errcode, error.errmsg.FromRiakString(), false);
                    }
                }

                if (expectedCode != messageCode)
                {
                    throw new RiakException("Expected return code {0} received {1}".Fmt(expectedCode, messageCode));
                }

                return(messageCode);
            }
            catch (RiakException)
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }
                throw;
            }
            catch (SocketException)
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }
                throw;
            }
            finally
            {
                _blockingBufferManager.ReleaseBuffer(buffer);
            }
        }