private async Task RunGenericStreamingAsync(Channel channel, IInterarrivalTimer timer) { var request = CreateByteBufferRequest(); var stopwatch = new Stopwatch(); var callDetails = new CallInvocationDetails <byte[], byte[]>(channel, GenericService.StreamingCallMethod, new CallOptions()); using (var call = Calls.AsyncDuplexStreamingCall(callDetails)) { while (!stoppedCts.Token.IsCancellationRequested) { stopwatch.Restart(); await call.RequestStream.WriteAsync(request); await call.ResponseStream.MoveNext(); stopwatch.Stop(); // spec requires data point in nanoseconds. histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); await timer.WaitForNextAsync(); } // finish the streaming call await call.RequestStream.CompleteAsync(); Assert.IsFalse(await call.ResponseStream.MoveNext()); } }
AsyncClientStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) { // No channel affinity feature for client streaming call. ChannelRef channelRef = GetChannelRef(); var callDetails = new CallInvocationDetails <TRequest, TResponse>(channelRef.Channel, method, host, options); var originalCall = Calls.AsyncClientStreamingCall(callDetails); // Decrease the active streams count once async response finishes. var gcpResponseAsync = DecrementCountAndPropagateResult(originalCall.ResponseAsync); // Create a wrapper of the original AsyncClientStreamingCall. return(new AsyncClientStreamingCall <TRequest, TResponse>( originalCall.RequestStream, gcpResponseAsync, originalCall.ResponseHeadersAsync, () => originalCall.GetStatus(), () => originalCall.GetTrailers(), () => originalCall.Dispose())); async Task <TResponse> DecrementCountAndPropagateResult(Task <TResponse> task) { try { return(await task.ConfigureAwait(false)); } finally { channelRef.ActiveStreamCountDecr(); } } }
/* * Missing in gRPC library, but very useful (not used in this example, though) */ public virtual TResponse BlockingUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) where TRequest : class where TResponse : class { var call = new CallInvocationDetails <TRequest, TResponse>(this.ch, method, host, options); return(Calls.BlockingUnaryCall(call, request)); }
/// <summary> /// Invokes a simple remote call in a blocking fashion. /// </summary> public override TResponse BlockingUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) { return(_resourceManager.ExecuteAction((grpcResource, retryCount) => { var overriddenOptions = OverrideCallOptions(options); var call = new CallInvocationDetails <TRequest, TResponse>(grpcResource.Channel, method, host, overriddenOptions); return Calls.BlockingUnaryCall(call, request); }, _shouldRetry, _onError)); }
public void Init() { channel = new Channel("localhost", Credentials.Insecure); fakeCall = new FakeNativeCall(); var callDetails = new CallInvocationDetails<string, string>(channel, "someMethod", null, Marshallers.StringMarshaller, Marshallers.StringMarshaller, new CallOptions()); asyncCall = new AsyncCall<string, string>(callDetails, fakeCall); }
public void Init() { channel = new Channel("localhost", Credentials.Insecure); fakeCall = new FakeNativeCall(); var callDetails = new CallInvocationDetails <string, string>(channel, "someMethod", null, Marshallers.StringMarshaller, Marshallers.StringMarshaller, new CallOptions()); asyncCall = new AsyncCall <string, string>(callDetails, fakeCall); }
/// <summary> /// /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="callInvocation"></param> /// <returns></returns> public static AsyncClientStreamingCall <TRequest, TResponse> AsyncClientStreamingCall <TRequest, TResponse>( CallInvocationDetails <TRequest, TResponse> callInvocation ) where TRequest : class where TResponse : class { var asyncCall = new AsyncCall <TRequest, TResponse>(callInvocation); var resultTask = asyncCall.ClientStreamingCallAsync(); var requestStream = new ClientRequestStream <TRequest, TResponse>(asyncCall); return(new AsyncClientStreamingCall <TRequest, TResponse>(requestStream, resultTask, asyncCall.Cancel)); }
/// <summary> /// /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="callInvocation"></param> /// <param name="request"></param> /// <returns></returns> public static AsyncClientCall <TResponse> AsyncClientCall <TRequest, TResponse>( CallInvocationDetails <TRequest, TResponse> callInvocation, TRequest request ) where TRequest : class where TResponse : class { var asyncCall = new AsyncCall <TRequest, TResponse>(callInvocation); var resultTask = asyncCall.ClientCallAsync(request); return(new AsyncClientCall <TResponse>(resultTask, asyncCall.Cancel)); }
public void UnknownMethodHandler() { var nonexistentMethod = new Method <string, string>( MethodType.Unary, MockServiceHelper.ServiceName, "NonExistentMethod", Marshallers.StringMarshaller, Marshallers.StringMarshaller); var callDetails = new CallInvocationDetails <string, string>(channel, nonexistentMethod, new CallOptions()); var ex = Assert.Throws <RpcException>(() => Calls.BlockingUnaryCall(callDetails, "abc")); Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode); }
/// <summary> /// Invokes a simple remote call asynchronously. /// </summary> public override AsyncUnaryCall <TResponse> AsyncUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) { var result = _resourceManager.ExecuteAsync(async(grpcResource, retryCount) => { var overriddenOptions = OverrideCallOptions(options); var call = new CallInvocationDetails <TRequest, TResponse>(grpcResource.Channel, method, host, overriddenOptions); var asyncCall = Calls.AsyncUnaryCall(call, request); // Await for any exception, but return the original object because we don't want to lose any information var response = await asyncCall.ResponseAsync.ConfigureAwait(false); var headers = await asyncCall.ResponseHeadersAsync.ConfigureAwait(false); var status = asyncCall.GetStatus(); var trailers = asyncCall.GetTrailers(); return(Tuple.Create(response, headers, status, trailers)); }, _shouldRetry, _onError); return(new AsyncUnaryCallWrapper <TResponse>(result).GetAsyncUnaryCall()); }
BlockingUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) { affinityByMethod.TryGetValue(method.FullName, out AffinityConfig affinityConfig); ChannelRef channelRef = PreProcess(affinityConfig, request); var callDetails = new CallInvocationDetails <TRequest, TResponse>(channelRef.Channel, method, host, options); TResponse response = default(TResponse); try { response = Calls.BlockingUnaryCall <TRequest, TResponse>(callDetails, request); return(response); } finally { PostProcess(affinityConfig, channelRef, request, response); } }
protected virtual CallInvocationDetails <TRequest, TResponse> CreateCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) where TRequest : class where TResponse : class { var methodName = $"{method.ServiceName}.{method.Name}"; var key = methodName.Substring(methodName.IndexOf(".") + 1).ToLower(); var a = _options.MethodPolicies.TryGetValue(key, out PollyAttribute methodPollyAttr); if (!a) { _options.MethodPolicies.TryGetValue("", out methodPollyAttr); } CallOptions options2; //重写header if (options.Headers != null) { options2 = options; } else { options2 = new CallOptions(_grpcConnect.GetMetadata(), options.Deadline, options.CancellationToken); } var pollyData = PollyExtension.Invoke(methodPollyAttr, () => { var callRes = new CallInvocationDetails <TRequest, TResponse>(_grpcConnect.GetChannel(), method, host, options2); return(new PollyExtension.PollyData <CallInvocationDetails <TRequest, TResponse> >() { Data = callRes }); }, $"{methodName}"); var response = pollyData.Data; if (!string.IsNullOrEmpty(pollyData.Error)) { throw new Exception(pollyData.Error); } return(response); //return new CallInvocationDetails<TRequest, TResponse>(Channel.Invoke(), method, host, options2); }
AsyncDuplexStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) { // No channel affinity feature for duplex streaming call. ChannelRef channelRef = GetChannelRef(); var callDetails = new CallInvocationDetails <TRequest, TResponse>(channelRef.Channel, method, host, options); var originalCall = Calls.AsyncDuplexStreamingCall(callDetails); // Decrease the active streams count once the streaming response finishes its final batch. var gcpResponseStream = new GcpClientResponseStream <TRequest, TResponse>( originalCall.ResponseStream, (resp) => channelRef.ActiveStreamCountDecr()); // Create a wrapper of the original AsyncDuplexStreamingCall. return(new AsyncDuplexStreamingCall <TRequest, TResponse>( originalCall.RequestStream, gcpResponseStream, originalCall.ResponseHeadersAsync, () => originalCall.GetStatus(), () => originalCall.GetTrailers(), () => originalCall.Dispose())); }
AsyncServerStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) { affinityByMethod.TryGetValue(method.FullName, out AffinityConfig affinityConfig); ChannelRef channelRef = PreProcess(affinityConfig, request); var callDetails = new CallInvocationDetails <TRequest, TResponse>(channelRef.Channel, method, host, options); var originalCall = Calls.AsyncServerStreamingCall(callDetails, request); // Executes affinity postprocess once the streaming response finishes its final batch. var gcpResponseStream = new GcpClientResponseStream <TRequest, TResponse>( originalCall.ResponseStream, (resp) => PostProcess(affinityConfig, channelRef, request, resp)); // Create a wrapper of the original AsyncServerStreamingCall. return(new AsyncServerStreamingCall <TResponse>( gcpResponseStream, originalCall.ResponseHeadersAsync, () => originalCall.GetStatus(), () => originalCall.GetTrailers(), () => originalCall.Dispose())); }
AsyncUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request) { affinityByMethod.TryGetValue(method.FullName, out AffinityConfig affinityConfig); Tuple <ChannelRef, string> tupleResult = PreProcess(affinityConfig, request); ChannelRef channelRef = tupleResult.Item1; string boundKey = tupleResult.Item2; var callDetails = new CallInvocationDetails <TRequest, TResponse>(channelRef.Channel, method, host, options); var originalCall = Calls.AsyncUnaryCall(callDetails, request); // Executes affinity postprocess once the async response finishes. var gcpResponseAsync = PostProcessPropagateResult(originalCall.ResponseAsync); // Create a wrapper of the original AsyncUnaryCall. return(new AsyncUnaryCall <TResponse>( gcpResponseAsync, originalCall.ResponseHeadersAsync, () => originalCall.GetStatus(), () => originalCall.GetTrailers(), () => originalCall.Dispose())); async Task <TResponse> PostProcessPropagateResult(Task <TResponse> task) { TResponse response = default(TResponse); try { response = await task.ConfigureAwait(false); return(response); } finally { PostProcess(affinityConfig, channelRef, boundKey, response); } } }
public void UnaryCall() { var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); Assert.AreEqual("ABC", Calls.BlockingUnaryCall(callDetails, "ABC")); }
public void InfiniteDeadline() { // no deadline specified, check server sees infinite deadline var callDetails = new CallInvocationDetails<string, string>(channel, TestMethod, new CallOptions()); Assert.AreEqual("DATETIME_MAXVALUE", Calls.BlockingUnaryCall(callDetails, "RETURN_DEADLINE")); // DateTime.MaxValue deadline specified, check server sees infinite deadline var callDetails2 = new CallInvocationDetails<string, string>(channel, TestMethod, new CallOptions()); Assert.AreEqual("DATETIME_MAXVALUE", Calls.BlockingUnaryCall(callDetails2, "RETURN_DEADLINE")); }
public void ServerReceivesCancellationOnTimeout() { var deadline = DateTime.UtcNow.Add(TimeSpan.FromSeconds(5)); var callDetails = new CallInvocationDetails<string, string>(channel, TestMethod, new CallOptions(deadline: deadline)); try { Calls.BlockingUnaryCall(callDetails, "CHECK_CANCELLATION_RECEIVED"); Assert.Fail(); } catch (RpcException e) { // We can't guarantee the status code is always DeadlineExceeded. See issue #2685. Assert.Contains(e.Status.StatusCode, new[] { StatusCode.DeadlineExceeded, StatusCode.Internal }); } Assert.AreEqual("CANCELLED", stringFromServerHandlerTcs.Task.Result); }
public void DeadlineExceededStatusOnTimeout() { var deadline = DateTime.UtcNow.Add(TimeSpan.FromSeconds(5)); var callDetails = new CallInvocationDetails<string, string>(channel, TestMethod, new CallOptions(deadline: deadline)); try { Calls.BlockingUnaryCall(callDetails, "TIMEOUT"); Assert.Fail(); } catch (RpcException e) { // We can't guarantee the status code always DeadlineExceeded. See issue #2685. Assert.Contains(e.Status.StatusCode, new[] { StatusCode.DeadlineExceeded, StatusCode.Internal }); } }
public void DeadlineInThePast() { var callDetails = new CallInvocationDetails<string, string>(channel, TestMethod, new CallOptions(deadline: DateTime.MinValue)); try { Calls.BlockingUnaryCall(callDetails, "TIMEOUT"); Assert.Fail(); } catch (RpcException e) { // We can't guarantee the status code always DeadlineExceeded. See issue #2685. Assert.Contains(e.Status.StatusCode, new[] { StatusCode.DeadlineExceeded, StatusCode.Internal }); } }
public void UserAgentStringPresent() { var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); string userAgent = Calls.BlockingUnaryCall(callDetails, "RETURN-USER-AGENT"); Assert.IsTrue(userAgent.StartsWith("grpc-csharp/")); }
public void PeerInfoPresent() { var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); string peer = Calls.BlockingUnaryCall(callDetails, "RETURN-PEER"); Assert.IsTrue(peer.Contains(Host)); }
public async Task Channel_WaitForStateChangedAsync() { Assert.Throws(typeof(TaskCanceledException), async () => await channel.WaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(10))); var stateChangedTask = channel.WaitForStateChangedAsync(channel.State); var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); await Calls.AsyncUnaryCall(callDetails, "abc"); await stateChangedTask; Assert.AreEqual(ChannelState.Ready, channel.State); }
public async Task ClientStreamingCall_CancelAfterBegin() { var cts = new CancellationTokenSource(); var callDetails = new CallInvocationDetails<string, string>(channel, ConcatAndEchoMethod, new CallOptions(cancellationToken: cts.Token)); var call = Calls.AsyncClientStreamingCall(callDetails); // TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it. await Task.Delay(1000); cts.Cancel(); try { await call.ResponseAsync; } catch (RpcException e) { Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode); } }
public async Task AsyncUnaryCall() { var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); var result = await Calls.AsyncUnaryCall(callDetails, "ABC"); Assert.AreEqual("ABC", result); }
protected abstract IObservable <TResponse> HandleUnaryCall <TRequest, TResponse>(IObservable <TResponse> source, CallInvocationDetails <TRequest, TResponse> details);
public void UnaryCall_DisposedChannel() { channel.Dispose(); var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); Assert.Throws(typeof(ObjectDisposedException), () => Calls.BlockingUnaryCall(callDetails, "ABC")); }
public void UnaryCallPerformance() { var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); BenchmarkUtil.RunBenchmark(100, 100, () => { Calls.BlockingUnaryCall(callDetails, "ABC"); }); }
public static AsyncUnaryCall <TResponse> AsyncUnaryCall <TRequest, TResponse>(CallInvocationDetails <TRequest, TResponse> call, TRequest req, Action customDisposeAction) where TRequest : class where TResponse : class { var asyncCall = new AsyncCall <TRequest, TResponse>(call); var asyncResult = asyncCall.UnaryCallAsync(req); var token = asyncCall.Details.Options.CancellationToken; if (token.CanBeCanceled) { token.Register(() => customDisposeAction()); return(new AsyncUnaryCall <TResponse>(asyncResult, asyncCall.ResponseHeadersAsync, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel)); } else { return(new AsyncUnaryCall <TResponse>(asyncResult, asyncCall.ResponseHeadersAsync, asyncCall.GetStatus, asyncCall.GetTrailers, () => { customDisposeAction(); asyncCall.Cancel(); })); } }
public static AsyncDuplexStreamingCall <TRequest, TResponse> AsyncDuplexStreamingCall <TRequest, TResponse>(CallInvocationDetails <TRequest, TResponse> call, Action customDisposeAction) where TRequest : class where TResponse : class { var asyncCall = new AsyncCall <TRequest, TResponse>(call); asyncCall.StartDuplexStreamingCall(); var requestStream = new ClientRequestStream <TRequest, TResponse>(asyncCall); var responseStream = new ClientResponseStream <TRequest, TResponse>(asyncCall); var token = asyncCall.Details.Options.CancellationToken; if (token.CanBeCanceled) { token.Register(() => customDisposeAction()); return(new AsyncDuplexStreamingCall <TRequest, TResponse>(requestStream, responseStream, asyncCall.ResponseHeadersAsync, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel)); } else { return(new AsyncDuplexStreamingCall <TRequest, TResponse>(requestStream, responseStream, asyncCall.ResponseHeadersAsync, asyncCall.GetStatus, asyncCall.GetTrailers, () => { asyncCall.Cancel(); customDisposeAction(); })); } }
public void AsyncUnaryCall_EchoMetadata() { var headers = new Metadata { new Metadata.Entry("ascii-header", "abcdefg"), new Metadata.Entry("binary-header-bin", new byte[] { 1, 2, 3, 0, 0xff }), }; var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions(headers: headers)); var call = Calls.AsyncUnaryCall(callDetails, "ABC"); Assert.AreEqual("ABC", call.ResponseAsync.Result); Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); var trailers = call.GetTrailers(); Assert.AreEqual(2, trailers.Count); Assert.AreEqual(headers[0].Key, trailers[0].Key); Assert.AreEqual(headers[0].Value, trailers[0].Value); Assert.AreEqual(headers[1].Key, trailers[1].Key); CollectionAssert.AreEqual(headers[1].ValueBytes, trailers[1].ValueBytes); }
public AsyncCall(CallInvocationDetails <TRequest, TResponse> callDetails) : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer) { this.details = callDetails.WithOptions(callDetails.Options.Normalize()); this.initialMetadataSent = true; // we always send metadata at the very beginning of the call. }
public void UnaryCall_ServerHandlerSetsStatus() { var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); try { Calls.BlockingUnaryCall(callDetails, "SET_UNAUTHENTICATED"); Assert.Fail(); } catch (RpcException e) { Assert.AreEqual(StatusCode.Unauthenticated, e.Status.StatusCode); } }
public async Task ClientStreamingCall() { var callDetails = new CallInvocationDetails<string, string>(channel, ConcatAndEchoMethod, new CallOptions()); var call = Calls.AsyncClientStreamingCall(callDetails); await call.RequestStream.WriteAll(new string[] { "A", "B", "C" }); Assert.AreEqual("ABC", await call.ResponseAsync); }
private async Task RunGenericStreamingAsync(Channel channel, IInterarrivalTimer timer) { var request = CreateByteBufferRequest(); var stopwatch = new Stopwatch(); var callDetails = new CallInvocationDetails<byte[], byte[]>(channel, GenericService.StreamingCallMethod, new CallOptions()); using (var call = Calls.AsyncDuplexStreamingCall(callDetails)) { while (!stoppedCts.Token.IsCancellationRequested) { stopwatch.Restart(); await call.RequestStream.WriteAsync(request); await call.ResponseStream.MoveNext(); stopwatch.Stop(); // spec requires data point in nanoseconds. histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); await timer.WaitForNextAsync(); } // finish the streaming call await call.RequestStream.CompleteAsync(); Assert.IsFalse(await call.ResponseStream.MoveNext()); } }
public void DeadlineTransferredToServer() { var remainingTimeClient = TimeSpan.FromDays(7); var deadline = DateTime.UtcNow + remainingTimeClient; Thread.Sleep(1000); var callDetails = new CallInvocationDetails<string, string>(channel, TestMethod, new CallOptions(deadline: deadline)); var serverDeadlineTicksString = Calls.BlockingUnaryCall(callDetails, "RETURN_DEADLINE"); var serverDeadline = new DateTime(long.Parse(serverDeadlineTicksString), DateTimeKind.Utc); // A fairly relaxed check that the deadline set by client and deadline seen by server // are in agreement. C core takes care of the work with transferring deadline over the wire, // so we don't need an exact check here. Assert.IsTrue(Math.Abs((deadline - serverDeadline).TotalMilliseconds) < 5000); }
public void UnknownMethodHandler() { var nonexistentMethod = new Method<string, string>( MethodType.Unary, MockServiceHelper.ServiceName, "NonExistentMethod", Marshallers.StringMarshaller, Marshallers.StringMarshaller); var callDetails = new CallInvocationDetails<string, string>(channel, nonexistentMethod, new CallOptions()); var ex = Assert.Throws<RpcException>(() => Calls.BlockingUnaryCall(callDetails, "abc")); Assert.AreEqual(StatusCode.Unimplemented, ex.Status.StatusCode); }
public void UnknownMethodHandler() { var callDetails = new CallInvocationDetails<string, string>(channel, NonexistentMethod, new CallOptions()); try { Calls.BlockingUnaryCall(callDetails, "ABC"); Assert.Fail(); } catch (RpcException e) { Assert.AreEqual(StatusCode.Unimplemented, e.Status.StatusCode); } }
/// <summary> /// This constructor should only be used for testing. /// </summary> public AsyncCall(CallInvocationDetails <TRequest, TResponse> callDetails, INativeCall injectedNativeCall) : this(callDetails) { this.injectedNativeCall = injectedNativeCall; }
public async Task AsyncUnaryCall_ServerHandlerThrows() { var callDetails = new CallInvocationDetails<string, string>(channel, EchoMethod, new CallOptions()); try { await Calls.AsyncUnaryCall(callDetails, "THROW"); Assert.Fail(); } catch (RpcException e) { Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode); } }