/// <summary> /// Invokes a duplex streaming call asynchronously. /// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses. /// The response stream is completely independent and both side can be sending messages at the same time. /// </summary> public override AsyncDuplexStreamingCall <TRequest, TResponse> AsyncDuplexStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) { var call = CreateCall(method, host, options); var response = Calls.AsyncDuplexStreamingCall(call); return(response); }
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 override AsyncDuplexStreamingCall <TRequest, TResponse> AsyncDuplexStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) { var _context = new ClientInterceptorContext <TRequest, TResponse>(method, host, options); var rspCnt = Calls.AsyncDuplexStreamingCall(CreateCall(method, host, options)); var tracingRequestStream = new TracingClientStreamWriter <TRequest, TResponse>(rspCnt.RequestStream, _context, _tracer.Request); var tracingResponseStream = new TracingAsyncClientStreamReader <TResponse, TRequest>(rspCnt.ResponseStream, _context, _tracer.Response, _tracer.Finish, _tracer.Exception); return(new AsyncDuplexStreamingCall <TRequest, TResponse>(tracingRequestStream, tracingResponseStream, rspCnt.ResponseHeadersAsync, rspCnt.GetStatus, rspCnt.GetTrailers, rspCnt.Dispose)); }
/// <summary> /// Invokes a duplex streaming call asynchronously. /// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses. /// The response stream is completely independent and both side can be sending messages at the same time. /// </summary> public override AsyncDuplexStreamingCall <TRequest, TResponse> AsyncDuplexStreamingCall <TRequest, TResponse>( Method <TRequest, TResponse> method, string host, CallOptions options) { CallOptions updateOptions = ProcessOptions(options); var call = CreateCall(method, host, updateOptions); return(Calls.AsyncDuplexStreamingCall(call)); }
public async Task AbandonedCall() { helper.DuplexStreamingHandler = new DuplexStreamingServerMethod <string, string>(async(requestStream, responseStream, context) => { await requestStream.ToListAsync(); }); var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall(new CallOptions(deadline: DateTime.UtcNow.AddMilliseconds(1)))); channel.ShutdownAsync().Wait(); server.ShutdownAsync().Wait(); }
public async Task AbandonedCall_ServerKillAsync() { var readyToShutdown = new TaskCompletionSource <object>(); helper.DuplexStreamingHandler = new DuplexStreamingServerMethod <string, string>(async(requestStream, responseStream, context) => { readyToShutdown.SetResult(null); await requestStream.ToListAsync(); }); var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall()); await readyToShutdown.Task; // make sure handler is running await channel.ShutdownAsync(); // channel.ShutdownAsync() works even if there's a pending call. await server.KillAsync(); // server.ShutdownAsync() would hang waiting for the call to finish. }
public async Task DuplexStreamingCall() { helper.DuplexStreamingHandler = new DuplexStreamingServerMethod <string, string>(async(requestStream, responseStream, context) => { while (await requestStream.MoveNext()) { await responseStream.WriteAsync(requestStream.Current); } context.ResponseTrailers.Add("xyz", "xyz-value"); }); var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall()); await call.RequestStream.WriteAllAsync(new string[] { "A", "B", "C" }); CollectionAssert.AreEqual(new string[] { "A", "B", "C" }, await call.ResponseStream.ToListAsync()); Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); Assert.AreEqual("xyz-value", call.GetTrailers()[0].Value); }
/// <summary> /// Invokes a duplex streaming call asynchronously. /// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses. /// The response stream is completely independent and both side can be sending messages at the same time. /// </summary> public override AsyncDuplexStreamingCall <TRequest, TResponse> AsyncDuplexStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) { using (var clientTrace = new ClientTrace(_serviceName, "grpc")) { var trace = clientTrace.Trace; var channel = new Channel(_target, ChannelCredentials.Insecure); var call = CreateCall(channel, method, host, options, trace); try { var response = Calls.AsyncDuplexStreamingCall(call); return(response); } finally { channel.ShutdownAsync(); } } }
public void ProcessExitHookCanCleanupAbandonedCall() { var helper = new MockServiceHelper(Host); var server = helper.GetServer(); server.Start(); var channel = helper.GetChannel(); var readyToShutdown = new TaskCompletionSource <object>(); helper.DuplexStreamingHandler = new DuplexStreamingServerMethod <string, string>(async(requestStream, responseStream, context) => { readyToShutdown.SetResult(null); await requestStream.ToListAsync(); }); var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall()); readyToShutdown.Task.Wait(); // make sure handler is running }
public async Task ResponseHeadersAsync_DuplexStreamingCall() { helper.DuplexStreamingHandler = new DuplexStreamingServerMethod <string, string>(async(requestStream, responseStream, context) => { await context.WriteResponseHeadersAsync(headers); while (await requestStream.MoveNext()) { await responseStream.WriteAsync(requestStream.Current); } }); var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall()); var responseHeaders = await call.ResponseHeadersAsync; var messages = new[] { "PASS" }; await call.RequestStream.WriteAllAsync(messages); Assert.AreEqual("ascii-header", responseHeaders[0].Key); CollectionAssert.AreEqual(messages, await call.ResponseStream.ToListAsync()); }
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())); }
public async Task WriteOptions_DuplexStreaming() { helper.DuplexStreamingHandler = new DuplexStreamingServerMethod <string, string>(async(requestStream, responseStream, context) => { await requestStream.ToListAsync(); context.WriteOptions = new WriteOptions(WriteFlags.NoCompress); await context.WriteResponseHeadersAsync(new Metadata { { "ascii-header", "abcdefg" } }); await responseStream.WriteAsync("X"); responseStream.WriteOptions = null; await responseStream.WriteAsync("Y"); responseStream.WriteOptions = new WriteOptions(WriteFlags.NoCompress); await responseStream.WriteAsync("Z"); }); var callOptions = new CallOptions(writeOptions: new WriteOptions(WriteFlags.NoCompress)); var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall(callOptions)); // check that write options from call options are propagated to request stream. Assert.IsTrue((call.RequestStream.WriteOptions.Flags & WriteFlags.NoCompress) != 0); call.RequestStream.WriteOptions = new WriteOptions(); await call.RequestStream.WriteAsync("A"); call.RequestStream.WriteOptions = null; await call.RequestStream.WriteAsync("B"); call.RequestStream.WriteOptions = new WriteOptions(WriteFlags.NoCompress); await call.RequestStream.WriteAsync("C"); await call.RequestStream.CompleteAsync(); await call.ResponseStream.ToListAsync(); }
/// <summary> /// Invokes a duplex streaming call asynchronously. /// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses. /// The response stream is completely independent and both side can be sending messages at the same time. /// </summary> public override AsyncDuplexStreamingCall <TRequest, TResponse> AsyncDuplexStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) { var trace = this.ResolveTraceSpan().Child(); trace.Record(Annotations.ClientSend()); trace.Record(Annotations.ServiceName(_serviceName)); trace.Record(Annotations.Rpc("grpc")); var channel = new Channel(_target, ChannelCredentials.Insecure); var call = CreateCall(channel, method, host, options, trace); try { var response = Calls.AsyncDuplexStreamingCall(call); return(response); } finally { trace.Record(Annotations.ClientRecv()); channel.ShutdownAsync(); } }
public AsyncDuplexStreamingCall <global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(Metadata headers = null, DateTime?deadline = null, CancellationToken cancellationToken = default(CancellationToken)) { var call = CreateCall(__Method_RouteChat, new CallOptions(headers, deadline, cancellationToken)); return(Calls.AsyncDuplexStreamingCall(call)); }
public AsyncDuplexStreamingCall <StreamingOutputCallRequest, StreamingOutputCallResponse> HalfDuplexCall(CancellationToken token = default(CancellationToken)) { var call = CreateCall(ServiceName, HalfDuplexCallMethod); return(Calls.AsyncDuplexStreamingCall(call, token)); }
public AsyncDuplexStreamingCall <global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(CallOptions options) { var call = CreateCall(__Method_RouteChat, options); return(Calls.AsyncDuplexStreamingCall(call)); }
public AsyncDuplexStreamingCall <global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options) { var call = CreateCall(__Method_StreamingCall, options); return(Calls.AsyncDuplexStreamingCall(call)); }
public AsyncDuplexStreamingCall <global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options) { var call = CreateCall(__Method_HalfDuplexCall, options); return(Calls.AsyncDuplexStreamingCall(call)); }
public AsyncDuplexStreamingCall <global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime?deadline = null, CancellationToken cancellationToken = default(CancellationToken)) { var call = CreateCall(__Method_RunClient, new CallOptions(headers, deadline, cancellationToken)); return(Calls.AsyncDuplexStreamingCall(call)); }
public AsyncDuplexStreamingCall <global::math.DivArgs, global::math.DivReply> DivMany(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken)) { var call = CreateCall(__ServiceName, __Method_DivMany, headers); return(Calls.AsyncDuplexStreamingCall(call, cancellationToken)); }
public AsyncDuplexStreamingCall <DivArgs, DivReply> DivMany(CancellationToken token = default(CancellationToken)) { var call = CreateCall(__ServiceName, __Method_DivMany); return(Calls.AsyncDuplexStreamingCall(call, token)); }
public AsyncDuplexStreamingCall <global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options) { var call = CreateCall(__Method_DivMany, options); return(Calls.AsyncDuplexStreamingCall(call)); }
public AsyncDuplexStreamingCall <global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime?deadline = null, CancellationToken cancellationToken = default(CancellationToken)) { var call = CreateCall(__Method_DivMany, new CallOptions(headers, deadline, cancellationToken)); return(Calls.AsyncDuplexStreamingCall(call)); }
public AsyncDuplexStreamingCall <global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options) { var call = CreateCall(__Method_RunClient, options); return(Calls.AsyncDuplexStreamingCall(call)); }
public override AsyncDuplexStreamingCall <TRequest, TResponse> AsyncDuplexStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) { var policy = CreatePollyPolicy <AsyncDuplexStreamingCall <TRequest, TResponse> >(); return(policy.Execute(() => Calls.AsyncDuplexStreamingCall(CreateCall(method, host, options)))); }
public AsyncDuplexStreamingCall <global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime?deadline = null, CancellationToken cancellationToken = default(CancellationToken)) { var call = CreateCall(__Method_StreamingCall, new CallOptions(headers, deadline, cancellationToken)); return(Calls.AsyncDuplexStreamingCall(call)); }
public AsyncDuplexStreamingCall <global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(CancellationToken token = default(CancellationToken)) { var call = CreateCall(__ServiceName, __Method_HalfDuplexCall); return(Calls.AsyncDuplexStreamingCall(call, token)); }
public AsyncDuplexStreamingCall <global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken)) { var call = CreateCall(__ServiceName, __Method_FullDuplexCall, headers); return(Calls.AsyncDuplexStreamingCall(call, cancellationToken)); }
public override AsyncDuplexStreamingCall <TRequest, TResponse> AsyncDuplexStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) { return(Calls.AsyncDuplexStreamingCall(CreateCall(method, host, options))); }
public AsyncDuplexStreamingCall <global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options) { var call = CreateCall(__Method_RunServer, options); return(Calls.AsyncDuplexStreamingCall(call)); }