/// <summary>
        /// Sends a memcached packet asyncronously and handles the response be calling the passed in <see cref="callback" /> delegate.
        /// </summary>
        /// <param name="request">The memcached request packet.</param>
        /// <param name="callback">The callback handled when the response has been been received.</param>
        public override void SendAsync(byte[] request, Func<SocketAsyncState, Task> callback)
        {
            var state = new AsyncState
            {
                Id = Converter.ToUInt32(request, HeaderIndexFor.Opaque),
                Callback = callback,
                Converter = Converter
            };

            lock (_statesInFlight)
            {
                _statesInFlight.TryAdd(state.Id, state);
            }

            state.Timer = new Timer(o =>
            {
                AsyncState a = (AsyncState)o;
                lock (_statesInFlight)
                {
                    IState inflight;
                    _statesInFlight.TryRemove(a.Id, out inflight);
                }
                a.Cancel();
            }, state, Configuration.SendTimeout, Timeout.Infinite);

            var sentBytesCount = 0;
            lock (Socket)
            {
                do
                {
                    sentBytesCount += Socket.Send(request, sentBytesCount, request.Length - sentBytesCount, SocketFlags.None);

                } while (sentBytesCount < request.Length);
            }
        }
Ejemplo n.º 2
0
        public override Task SendAsync(byte[] request, Func <SocketAsyncState, Task> callback, ISpan span, ErrorMap errorMap)
        {
            var opaque = Converter.ToUInt32(request, HeaderIndexFor.Opaque);
            var state  = new AsyncState
            {
                Opaque        = opaque,
                Callback      = callback,
                Converter     = Converter,
                EndPoint      = (IPEndPoint)EndPoint,
                DispatchSpan  = span,
                ConnectionId  = ContextId,
                ErrorMap      = errorMap,
                Timeout       = Configuration.SendTimeout,
                LocalEndpoint = LocalEndPoint.ToString()
            };

            _statesInFlight.TryAdd(state.Opaque, state);

            state.Timer = new Timer(o =>
            {
                AsyncState a = (AsyncState)o;
                _statesInFlight.TryRemove(a.Opaque, out _);
                a.Cancel(ResponseStatus.OperationTimeout, CreateTimeoutException(opaque));
            }, state, Configuration.SendTimeout, Timeout.Infinite);

            var sentBytesCount = 0;

            lock (Socket)
            {
                try
                {
                    do
                    {
                        sentBytesCount += Socket.Send(request, sentBytesCount, request.Length - sentBytesCount,
                                                      SocketFlags.None);
                    } while (sentBytesCount < request.Length);
                }
                catch (Exception e)
                {
                    HandleDisconnect(e);
                }
            }

            return(Task.FromResult(0));
        }
        /// <summary>
        /// Sends a memcached packet asyncronously and handles the response be calling the passed in <see cref="callback" /> delegate.
        /// </summary>
        /// <param name="request">The memcached request packet.</param>
        /// <param name="callback">The callback handled when the response has been been received.</param>
        /// <exception cref="SendTimeoutExpiredException"></exception>
        public override void SendAsync(byte[] request, Func <SocketAsyncState, Task> callback)
        {
            var state = new AsyncState
            {
                Id        = Converter.ToUInt32(request, HeaderIndexFor.Opaque),
                Callback  = callback,
                Converter = Converter,
                EndPoint  = (IPEndPoint)EndPoint
            };

            lock (_statesInFlight)
            {
                _statesInFlight.TryAdd(state.Id, state);
            }

            state.Timer = new Timer(o =>
            {
                AsyncState a = (AsyncState)o;
                lock (_statesInFlight)
                {
                    IState inflight;
                    _statesInFlight.TryRemove(a.Id, out inflight);
                }
                a.Cancel(ResponseStatus.OperationTimeout, new SendTimeoutExpiredException());
            }, state, Configuration.SendTimeout, Timeout.Infinite);

            var sentBytesCount = 0;

            lock (Socket)
            {
                try
                {
                    do
                    {
                        sentBytesCount += Socket.Send(request, sentBytesCount, request.Length - sentBytesCount,
                                                      SocketFlags.None);
                    } while (sentBytesCount < request.Length);
                }
                catch (Exception e)
                {
                    HandleDisconnect(e);
                }
            }
        }