public override AsyncUnaryCall <TResponse> AsyncUnaryCall <TRequest, TResponse>(TRequest request, ClientInterceptorContext <TRequest, TResponse> context, AsyncUnaryCallContinuation <TRequest, TResponse> continuation) { var currentRetry = 0; string headerTimeout = context.GetHeaderStringValue(GrpcConstants.TimeoutMetadataKey, true); int timeout = headerTimeout == null ? GrpcConstants.DefaultRequestTimeout : int.Parse(headerTimeout); var timeoutSpan = TimeSpan.FromMilliseconds(timeout); string headerRetryCount = context.GetHeaderStringValue(GrpcConstants.RetryCountMetadataKey, true); int retryCount = headerRetryCount == null ? NetworkConstants.DefaultRequestRetryCount : int.Parse(headerRetryCount); async Task <TResponse> RetryCallback(Task <TResponse> responseTask) { var response = responseTask; // if no problem occured return if (!response.IsFaulted) { return(response.Result); } // if a problem occured but reached the max retries if (currentRetry == retryCount) { return(response.Result); } currentRetry++; // try again var retryContext = BuildNewContext(context, timeoutSpan); var result = GetResponseAsync(continuation(request, retryContext), timeoutSpan) .ContinueWith(RetryCallback).Unwrap(); return(await result); } var newContext = BuildNewContext(context, timeoutSpan); var responseContinuation = continuation(request, newContext); var responseAsync = GetResponseAsync(responseContinuation, timeoutSpan).ContinueWith(RetryCallback) .Unwrap(); return(new AsyncUnaryCall <TResponse>( responseAsync, responseContinuation.ResponseHeadersAsync, responseContinuation.GetStatus, responseContinuation.GetTrailers, responseContinuation.Dispose)); }
public void GetHeader_Test() { var context = new ClientInterceptorContext <string, string>(null, null, new CallOptions()); context.GetHeaderStringValue(GrpcConstants.RetryCountMetadataKey).ShouldBeNull(); context = new ClientInterceptorContext <string, string>(null, null, new CallOptions(new Metadata())); context.GetHeaderStringValue(GrpcConstants.RetryCountMetadataKey).ShouldBeNull(); Metadata data = new Metadata { { GrpcConstants.TimeoutMetadataKey, "TimeoutMetadata" }, { GrpcConstants.RetryCountMetadataKey, "2" } }; context = new ClientInterceptorContext <string, string>(null, null, new CallOptions(data)); context.GetHeaderStringValue(GrpcConstants.TimeoutMetadataKey).ShouldBe("TimeoutMetadata"); context.GetHeaderStringValue(GrpcConstants.RetryCountMetadataKey).ShouldBe("2"); context.GetHeaderStringValue(GrpcConstants.TimeoutMetadataKey, true).ShouldBe("TimeoutMetadata"); context.GetHeaderStringValue(GrpcConstants.RetryCountMetadataKey, true).ShouldBe("2"); context.GetHeaderStringValue(GrpcConstants.TimeoutMetadataKey).ShouldBeNull(); context.GetHeaderStringValue(GrpcConstants.RetryCountMetadataKey).ShouldBeNull(); }