예제 #1
0
        internal static ResponseStatus GetResponseStatus(short code, ErrorMap errorMap, out ErrorCode errorCode)
        {
            var status = (ResponseStatus)code;

            // Is it a known response status?
            if (!ValidResponseStatuses.Contains(status))
            {
                status = ResponseStatus.UnknownError;
            }

            // If available, try and use the error map to get more details
            if (errorMap != null)
            {
                errorMap.TryGetGetErrorCode(code, out errorCode);
            }
            else
            {
                errorCode = null;//make the compiler happy
            }

            return(status);
        }
예제 #2
0
        public async Task ExecuteOp(IOperation op, CancellationToken token = default(CancellationToken),
                                    TimeSpan?timeout = null)
        {
            Log.LogDebug("Executing op {0} with key {1} and opaque {2}", op.OpCode, op.Key, op.Opaque);

            // wire up op's completed function
            var tcs = new TaskCompletionSource <IMemoryOwner <byte> >();

            op.Completed = state =>
            {
                if (state.Status == ResponseStatus.Success)
                {
                    tcs.TrySetResult(state.ExtractData());
                }
                else if
                (state.Status == ResponseStatus.VBucketBelongsToAnotherServer)
                {
                    tcs.TrySetResult(state.ExtractData());
                }
                else
                {
                    ErrorMap.TryGetGetErrorCode((short)state.Status, out ErrorCode errorCode);
                    tcs.TrySetException(state.ThrowException(errorCode));
                }

                return(tcs.Task);
            };

            CancellationTokenSource cts = null;

            try
            {
                if (token == CancellationToken.None)
                {
                    cts = CancellationTokenSource.CreateLinkedTokenSource(token);
                    cts.CancelAfter(timeout.HasValue && timeout != TimeSpan.Zero ? timeout.Value : DefaultTimeout);
                    token = cts.Token;
                }

                using (token.Register(() =>
                {
                    if (tcs.Task.Status != TaskStatus.RanToCompletion)
                    {
                        tcs.TrySetCanceled();
                    }
                }, useSynchronizationContext: false))
                {
                    await CheckConnectionAsync();

                    await op.SendAsync(Connection).ConfigureAwait(false);

                    var bytes = await tcs.Task.ConfigureAwait(false);

                    await op.ReadAsync(bytes).ConfigureAwait(false);

                    var status = op.Header.Status;
                    if (status == ResponseStatus.VBucketBelongsToAnotherServer)
                    {
                        var config = op.GetConfig(_transcoder);
                        _context.PublishConfig(config);
                    }

                    Log.LogDebug("Completed executing op {0} with key {1} and opaque {2}", op.OpCode, op.Key,
                                 op.Opaque);
                }
            }
            catch (OperationCanceledException e)
            {
                if (!e.CancellationToken.IsCancellationRequested)
                {
                    //oddly IsCancellationRequested is false when timed out
                    throw new TimeoutException();
                }
            }
            finally
            {
                //clean up the token if we used a default token
                cts?.Dispose();
            }
        }