blob: a8d2b9498e999af80d8242a9d42ba3f3b5cc9097 [file] [log] [blame]
Jan Tattermuscha7fff862015-02-13 11:08:08 -08001#region Copyright notice and license
2
Jan Tattermuschaf77b3d2015-02-13 11:22:21 -08003// Copyright 2015, Google Inc.
Jan Tattermuscha7fff862015-02-13 11:08:08 -08004// All rights reserved.
Craig Tiller190d3602015-02-18 09:23:38 -08005//
Jan Tattermuscha7fff862015-02-13 11:08:08 -08006// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
Craig Tiller190d3602015-02-18 09:23:38 -08009//
Jan Tattermuscha7fff862015-02-13 11:08:08 -080010// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
Craig Tiller190d3602015-02-18 09:23:38 -080019//
Jan Tattermuscha7fff862015-02-13 11:08:08 -080020// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32#endregion
33
Jan Tattermuscha7608b02015-02-03 17:54:38 -080034using System;
35using System.Threading;
36using System.Threading.Tasks;
Jan Tattermusch30868622015-02-19 09:22:33 -080037using Grpc.Core.Internal;
Jan Tattermuscha7608b02015-02-03 17:54:38 -080038
Jan Tattermusch30868622015-02-19 09:22:33 -080039namespace Grpc.Core
Jan Tattermuscha7608b02015-02-03 17:54:38 -080040{
Jan Tattermuscha7608b02015-02-03 17:54:38 -080041 /// <summary>
Jan Tattermuscha5272b62015-04-30 11:56:46 -070042 /// Helper methods for generated client stubs to make RPC calls.
Jan Tattermuscha7608b02015-02-03 17:54:38 -080043 /// </summary>
44 public static class Calls
45 {
46 public static TResponse BlockingUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
47 {
Jan Tattermuschc0b37212015-03-13 08:35:41 -070048 var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
Jan Tattermusche5c44602015-05-01 11:12:34 -070049 // TODO(jtattermusch): this gives a race that cancellation can be requested before the call even starts.
50 RegisterCancellationCallback(asyncCall, token);
Jan Tattermuschc0b37212015-03-13 08:35:41 -070051 return asyncCall.UnaryCall(call.Channel, call.Name, req, call.Headers);
Jan Tattermuscha7608b02015-02-03 17:54:38 -080052 }
53
54 public static async Task<TResponse> AsyncUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
55 {
Jan Tattermuschc0b37212015-03-13 08:35:41 -070056 var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
57 asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name);
Jan Tattermusche5c44602015-05-01 11:12:34 -070058 var asyncResult = asyncCall.UnaryCallAsync(req, call.Headers);
59 RegisterCancellationCallback(asyncCall, token);
60 return await asyncResult;
Jan Tattermuscha7608b02015-02-03 17:54:38 -080061 }
62
Jan Tattermuscha5272b62015-04-30 11:56:46 -070063 public static AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
Jan Tattermuscha7608b02015-02-03 17:54:38 -080064 {
Jan Tattermuschc0b37212015-03-13 08:35:41 -070065 var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
66 asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name);
Jan Tattermuscha5272b62015-04-30 11:56:46 -070067 asyncCall.StartServerStreamingCall(req, call.Headers);
Jan Tattermusche5c44602015-05-01 11:12:34 -070068 RegisterCancellationCallback(asyncCall, token);
Jan Tattermuscha5272b62015-04-30 11:56:46 -070069 var responseStream = new ClientResponseStream<TRequest, TResponse>(asyncCall);
70 return new AsyncServerStreamingCall<TResponse>(responseStream);
Jan Tattermuscha7608b02015-02-03 17:54:38 -080071 }
72
Jan Tattermuscha5272b62015-04-30 11:56:46 -070073 public static AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token)
Jan Tattermuscha7608b02015-02-03 17:54:38 -080074 {
Jan Tattermuschc0b37212015-03-13 08:35:41 -070075 var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
76 asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name);
Jan Tattermuscha5272b62015-04-30 11:56:46 -070077 var resultTask = asyncCall.ClientStreamingCallAsync(call.Headers);
Jan Tattermusche5c44602015-05-01 11:12:34 -070078 RegisterCancellationCallback(asyncCall, token);
Jan Tattermuscha5272b62015-04-30 11:56:46 -070079 var requestStream = new ClientRequestStream<TRequest, TResponse>(asyncCall);
80 return new AsyncClientStreamingCall<TRequest, TResponse>(requestStream, resultTask);
Jan Tattermuscha7608b02015-02-03 17:54:38 -080081 }
82
Jan Tattermuscha5272b62015-04-30 11:56:46 -070083 public static AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token)
Jan Tattermuscha7608b02015-02-03 17:54:38 -080084 {
Jan Tattermuschc0b37212015-03-13 08:35:41 -070085 var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
86 asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name);
Jan Tattermuscha5272b62015-04-30 11:56:46 -070087 asyncCall.StartDuplexStreamingCall(call.Headers);
Jan Tattermusche5c44602015-05-01 11:12:34 -070088 RegisterCancellationCallback(asyncCall, token);
Jan Tattermuscha5272b62015-04-30 11:56:46 -070089 var requestStream = new ClientRequestStream<TRequest, TResponse>(asyncCall);
90 var responseStream = new ClientResponseStream<TRequest, TResponse>(asyncCall);
91 return new AsyncDuplexStreamingCall<TRequest, TResponse>(requestStream, responseStream);
Jan Tattermuscha7608b02015-02-03 17:54:38 -080092 }
93
Jan Tattermusche5c44602015-05-01 11:12:34 -070094 private static void RegisterCancellationCallback<TRequest, TResponse>(AsyncCall<TRequest, TResponse> asyncCall, CancellationToken token)
95 {
96 if (token.CanBeCanceled)
97 {
Jan Tattermusch618647d2015-05-01 11:23:28 -070098 token.Register(() => asyncCall.Cancel());
Jan Tattermusche5c44602015-05-01 11:12:34 -070099 }
100 }
101
Jan Tattermuscha5272b62015-04-30 11:56:46 -0700102 /// <summary>
103 /// Gets shared completion queue used for async calls.
104 /// </summary>
Jan Tattermusch075dde42015-03-11 18:21:00 -0700105 private static CompletionQueueSafeHandle GetCompletionQueue()
106 {
Jan Tattermuscha7608b02015-02-03 17:54:38 -0800107 return GrpcEnvironment.ThreadPool.CompletionQueue;
108 }
109 }
110}