From 77415b63bbad2d8a6cbcf610c07da958d34f87f0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Jul 2015 20:18:26 -0700 Subject: [PATCH] some cleanup and better metadata support --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 7 +- .../Internal/BatchContextSafeHandle.cs | 140 +++++++++++++++--- .../Internal/MetadataArraySafeHandle.cs | 2 - src/csharp/Grpc.Core/Server.cs | 7 +- src/csharp/ext/grpc_csharp_ext.c | 16 +- 5 files changed, 142 insertions(+), 30 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 24b75d16686..660ad1c32a4 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -302,7 +302,9 @@ namespace Grpc.Core.Internal return; } - var status = ctx.GetReceivedStatus(); + var fullStatus = ctx.GetReceivedStatusOnClient(); + var status = fullStatus.Status; + if (status.StatusCode != StatusCode.OK) { unaryResponseTcs.SetException(new RpcException(status)); @@ -321,7 +323,8 @@ namespace Grpc.Core.Internal /// private void HandleFinished(bool success, BatchContextSafeHandle ctx) { - var status = ctx.GetReceivedStatus(); + var fullStatus = ctx.GetReceivedStatusOnClient(); + var status = fullStatus.Status; AsyncCompletionDelegate origReadCompletionDelegate = null; lock (myLock) diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs index bfd88a0940b..6a2add54db5 100644 --- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs @@ -38,7 +38,6 @@ using Grpc.Core; namespace Grpc.Core.Internal { /// - /// Not owned version of /// grpcsharp_batch_context /// internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid @@ -47,7 +46,7 @@ namespace Grpc.Core.Internal static extern BatchContextSafeHandle grpcsharp_batch_context_create(); [DllImport("grpc_csharp_ext.dll")] - static extern IntPtr grpcsharp_batch_context_receive_initial_metadata(BatchContextSafeHandle ctx); + static extern IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx); [DllImport("grpc_csharp_ext.dll")] static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx); @@ -70,6 +69,12 @@ namespace Grpc.Core.Internal [DllImport("grpc_csharp_ext.dll")] static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char* + [DllImport("grpc_csharp_ext.dll")] + static extern IntPtr grpcsharp_batch_context_server_rpc_new_host(BatchContextSafeHandle ctx); // returns const char* + + [DllImport("grpc_csharp_ext.dll")] + static extern Timespec grpcsharp_batch_context_server_rpc_new_deadline(BatchContextSafeHandle ctx); + [DllImport("grpc_csharp_ext.dll")] static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx); @@ -96,24 +101,26 @@ namespace Grpc.Core.Internal } } + // Gets data of recv_initial_metadata completion. public Metadata GetReceivedInitialMetadata() { - IntPtr metadataArrayPtr = grpcsharp_batch_context_receive_initial_metadata(this); + IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_initial_metadata(this); return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); } - - public Status GetReceivedStatus() + + // Gets data of recv_status_on_client completion. + public ClientSideStatus GetReceivedStatusOnClient() { string details = Marshal.PtrToStringAnsi(grpcsharp_batch_context_recv_status_on_client_details(this)); - return new Status(grpcsharp_batch_context_recv_status_on_client_status(this), details); - } + var status = new Status(grpcsharp_batch_context_recv_status_on_client_status(this), details); - public Metadata GetReceivedStatusTrailingMetadata() - { IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this); - return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); + var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); + + return new ClientSideStatus(status, metadata); } + // Gets data of recv_message completion. public byte[] GetReceivedMessage() { IntPtr len = grpcsharp_batch_context_recv_message_length(this); @@ -126,22 +133,22 @@ namespace Grpc.Core.Internal return data; } - public CallSafeHandle GetServerRpcNewCall() + // Gets data of server_rpc_new completion. + public ServerRpcNew GetServerRpcNew() { - return grpcsharp_batch_context_server_rpc_new_call(this); - } + var call = grpcsharp_batch_context_server_rpc_new_call(this); - public string GetServerRpcNewMethod() - { - return Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this)); - } + var method = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this)); + var host = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_host(this)); + var deadline = grpcsharp_batch_context_server_rpc_new_deadline(this); - public Metadata GetServerRpcNewRequestMetadata() - { IntPtr metadataArrayPtr = grpcsharp_batch_context_server_rpc_new_request_metadata(this); - return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); + var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); + + return new ServerRpcNew(call, method, host, deadline, metadata); } + // Gets data of receive_close_on_server completion. public bool GetReceivedCloseOnServerCancelled() { return grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0; @@ -153,4 +160,97 @@ namespace Grpc.Core.Internal return true; } } + + /// + /// Status + metadata received on client side when call finishes. + /// (when receive_status_on_client operation finishes). + /// + internal struct ClientSideStatus + { + readonly Status status; + readonly Metadata trailers; + + public ClientSideStatus(Status status, Metadata trailers) + { + this.status = status; + this.trailers = trailers; + } + + public Status Status + { + get + { + return this.status; + } + } + + public Metadata Trailers + { + get + { + return this.trailers; + } + } + } + + /// + /// Details of a newly received RPC. + /// + internal struct ServerRpcNew + { + readonly CallSafeHandle call; + readonly string method; + readonly string host; + readonly Timespec deadline; + readonly Metadata requestMetadata; + + public ServerRpcNew(CallSafeHandle call, string method, string host, Timespec deadline, Metadata requestMetadata) + { + this.call = call; + this.method = method; + this.host = host; + this.deadline = deadline; + this.requestMetadata = requestMetadata; + } + + public CallSafeHandle Call + { + get + { + return this.call; + } + } + + public string Method + { + get + { + return this.method; + } + } + + public string Host + { + get + { + return this.host; + } + } + + public Timespec Deadline + { + get + { + return this.deadline; + } + } + + public Metadata RequestMetadata + { + get + { + return this.requestMetadata; + } + } + } } \ No newline at end of file diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs index e17eb89abc7..ede85fb7f23 100644 --- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs @@ -34,8 +34,6 @@ using System.Threading.Tasks; namespace Grpc.Core.Internal { - - /// /// grpc_metadata_array from /// diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index cbf77196cf3..22f0e8973a3 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -242,13 +242,12 @@ namespace Grpc.Core { // TODO: handle error - CallSafeHandle call = ctx.GetServerRpcNewCall(); - string method = ctx.GetServerRpcNewMethod(); + ServerRpcNew newRpc = ctx.GetServerRpcNew(); // after server shutdown, the callback returns with null call - if (!call.IsInvalid) + if (!newRpc.Call.IsInvalid) { - Task.Run(async () => await InvokeCallHandler(call, method)); + Task.Run(async () => await InvokeCallHandler(newRpc.Call, newRpc.Method)); } AllowOneRpc(); diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index d8996ae7a99..cfd96d15f1d 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -175,7 +175,7 @@ grpcsharp_metadata_array_count(grpc_metadata_array *array) { GPR_EXPORT const grpc_metadata *GPR_CALLTYPE grpcsharp_metadata_array_get(grpc_metadata_array *array, size_t index) { GPR_ASSERT(index < array->count); - return array->metadata[index]; + return &(array->metadata[index]); } /* Move contents of metadata array */ @@ -230,7 +230,7 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_destroy(grpcsharp_batch_con } GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE -grpcsharp_batch_context_receive_initial_metadata( +grpcsharp_batch_context_recv_initial_metadata( const grpcsharp_batch_context *ctx) { return &(ctx->recv_initial_metadata); } @@ -294,6 +294,18 @@ grpcsharp_batch_context_server_rpc_new_method( return ctx->server_rpc_new.call_details.method; } +GPR_EXPORT const char *GPR_CALLTYPE +grpcsharp_batch_context_server_rpc_new_host( + const grpcsharp_batch_context *ctx) { + return ctx->server_rpc_new.call_details.host; +} + +GPR_EXPORT gpr_timespec GPR_CALLTYPE +grpcsharp_batch_context_server_rpc_new_deadline( + const grpcsharp_batch_context *ctx) { + return ctx->server_rpc_new.call_details.deadline; +} + GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE grpcsharp_batch_context_server_rpc_new_request_metadata( const grpcsharp_batch_context *ctx) {