some cleanup and better metadata support

pull/2597/head
Jan Tattermusch 9 years ago
parent ec50f281be
commit 77415b63bb
  1. 7
      src/csharp/Grpc.Core/Internal/AsyncCall.cs
  2. 140
      src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
  3. 2
      src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
  4. 7
      src/csharp/Grpc.Core/Server.cs
  5. 16
      src/csharp/ext/grpc_csharp_ext.c

@ -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
/// </summary>
private void HandleFinished(bool success, BatchContextSafeHandle ctx)
{
var status = ctx.GetReceivedStatus();
var fullStatus = ctx.GetReceivedStatusOnClient();
var status = fullStatus.Status;
AsyncCompletionDelegate<TResponse> origReadCompletionDelegate = null;
lock (myLock)

@ -38,7 +38,6 @@ using Grpc.Core;
namespace Grpc.Core.Internal
{
/// <summary>
/// Not owned version of
/// grpcsharp_batch_context
/// </summary>
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;
}
}
/// <summary>
/// Status + metadata received on client side when call finishes.
/// (when receive_status_on_client operation finishes).
/// </summary>
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;
}
}
}
/// <summary>
/// Details of a newly received RPC.
/// </summary>
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;
}
}
}
}

@ -34,8 +34,6 @@ using System.Threading.Tasks;
namespace Grpc.Core.Internal
{
/// <summary>
/// grpc_metadata_array from <grpc/grpc.h>
/// </summary>

@ -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();

@ -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) {

Loading…
Cancel
Save