diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs index caa6220f2cc..4eb542fae89 100644 --- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs @@ -220,7 +220,7 @@ namespace Grpc.Core.Tests } } - private static async Task EchoHandler(string request) + private static async Task EchoHandler(ServerCallContext context, string request) { if (request == "THROW") { @@ -229,7 +229,7 @@ namespace Grpc.Core.Tests return request; } - private static async Task ConcatAndEchoHandler(IAsyncStreamReader requestStream) + private static async Task ConcatAndEchoHandler(ServerCallContext context, IAsyncStreamReader requestStream) { string result = ""; await requestStream.ForEach(async (request) => diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 9c91541d904..f5f2cf5f220 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -96,6 +96,7 @@ + diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index 2bef6e68b7d..95d8e978692 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -74,7 +74,8 @@ namespace Grpc.Core.Internal var request = await requestStream.ReadNext(); // TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated. Preconditions.CheckArgument(await requestStream.ReadNext() == null); - var result = await handler(request); + var context = new ServerCallContext(); // TODO(jtattermusch): initialize the context + var result = await handler(context, request); await responseStream.Write(result); } catch (Exception e) @@ -125,7 +126,8 @@ namespace Grpc.Core.Internal // TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated. Preconditions.CheckArgument(await requestStream.ReadNext() == null); - await handler(request, responseStream); + var context = new ServerCallContext(); // TODO(jtattermusch): initialize the context + await handler(context, request, responseStream); } catch (Exception e) { @@ -168,11 +170,12 @@ namespace Grpc.Core.Internal var finishedTask = asyncCall.ServerSideCallAsync(); var requestStream = new ServerRequestStream(asyncCall); var responseStream = new ServerResponseStream(asyncCall); + var context = new ServerCallContext(); // TODO(jtattermusch): initialize the context Status status = Status.DefaultSuccess; try { - var result = await handler(requestStream); + var result = await handler(context, requestStream); try { await responseStream.Write(result); @@ -223,11 +226,12 @@ namespace Grpc.Core.Internal var finishedTask = asyncCall.ServerSideCallAsync(); var requestStream = new ServerRequestStream(asyncCall); var responseStream = new ServerResponseStream(asyncCall); + var context = new ServerCallContext(); // TODO(jtattermusch): initialize the context Status status = Status.DefaultSuccess; try { - await handler(requestStream, responseStream); + await handler(context, requestStream, responseStream); } catch (Exception e) { diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs new file mode 100644 index 00000000000..e873b3e88a7 --- /dev/null +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -0,0 +1,56 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +namespace Grpc.Core +{ + /// + /// Context for a server-side call. + /// + public sealed class ServerCallContext + { + + // TODO(jtattermusch): add cancellationToken + + // TODO(jtattermusch): add deadline info + + // TODO(jtattermusch): expose initial metadata sent by client for reading + + // TODO(jtattermusch): expose method to send initial metadata back to client + + // TODO(jtattermusch): allow setting status and trailing metadata to send after handler completes. + } +} diff --git a/src/csharp/Grpc.Core/ServerMethods.cs b/src/csharp/Grpc.Core/ServerMethods.cs index 291835671f0..377b78eb302 100644 --- a/src/csharp/Grpc.Core/ServerMethods.cs +++ b/src/csharp/Grpc.Core/ServerMethods.cs @@ -42,28 +42,28 @@ namespace Grpc.Core /// /// Server-side handler for unary call. /// - public delegate Task UnaryServerMethod(TRequest request) + public delegate Task UnaryServerMethod(ServerCallContext context, TRequest request) where TRequest : class where TResponse : class; /// /// Server-side handler for client streaming call. /// - public delegate Task ClientStreamingServerMethod(IAsyncStreamReader requestStream) + public delegate Task ClientStreamingServerMethod(ServerCallContext context, IAsyncStreamReader requestStream) where TRequest : class where TResponse : class; /// /// Server-side handler for server streaming call. /// - public delegate Task ServerStreamingServerMethod(TRequest request, IServerStreamWriter responseStream) + public delegate Task ServerStreamingServerMethod(ServerCallContext context, TRequest request, IServerStreamWriter responseStream) where TRequest : class where TResponse : class; /// /// Server-side handler for bidi streaming call. /// - public delegate Task DuplexStreamingServerMethod(IAsyncStreamReader requestStream, IServerStreamWriter responseStream) + public delegate Task DuplexStreamingServerMethod(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream) where TRequest : class where TResponse : class; } diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index 60408b90184..03f5c31cb7a 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -133,13 +133,13 @@ namespace math // server-side interface public interface IMathService { - Task Div(DivArgs request); + Task Div(ServerCallContext context, DivArgs request); - Task Fib(FibArgs request, IServerStreamWriter responseStream); + Task Fib(ServerCallContext context, FibArgs request, IServerStreamWriter responseStream); - Task Sum(IAsyncStreamReader requestStream); + Task Sum(ServerCallContext context, IAsyncStreamReader requestStream); - Task DivMany(IAsyncStreamReader requestStream, IServerStreamWriter responseStream); + Task DivMany(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream); } public static ServerServiceDefinition BindService(IMathService serviceImpl) diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs index 83ec2a8c3df..800dee87354 100644 --- a/src/csharp/Grpc.Examples/MathServiceImpl.cs +++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs @@ -46,12 +46,12 @@ namespace math /// public class MathServiceImpl : MathGrpc.IMathService { - public Task Div(DivArgs request) + public Task Div(ServerCallContext context, DivArgs request) { return Task.FromResult(DivInternal(request)); } - public async Task Fib(FibArgs request, IServerStreamWriter responseStream) + public async Task Fib(ServerCallContext context, FibArgs request, IServerStreamWriter responseStream) { if (request.Limit <= 0) { @@ -68,7 +68,7 @@ namespace math } } - public async Task Sum(IAsyncStreamReader requestStream) + public async Task Sum(ServerCallContext context, IAsyncStreamReader requestStream) { long sum = 0; await requestStream.ForEach(async num => @@ -78,7 +78,7 @@ namespace math return Num.CreateBuilder().SetNum_(sum).Build(); } - public async Task DivMany(IAsyncStreamReader requestStream, IServerStreamWriter responseStream) + public async Task DivMany(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream) { await requestStream.ForEach(async divArgs => { diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceGrpc.cs index d1f8aa12c78..9f14dad6c0c 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestServiceGrpc.cs @@ -171,17 +171,17 @@ namespace grpc.testing // server-side interface public interface ITestService { - Task EmptyCall(Empty request); + Task EmptyCall(ServerCallContext context, Empty request); - Task UnaryCall(SimpleRequest request); + Task UnaryCall(ServerCallContext context, SimpleRequest request); - Task StreamingOutputCall(StreamingOutputCallRequest request, IServerStreamWriter responseStream); + Task StreamingOutputCall(ServerCallContext context, StreamingOutputCallRequest request, IServerStreamWriter responseStream); - Task StreamingInputCall(IAsyncStreamReader requestStream); + Task StreamingInputCall(ServerCallContext context, IAsyncStreamReader requestStream); - Task FullDuplexCall(IAsyncStreamReader requestStream, IServerStreamWriter responseStream); + Task FullDuplexCall(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream); - Task HalfDuplexCall(IAsyncStreamReader requestStream, IServerStreamWriter responseStream); + Task HalfDuplexCall(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream); } public static ServerServiceDefinition BindService(ITestService serviceImpl) diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs index 8b0cf3a2d05..40f32b5a88f 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs @@ -46,19 +46,19 @@ namespace grpc.testing /// public class TestServiceImpl : TestServiceGrpc.ITestService { - public Task EmptyCall(Empty request) + public Task EmptyCall(ServerCallContext context, Empty request) { return Task.FromResult(Empty.DefaultInstance); } - public Task UnaryCall(SimpleRequest request) + public Task UnaryCall(ServerCallContext context, SimpleRequest request) { var response = SimpleResponse.CreateBuilder() .SetPayload(CreateZerosPayload(request.ResponseSize)).Build(); return Task.FromResult(response); } - public async Task StreamingOutputCall(StreamingOutputCallRequest request, IServerStreamWriter responseStream) + public async Task StreamingOutputCall(ServerCallContext context, StreamingOutputCallRequest request, IServerStreamWriter responseStream) { foreach (var responseParam in request.ResponseParametersList) { @@ -68,7 +68,7 @@ namespace grpc.testing } } - public async Task StreamingInputCall(IAsyncStreamReader requestStream) + public async Task StreamingInputCall(ServerCallContext context, IAsyncStreamReader requestStream) { int sum = 0; await requestStream.ForEach(async request => @@ -78,7 +78,7 @@ namespace grpc.testing return StreamingInputCallResponse.CreateBuilder().SetAggregatedPayloadSize(sum).Build(); } - public async Task FullDuplexCall(IAsyncStreamReader requestStream, IServerStreamWriter responseStream) + public async Task FullDuplexCall(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream) { await requestStream.ForEach(async request => { @@ -91,7 +91,7 @@ namespace grpc.testing }); } - public async Task HalfDuplexCall(IAsyncStreamReader requestStream, IServerStreamWriter responseStream) + public async Task HalfDuplexCall(ServerCallContext context, IAsyncStreamReader requestStream, IServerStreamWriter responseStream) { throw new NotImplementedException(); }