public override void SendAsync(byte[] buffer, Func<SocketAsyncState, Task> callback)
        {
            SocketAsyncState state = null;
            try
            {
                state = new SocketAsyncState
                {
                    Data = new MemoryStream(),
                    Opaque = Converter.ToUInt32(buffer, HeaderIndexFor.Opaque),
                    Buffer = buffer,
                    Completed = callback,
                    SendOffset = _eventArgs.Offset
                };

                _eventArgs.UserToken = state;
                Log.Debug(m => m("Sending {0} with {1} on server {2}", state.Opaque, Identity, EndPoint));

                //set the buffer
                var bufferLength = buffer.Length < Configuration.BufferSize
                    ? buffer.Length
                    : Configuration.BufferSize;

                _eventArgs.SetBuffer(state.SendOffset, bufferLength);
                Buffer.BlockCopy(buffer, 0, _eventArgs.Buffer, state.SendOffset, bufferLength);

                //Send the request
                if (!Socket.SendAsync(_eventArgs))
                {
                    OnCompleted(Socket, _eventArgs);
                }
            }
            catch (Exception e)
            {
                if (state == null)
                {
                    callback(new SocketAsyncState
                    {
                        Exception = e,
                        Status = (e is SocketException) ?
                            ResponseStatus.TransportFailure :
                            ResponseStatus.ClientFailure
                    });
                }
                else
                {
                    state.Exception = e;
                    state.Completed(state);
                    Log.Debug(e);
                }
            }
        }
        public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback)
        {
            ExceptionDispatchInfo capturedException = null;
            SocketAsyncState      state             = null;

            try
            {
                state = new SocketAsyncState
                {
                    Data      = new MemoryStream(),
                    Opaque    = Converter.ToUInt32(request, HeaderIndexFor.Opaque),
                    Buffer    = request,
                    Completed = callback
                };

                await _sslStream.WriteAsync(request, 0, request.Length).ConfigureAwait(false);

                state.SetIOBuffer(BufferAllocator.GetBuffer());
                state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, state.BufferLength).ConfigureAwait(false);

                //write the received buffer to the state obj
                await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived).ConfigureAwait(false);

                state.BodyLength = Converter.ToInt32(state.Buffer, state.BufferOffset + HeaderIndexFor.BodyLength);
                while (state.BytesReceived < state.BodyLength + 24)
                {
                    var bufferLength = state.BufferLength - state.BytesSent < state.BufferLength
                        ? state.BufferLength - state.BytesSent
                        : state.BufferLength;

                    state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, bufferLength).ConfigureAwait(false);

                    await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived - (int)state.Data.Length).ConfigureAwait(false);
                }
                await callback(state).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                IsDead            = true;
                capturedException = ExceptionDispatchInfo.Capture(e);
            }
            finally
            {
                ConnectionPool.Release(this);
                if (state.IOBuffer != null)
                {
                    BufferAllocator.ReleaseBuffer(state.IOBuffer);
                }
            }

            if (capturedException != null)
            {
                var sourceException = capturedException.SourceException;
                if (state == null)
                {
                    await callback(new SocketAsyncState
                    {
                        Exception = capturedException.SourceException,
                        Status    = (sourceException is SocketException)
                            ? ResponseStatus.TransportFailure
                            : ResponseStatus.ClientFailure
                    }).ConfigureAwait(false);
                }
                else
                {
                    state.Exception = sourceException;
                    await state.Completed(state).ConfigureAwait(false);

                    Log.Debug(sourceException);
                }
            }
        }
        public override async void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback)
        {
            SocketAsyncState state = null;

            byte[] buffer = null;
            try
            {
                state = new SocketAsyncState
                {
                    Data      = new MemoryStream(),
                    Opaque    = Converter.ToUInt32(request, HeaderIndexFor.Opaque),
                    Buffer    = request,
                    Completed = callback
                };

                await _sslStream.WriteAsync(request, 0, request.Length);

                state.Buffer        = BufferManager.TakeBuffer(Configuration.BufferSize);
                state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, 0, Configuration.BufferSize);

                //write the received buffer to the state obj
                await state.Data.WriteAsync(state.Buffer, 0, state.BytesReceived);

                state.BodyLength = Converter.ToInt32(state.Buffer, HeaderIndexFor.BodyLength);
                while (state.BytesReceived < state.BodyLength + 24)
                {
                    var bufferLength = state.Buffer.Length - state.BytesSent < Configuration.BufferSize
                        ? state.Buffer.Length - state.BytesSent
                        : Configuration.BufferSize;

                    state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, 0, bufferLength);

                    await state.Data.WriteAsync(state.Buffer, 0, state.BytesReceived - (int)state.Data.Length);
                }
                await callback(state);
            }
            catch (Exception e)
            {
                IsDead = true;
                if (state == null)
                {
                    callback(new SocketAsyncState
                    {
                        Exception = e,
                        Status    = (e is SocketException)
                            ? ResponseStatus.TransportFailure
                            : ResponseStatus.ClientFailure
                    });
                }
                else
                {
                    state.Exception = e;
                    state.Completed(state);
                    Log.Debug(e);
                }
            }
            finally
            {
                ConnectionPool.Release(this);
                if (buffer != null)
                {
                    BufferManager.ReturnBuffer(buffer);
                }
            }
        }
        /// <summary>
        /// Sends a memcached operation as a buffer to a the server.
        /// </summary>
        /// <param name="buffer">A memcached request buffer</param>
        /// <returns>A memcached response buffer.</returns>
        public override byte[] Send(byte[] buffer)
        {
            //create the state object and set it
            var state = new SocketAsyncState
            {
                Data = new MemoryStream(),
                Opaque = Converter.ToUInt32(buffer, HeaderIndexFor.Opaque),
                Buffer = buffer,
                SendOffset = _eventArgs.Offset
            };

            Log.DebugFormat("Sending opaque{0} on {1}", state.Opaque, Identity);
            _eventArgs.UserToken = state;

            //set the buffer
            var bufferLength = buffer.Length < Configuration.BufferSize
                ? buffer.Length
                : Configuration.BufferSize;

            _eventArgs.SetBuffer(state.SendOffset, bufferLength);
            Buffer.BlockCopy(buffer, 0, _eventArgs.Buffer, state.SendOffset, bufferLength);

            //Send the request
            if (!Socket.SendAsync(_eventArgs))
            {
               OnCompleted(Socket, _eventArgs);
            }

            //wait for completion
            if (!_requestCompleted.WaitOne(Configuration.SendTimeout))
            {
                IsDead = true;
                var msg = ExceptionUtil.GetMessage(ExceptionUtil.RemoteHostTimeoutMsg, Configuration.SendTimeout);
                throw new RemoteHostTimeoutException(msg);
            }

            //Check if an IO error occurred
            if (state.Exception != null)
            {
                Log.DebugFormat("Connection {0} has failed with {1}", Identity, state.Exception);
                IsDead = true;
                throw state.Exception;
            }

            Log.DebugFormat("Complete opaque{0} on {1}", state.Opaque, Identity);
            //return the response bytes
            return state.Data.ToArray();
        }
Beispiel #5
0
        public override async Task SendAsync(byte[] request, Func <SocketAsyncState, Task> callback, ISpan span, ErrorMap errorMap)
        {
            ExceptionDispatchInfo capturedException = null;
            SocketAsyncState      state             = null;

            try
            {
                var opaque = Converter.ToUInt32(request, HeaderIndexFor.Opaque);
                state = new SocketAsyncState
                {
                    Data          = MemoryStreamFactory.GetMemoryStream(),
                    Opaque        = opaque,
                    Buffer        = request,
                    Completed     = callback,
                    DispatchSpan  = span,
                    ConnectionId  = ContextId,
                    LocalEndpoint = LocalEndPoint.ToString(),
                    ErrorMap      = errorMap,
                    Timeout       = Configuration.SendTimeout
                };

                await _sslStream.WriteAsync(request, 0, request.Length).ContinueOnAnyContext();

                state.SetIOBuffer(_buffer);
                state.BytesReceived = await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, state.BufferLength).ContinueOnAnyContext();

                //write the received buffer to the state obj
                await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived).ContinueOnAnyContext();

                state.BodyLength = Converter.ToInt32(state.Buffer, state.BufferOffset + HeaderIndexFor.BodyLength);
                while (state.BytesReceived < state.BodyLength + OperationHeader.Length)
                {
                    var bufferLength = state.BufferLength - state.BytesSent < state.BufferLength
                        ? state.BufferLength - state.BytesSent
                        : state.BufferLength;

                    state.BytesReceived += await _sslStream.ReadAsync(state.Buffer, state.BufferOffset, bufferLength).ContinueOnAnyContext();

                    await state.Data.WriteAsync(state.Buffer, state.BufferOffset, state.BytesReceived - (int)state.Data.Length).ContinueOnAnyContext();
                }
                await callback(state).ContinueOnAnyContext();
            }
            catch (Exception e)
            {
                IsDead            = true;
                capturedException = ExceptionDispatchInfo.Capture(e);
            }
            finally
            {
                ConnectionPool.Release(this);
            }

            if (capturedException != null)
            {
                var sourceException = capturedException.SourceException;
                if (state == null)
                {
                    await callback(new SocketAsyncState
                    {
                        Exception = capturedException.SourceException,
                        Status    = (sourceException is SocketException)
                            ? ResponseStatus.TransportFailure
                            : ResponseStatus.ClientFailure
                    }).ContinueOnAnyContext();
                }
                else
                {
                    state.Exception = sourceException;
                    await state.Completed(state).ContinueOnAnyContext();

                    Log.Debug(sourceException);
                }
            }
        }