some cleanup and better metadata support

pull/2597/head
Jan Tattermusch 10 years ago
parent ec50f281be
commit 77415b63bb
  1. 7
      src/csharp/Grpc.Core/Internal/AsyncCall.cs
  2. 138
      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; return;
} }
var status = ctx.GetReceivedStatus(); var fullStatus = ctx.GetReceivedStatusOnClient();
var status = fullStatus.Status;
if (status.StatusCode != StatusCode.OK) if (status.StatusCode != StatusCode.OK)
{ {
unaryResponseTcs.SetException(new RpcException(status)); unaryResponseTcs.SetException(new RpcException(status));
@ -321,7 +323,8 @@ namespace Grpc.Core.Internal
/// </summary> /// </summary>
private void HandleFinished(bool success, BatchContextSafeHandle ctx) private void HandleFinished(bool success, BatchContextSafeHandle ctx)
{ {
var status = ctx.GetReceivedStatus(); var fullStatus = ctx.GetReceivedStatusOnClient();
var status = fullStatus.Status;
AsyncCompletionDelegate<TResponse> origReadCompletionDelegate = null; AsyncCompletionDelegate<TResponse> origReadCompletionDelegate = null;
lock (myLock) lock (myLock)

@ -38,7 +38,6 @@ using Grpc.Core;
namespace Grpc.Core.Internal namespace Grpc.Core.Internal
{ {
/// <summary> /// <summary>
/// Not owned version of
/// grpcsharp_batch_context /// grpcsharp_batch_context
/// </summary> /// </summary>
internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid
@ -47,7 +46,7 @@ namespace Grpc.Core.Internal
static extern BatchContextSafeHandle grpcsharp_batch_context_create(); static extern BatchContextSafeHandle grpcsharp_batch_context_create();
[DllImport("grpc_csharp_ext.dll")] [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")] [DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx); static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx);
@ -70,6 +69,12 @@ namespace Grpc.Core.Internal
[DllImport("grpc_csharp_ext.dll")] [DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char* 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")] [DllImport("grpc_csharp_ext.dll")]
static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx); 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() 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); 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)); 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); 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() public byte[] GetReceivedMessage()
{ {
IntPtr len = grpcsharp_batch_context_recv_message_length(this); IntPtr len = grpcsharp_batch_context_recv_message_length(this);
@ -126,22 +133,22 @@ namespace Grpc.Core.Internal
return data; 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() var method = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this));
{ var host = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_host(this));
return Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(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); 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() public bool GetReceivedCloseOnServerCancelled()
{ {
return grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0; return grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0;
@ -153,4 +160,97 @@ namespace Grpc.Core.Internal
return true; 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 namespace Grpc.Core.Internal
{ {
/// <summary> /// <summary>
/// grpc_metadata_array from <grpc/grpc.h> /// grpc_metadata_array from <grpc/grpc.h>
/// </summary> /// </summary>

@ -242,13 +242,12 @@ namespace Grpc.Core
{ {
// TODO: handle error // TODO: handle error
CallSafeHandle call = ctx.GetServerRpcNewCall(); ServerRpcNew newRpc = ctx.GetServerRpcNew();
string method = ctx.GetServerRpcNewMethod();
// after server shutdown, the callback returns with null call // 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(); AllowOneRpc();

@ -175,7 +175,7 @@ grpcsharp_metadata_array_count(grpc_metadata_array *array) {
GPR_EXPORT const grpc_metadata *GPR_CALLTYPE GPR_EXPORT const grpc_metadata *GPR_CALLTYPE
grpcsharp_metadata_array_get(grpc_metadata_array *array, size_t index) { grpcsharp_metadata_array_get(grpc_metadata_array *array, size_t index) {
GPR_ASSERT(index < array->count); GPR_ASSERT(index < array->count);
return array->metadata[index]; return &(array->metadata[index]);
} }
/* Move contents of metadata array */ /* 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 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) { const grpcsharp_batch_context *ctx) {
return &(ctx->recv_initial_metadata); return &(ctx->recv_initial_metadata);
} }
@ -294,6 +294,18 @@ grpcsharp_batch_context_server_rpc_new_method(
return ctx->server_rpc_new.call_details.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 GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
grpcsharp_batch_context_server_rpc_new_request_metadata( grpcsharp_batch_context_server_rpc_new_request_metadata(
const grpcsharp_batch_context *ctx) { const grpcsharp_batch_context *ctx) {

Loading…
Cancel
Save