Skip to content
Snippets Groups Projects
Commit bdb1b486 authored by Jan Tattermusch's avatar Jan Tattermusch
Browse files

add a generic constraint for TRequest and TResponse to require a class

parent 9b9a877e
No related branches found
No related tags found
No related merge requests found
Showing
with 71 additions and 8 deletions
...@@ -40,7 +40,9 @@ namespace Grpc.Core ...@@ -40,7 +40,9 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Return type for client streaming calls. /// Return type for client streaming calls.
/// </summary> /// </summary>
public struct AsyncClientStreamingCall<TRequest, TResponse> public sealed class AsyncClientStreamingCall<TRequest, TResponse>
where TRequest : class
where TResponse : class
{ {
readonly IClientStreamWriter<TRequest> requestStream; readonly IClientStreamWriter<TRequest> requestStream;
readonly Task<TResponse> result; readonly Task<TResponse> result;
......
...@@ -40,7 +40,9 @@ namespace Grpc.Core ...@@ -40,7 +40,9 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Return type for bidirectional streaming calls. /// Return type for bidirectional streaming calls.
/// </summary> /// </summary>
public struct AsyncDuplexStreamingCall<TRequest, TResponse> public sealed class AsyncDuplexStreamingCall<TRequest, TResponse>
where TRequest : class
where TResponse : class
{ {
readonly IClientStreamWriter<TRequest> requestStream; readonly IClientStreamWriter<TRequest> requestStream;
readonly IAsyncStreamReader<TResponse> responseStream; readonly IAsyncStreamReader<TResponse> responseStream;
......
...@@ -40,7 +40,8 @@ namespace Grpc.Core ...@@ -40,7 +40,8 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Return type for server streaming calls. /// Return type for server streaming calls.
/// </summary> /// </summary>
public struct AsyncServerStreamingCall<TResponse> public sealed class AsyncServerStreamingCall<TResponse>
where TResponse : class
{ {
readonly IAsyncStreamReader<TResponse> responseStream; readonly IAsyncStreamReader<TResponse> responseStream;
......
...@@ -41,6 +41,8 @@ namespace Grpc.Core ...@@ -41,6 +41,8 @@ namespace Grpc.Core
/// Abstraction of a call to be invoked on a client. /// Abstraction of a call to be invoked on a client.
/// </summary> /// </summary>
public class Call<TRequest, TResponse> public class Call<TRequest, TResponse>
where TRequest : class
where TResponse : class
{ {
readonly string name; readonly string name;
readonly Marshaller<TRequest> requestMarshaller; readonly Marshaller<TRequest> requestMarshaller;
......
...@@ -44,6 +44,8 @@ namespace Grpc.Core ...@@ -44,6 +44,8 @@ namespace Grpc.Core
public static class Calls public static class Calls
{ {
public static TResponse BlockingUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token) public static TResponse BlockingUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
where TRequest : class
where TResponse : class
{ {
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer); var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
// TODO(jtattermusch): this gives a race that cancellation can be requested before the call even starts. // TODO(jtattermusch): this gives a race that cancellation can be requested before the call even starts.
...@@ -52,6 +54,8 @@ namespace Grpc.Core ...@@ -52,6 +54,8 @@ namespace Grpc.Core
} }
public static async Task<TResponse> AsyncUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token) public static async Task<TResponse> AsyncUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
where TRequest : class
where TResponse : class
{ {
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer); var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name); asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name);
...@@ -61,6 +65,8 @@ namespace Grpc.Core ...@@ -61,6 +65,8 @@ namespace Grpc.Core
} }
public static AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token) public static AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
where TRequest : class
where TResponse : class
{ {
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer); var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name); asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name);
...@@ -71,6 +77,8 @@ namespace Grpc.Core ...@@ -71,6 +77,8 @@ namespace Grpc.Core
} }
public static AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token) public static AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token)
where TRequest : class
where TResponse : class
{ {
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer); var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name); asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name);
...@@ -81,6 +89,8 @@ namespace Grpc.Core ...@@ -81,6 +89,8 @@ namespace Grpc.Core
} }
public static AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token) public static AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Call<TRequest, TResponse> call, CancellationToken token)
where TRequest : class
where TResponse : class
{ {
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer); var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name); asyncCall.Initialize(call.Channel, GetCompletionQueue(), call.Name);
......
...@@ -44,9 +44,10 @@ namespace Grpc.Core ...@@ -44,9 +44,10 @@ namespace Grpc.Core
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
public interface IAsyncStreamReader<T> public interface IAsyncStreamReader<T>
where T : class
{ {
/// <summary> /// <summary>
/// Reads a single message. Returns default(T) if the last message was already read. /// Reads a single message. Returns null if the last message was already read.
/// A following read can only be started when the previous one finishes. /// A following read can only be started when the previous one finishes.
/// </summary> /// </summary>
Task<T> ReadNext(); Task<T> ReadNext();
......
...@@ -44,6 +44,7 @@ namespace Grpc.Core ...@@ -44,6 +44,7 @@ namespace Grpc.Core
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
public interface IAsyncStreamWriter<T> public interface IAsyncStreamWriter<T>
where T : class
{ {
/// <summary> /// <summary>
/// Writes a single message. Only one write can be pending at a time. /// Writes a single message. Only one write can be pending at a time.
......
...@@ -44,6 +44,7 @@ namespace Grpc.Core ...@@ -44,6 +44,7 @@ namespace Grpc.Core
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
public interface IClientStreamWriter<T> : IAsyncStreamWriter<T> public interface IClientStreamWriter<T> : IAsyncStreamWriter<T>
where T : class
{ {
/// <summary> /// <summary>
/// Closes the stream. Can only be called once there is no pending write. No writes should follow calling this. /// Closes the stream. Can only be called once there is no pending write. No writes should follow calling this.
......
...@@ -43,6 +43,7 @@ namespace Grpc.Core ...@@ -43,6 +43,7 @@ namespace Grpc.Core
/// A writable stream of messages that is used in server-side handlers. /// A writable stream of messages that is used in server-side handlers.
/// </summary> /// </summary>
public interface IServerStreamWriter<T> : IAsyncStreamWriter<T> public interface IServerStreamWriter<T> : IAsyncStreamWriter<T>
where T : class
{ {
} }
} }
...@@ -38,6 +38,8 @@ namespace Grpc.Core.Internal ...@@ -38,6 +38,8 @@ namespace Grpc.Core.Internal
/// Writes requests asynchronously to an underlying AsyncCall object. /// Writes requests asynchronously to an underlying AsyncCall object.
/// </summary> /// </summary>
internal class ClientRequestStream<TRequest, TResponse> : IClientStreamWriter<TRequest> internal class ClientRequestStream<TRequest, TResponse> : IClientStreamWriter<TRequest>
where TRequest : class
where TResponse : class
{ {
readonly AsyncCall<TRequest, TResponse> call; readonly AsyncCall<TRequest, TResponse> call;
......
...@@ -38,6 +38,8 @@ using System.Threading.Tasks; ...@@ -38,6 +38,8 @@ using System.Threading.Tasks;
namespace Grpc.Core.Internal namespace Grpc.Core.Internal
{ {
internal class ClientResponseStream<TRequest, TResponse> : IAsyncStreamReader<TResponse> internal class ClientResponseStream<TRequest, TResponse> : IAsyncStreamReader<TResponse>
where TRequest : class
where TResponse : class
{ {
readonly AsyncCall<TRequest, TResponse> call; readonly AsyncCall<TRequest, TResponse> call;
......
...@@ -45,6 +45,8 @@ namespace Grpc.Core.Internal ...@@ -45,6 +45,8 @@ namespace Grpc.Core.Internal
} }
internal class UnaryServerCallHandler<TRequest, TResponse> : IServerCallHandler internal class UnaryServerCallHandler<TRequest, TResponse> : IServerCallHandler
where TRequest : class
where TResponse : class
{ {
readonly Method<TRequest, TResponse> method; readonly Method<TRequest, TResponse> method;
readonly UnaryServerMethod<TRequest, TResponse> handler; readonly UnaryServerMethod<TRequest, TResponse> handler;
...@@ -93,6 +95,8 @@ namespace Grpc.Core.Internal ...@@ -93,6 +95,8 @@ namespace Grpc.Core.Internal
} }
internal class ServerStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler internal class ServerStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler
where TRequest : class
where TResponse : class
{ {
readonly Method<TRequest, TResponse> method; readonly Method<TRequest, TResponse> method;
readonly ServerStreamingServerMethod<TRequest, TResponse> handler; readonly ServerStreamingServerMethod<TRequest, TResponse> handler;
...@@ -142,6 +146,8 @@ namespace Grpc.Core.Internal ...@@ -142,6 +146,8 @@ namespace Grpc.Core.Internal
} }
internal class ClientStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler internal class ClientStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler
where TRequest : class
where TResponse : class
{ {
readonly Method<TRequest, TResponse> method; readonly Method<TRequest, TResponse> method;
readonly ClientStreamingServerMethod<TRequest, TResponse> handler; readonly ClientStreamingServerMethod<TRequest, TResponse> handler;
...@@ -195,6 +201,8 @@ namespace Grpc.Core.Internal ...@@ -195,6 +201,8 @@ namespace Grpc.Core.Internal
} }
internal class DuplexStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler internal class DuplexStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler
where TRequest : class
where TResponse : class
{ {
readonly Method<TRequest, TResponse> method; readonly Method<TRequest, TResponse> method;
readonly DuplexStreamingServerMethod<TRequest, TResponse> handler; readonly DuplexStreamingServerMethod<TRequest, TResponse> handler;
......
...@@ -41,21 +41,29 @@ namespace Grpc.Core.Internal ...@@ -41,21 +41,29 @@ namespace Grpc.Core.Internal
internal static class ServerCalls internal static class ServerCalls
{ {
public static IServerCallHandler UnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, UnaryServerMethod<TRequest, TResponse> handler) public static IServerCallHandler UnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, UnaryServerMethod<TRequest, TResponse> handler)
where TRequest : class
where TResponse : class
{ {
return new UnaryServerCallHandler<TRequest, TResponse>(method, handler); return new UnaryServerCallHandler<TRequest, TResponse>(method, handler);
} }
public static IServerCallHandler ClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, ClientStreamingServerMethod<TRequest, TResponse> handler) public static IServerCallHandler ClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, ClientStreamingServerMethod<TRequest, TResponse> handler)
where TRequest : class
where TResponse : class
{ {
return new ClientStreamingServerCallHandler<TRequest, TResponse>(method, handler); return new ClientStreamingServerCallHandler<TRequest, TResponse>(method, handler);
} }
public static IServerCallHandler ServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, ServerStreamingServerMethod<TRequest, TResponse> handler) public static IServerCallHandler ServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, ServerStreamingServerMethod<TRequest, TResponse> handler)
where TRequest : class
where TResponse : class
{ {
return new ServerStreamingServerCallHandler<TRequest, TResponse>(method, handler); return new ServerStreamingServerCallHandler<TRequest, TResponse>(method, handler);
} }
public static IServerCallHandler DuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, DuplexStreamingServerMethod<TRequest, TResponse> handler) public static IServerCallHandler DuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, DuplexStreamingServerMethod<TRequest, TResponse> handler)
where TRequest : class
where TResponse : class
{ {
return new DuplexStreamingServerCallHandler<TRequest, TResponse>(method, handler); return new DuplexStreamingServerCallHandler<TRequest, TResponse>(method, handler);
} }
......
...@@ -38,6 +38,8 @@ using System.Threading.Tasks; ...@@ -38,6 +38,8 @@ using System.Threading.Tasks;
namespace Grpc.Core.Internal namespace Grpc.Core.Internal
{ {
internal class ServerRequestStream<TRequest, TResponse> : IAsyncStreamReader<TRequest> internal class ServerRequestStream<TRequest, TResponse> : IAsyncStreamReader<TRequest>
where TRequest : class
where TResponse : class
{ {
readonly AsyncCallServer<TRequest, TResponse> call; readonly AsyncCallServer<TRequest, TResponse> call;
......
...@@ -39,6 +39,8 @@ namespace Grpc.Core.Internal ...@@ -39,6 +39,8 @@ namespace Grpc.Core.Internal
/// Writes responses asynchronously to an underlying AsyncCallServer object. /// Writes responses asynchronously to an underlying AsyncCallServer object.
/// </summary> /// </summary>
internal class ServerResponseStream<TRequest, TResponse> : IServerStreamWriter<TResponse> internal class ServerResponseStream<TRequest, TResponse> : IServerStreamWriter<TResponse>
where TRequest : class
where TResponse : class
{ {
readonly AsyncCallServer<TRequest, TResponse> call; readonly AsyncCallServer<TRequest, TResponse> call;
......
...@@ -42,20 +42,28 @@ namespace Grpc.Core ...@@ -42,20 +42,28 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Server-side handler for unary call. /// Server-side handler for unary call.
/// </summary> /// </summary>
public delegate Task<TResponse> UnaryServerMethod<TRequest, TResponse>(TRequest request); public delegate Task<TResponse> UnaryServerMethod<TRequest, TResponse>(TRequest request)
where TRequest : class
where TResponse : class;
/// <summary> /// <summary>
/// Server-side handler for client streaming call. /// Server-side handler for client streaming call.
/// </summary> /// </summary>
public delegate Task<TResponse> ClientStreamingServerMethod<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream); public delegate Task<TResponse> ClientStreamingServerMethod<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream)
where TRequest : class
where TResponse : class;
/// <summary> /// <summary>
/// Server-side handler for server streaming call. /// Server-side handler for server streaming call.
/// </summary> /// </summary>
public delegate Task ServerStreamingServerMethod<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream); public delegate Task ServerStreamingServerMethod<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream)
where TRequest : class
where TResponse : class;
/// <summary> /// <summary>
/// Server-side handler for bidi streaming call. /// Server-side handler for bidi streaming call.
/// </summary> /// </summary>
public delegate Task DuplexStreamingServerMethod<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream); public delegate Task DuplexStreamingServerMethod<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream)
where TRequest : class
where TResponse : class;
} }
...@@ -76,6 +76,8 @@ namespace Grpc.Core ...@@ -76,6 +76,8 @@ namespace Grpc.Core
public Builder AddMethod<TRequest, TResponse>( public Builder AddMethod<TRequest, TResponse>(
Method<TRequest, TResponse> method, Method<TRequest, TResponse> method,
UnaryServerMethod<TRequest, TResponse> handler) UnaryServerMethod<TRequest, TResponse> handler)
where TRequest : class
where TResponse : class
{ {
callHandlers.Add(GetFullMethodName(serviceName, method.Name), ServerCalls.UnaryCall(method, handler)); callHandlers.Add(GetFullMethodName(serviceName, method.Name), ServerCalls.UnaryCall(method, handler));
return this; return this;
...@@ -84,6 +86,8 @@ namespace Grpc.Core ...@@ -84,6 +86,8 @@ namespace Grpc.Core
public Builder AddMethod<TRequest, TResponse>( public Builder AddMethod<TRequest, TResponse>(
Method<TRequest, TResponse> method, Method<TRequest, TResponse> method,
ClientStreamingServerMethod<TRequest, TResponse> handler) ClientStreamingServerMethod<TRequest, TResponse> handler)
where TRequest : class
where TResponse : class
{ {
callHandlers.Add(GetFullMethodName(serviceName, method.Name), ServerCalls.ClientStreamingCall(method, handler)); callHandlers.Add(GetFullMethodName(serviceName, method.Name), ServerCalls.ClientStreamingCall(method, handler));
return this; return this;
...@@ -92,6 +96,8 @@ namespace Grpc.Core ...@@ -92,6 +96,8 @@ namespace Grpc.Core
public Builder AddMethod<TRequest, TResponse>( public Builder AddMethod<TRequest, TResponse>(
Method<TRequest, TResponse> method, Method<TRequest, TResponse> method,
ServerStreamingServerMethod<TRequest, TResponse> handler) ServerStreamingServerMethod<TRequest, TResponse> handler)
where TRequest : class
where TResponse : class
{ {
callHandlers.Add(GetFullMethodName(serviceName, method.Name), ServerCalls.ServerStreamingCall(method, handler)); callHandlers.Add(GetFullMethodName(serviceName, method.Name), ServerCalls.ServerStreamingCall(method, handler));
return this; return this;
...@@ -100,6 +106,8 @@ namespace Grpc.Core ...@@ -100,6 +106,8 @@ namespace Grpc.Core
public Builder AddMethod<TRequest, TResponse>( public Builder AddMethod<TRequest, TResponse>(
Method<TRequest, TResponse> method, Method<TRequest, TResponse> method,
DuplexStreamingServerMethod<TRequest, TResponse> handler) DuplexStreamingServerMethod<TRequest, TResponse> handler)
where TRequest : class
where TResponse : class
{ {
callHandlers.Add(GetFullMethodName(serviceName, method.Name), ServerCalls.DuplexStreamingCall(method, handler)); callHandlers.Add(GetFullMethodName(serviceName, method.Name), ServerCalls.DuplexStreamingCall(method, handler));
return this; return this;
......
...@@ -64,6 +64,8 @@ namespace Grpc.Core ...@@ -64,6 +64,8 @@ namespace Grpc.Core
/// Creates a new call to given method. /// Creates a new call to given method.
/// </summary> /// </summary>
protected Call<TRequest, TResponse> CreateCall<TRequest, TResponse>(string serviceName, Method<TRequest, TResponse> method) protected Call<TRequest, TResponse> CreateCall<TRequest, TResponse>(string serviceName, Method<TRequest, TResponse> method)
where TRequest : class
where TResponse : class
{ {
var headerBuilder = Metadata.CreateBuilder(); var headerBuilder = Metadata.CreateBuilder();
config.HeaderInterceptor(headerBuilder); config.HeaderInterceptor(headerBuilder);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment