public static Create ( Metadata metadata ) : |
||
metadata | Metadata | |
return |
/// <summary> /// Starts a unary request - unary response call. /// </summary> public Task <TResponse> UnaryCallAsync(TRequest msg) { lock (myLock) { GrpcPreconditions.CheckState(!started); started = true; Initialize(details.Channel.CompletionQueue); halfcloseRequested = true; readingDone = true; byte[] payload = UnsafeSerialize(msg); unaryResponseTcs = new TaskCompletionSource <TResponse>(); using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { call.StartUnary(HandleUnaryResponse, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); } return(unaryResponseTcs.Task); } }
/// <summary> /// Initiates sending a initial metadata. /// Even though C-core allows sending metadata in parallel to sending messages, we will treat sending metadata as a send message operation /// to make things simpler. /// completionDelegate is invoked upon completion. /// </summary> public void StartSendInitialMetadata(Metadata headers, AsyncCompletionDelegate <object> completionDelegate) { lock (myLock) { GrpcPreconditions.CheckNotNull(headers, "metadata"); GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); GrpcPreconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call."); GrpcPreconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts."); CheckSendingAllowed(allowFinished: false); GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); using (var metadataArray = MetadataArraySafeHandle.Create(headers)) { call.StartSendInitialMetadata(HandleSendFinished, metadataArray); } this.initialMetadataSent = true; sendCompletionDelegate = completionDelegate; } }
/// <summary> /// Starts a unary request - streamed response call. /// </summary> public void StartServerStreamingCall(TRequest msg, IObserver <TResponse> readObserver, Metadata headers) { lock (myLock) { Preconditions.CheckNotNull(call); started = true; halfcloseRequested = true; halfclosed = true; // halfclose not confirmed yet, but it will be once finishedHandler is called. this.readObserver = readObserver; byte[] payload = UnsafeSerialize(msg); using (var metadataArray = MetadataArraySafeHandle.Create(headers)) { call.StartServerStreaming(payload, finishedHandler, metadataArray); } StartReceiveMessage(); } }
/// <summary> /// Starts a unary request - unary response call. /// </summary> public Task <TResponse> UnaryCallAsync(TRequest msg) { lock (myLock) { bool callStartedOk = false; try { GrpcPreconditions.CheckState(!started); started = true; Initialize(details.Channel.CompletionQueue); halfcloseRequested = true; readingDone = true; using (var serializationScope = DefaultSerializationContext.GetInitializedThreadLocalScope()) { var payload = UnsafeSerialize(msg, serializationScope.Context); unaryResponseTcs = new TaskCompletionSource <TResponse>(); using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { call.StartUnary(UnaryResponseClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); callStartedOk = true; } } return(unaryResponseTcs.Task); } finally { if (!callStartedOk) { OnFailedToStartCallLocked(); } } } }
/// <summary> /// Starts a unary request - streamed response call. /// </summary> public void StartServerStreamingCall(TRequest msg) { lock (myLock) { bool callStartedOk = false; try { GrpcPreconditions.CheckState(!started); started = true; Initialize(details.Channel.CompletionQueue); halfcloseRequested = true; receiveResponseHeadersPending = true; using (var serializationScope = DefaultSerializationContext.GetInitializedThreadLocalScope()) { var payload = UnsafeSerialize(msg, serializationScope.Context); streamingResponseCallFinishedTcs = new TaskCompletionSource <object>(); using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { call.StartServerStreaming(ReceivedStatusOnClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); callStartedOk = true; } } call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); } finally { if (!callStartedOk) { OnFailedToStartCallLocked(); } } } }
private async void StartGetMetadata(AuthInterceptorContext context, IntPtr callbackPtr, IntPtr userDataPtr) { try { var metadata = new Metadata(); await interceptor(context, metadata).ConfigureAwait(false); using (var metadataArray = MetadataArraySafeHandle.Create(metadata)) { Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, metadataArray, StatusCode.OK, null); } } catch (Exception e) { Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg); Logger.Error(e, GetMetadataExceptionMsg); } }
private void NativeMetadataInterceptorHandler(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) { if (isDestroy) { gcHandle.Free(); return; } try { var context = new AuthInterceptorContext(Marshal.PtrToStringAnsi(serviceUrlPtr), Marshal.PtrToStringAnsi(methodNamePtr)); StartGetMetadata(context, callbackPtr, userDataPtr); } catch (Exception e) { Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg); Logger.Error(e, GetMetadataExceptionMsg); } }
// TODO: this method is not Async, so it shouldn't be in AsyncCall class, but // it is reusing fair amount of code in this class, so we are leaving it here. /// <summary> /// Blocking unary request - unary response call. /// </summary> public TResponse UnaryCall(TRequest msg) { var profiler = Profilers.ForCurrentThread(); using (profiler.NewScope("AsyncCall.UnaryCall")) using (CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.CreateSync()) { bool callStartedOk = false; try { unaryResponseTcs = new TaskCompletionSource <TResponse>(); lock (myLock) { GrpcPreconditions.CheckState(!started); started = true; Initialize(cq); halfcloseRequested = true; readingDone = true; } byte[] payload = UnsafeSerialize(msg); using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { var ctx = details.Channel.Environment.BatchContextPool.Lease(); try { call.StartUnary(ctx, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); callStartedOk = true; var ev = cq.Pluck(ctx.Handle); bool success = (ev.success != 0); try { using (profiler.NewScope("AsyncCall.UnaryCall.HandleBatch")) { HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessage(), ctx.GetReceivedInitialMetadata()); } } catch (Exception e) { Logger.Error(e, "Exception occurred while invoking completion delegate."); } } finally { ctx.Recycle(); } } } finally { if (!callStartedOk) { lock (myLock) { OnFailedToStartCallLocked(); } } } // Once the blocking call returns, the result should be available synchronously. // Note that GetAwaiter().GetResult() doesn't wrap exceptions in AggregateException. return(unaryResponseTcs.Task.GetAwaiter().GetResult()); } }
private void NativeMetadataInterceptorHandler(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) { if (isDestroy) { gcHandle.Free(); return; } try { var context = new AuthInterceptorContext(Marshal.PtrToStringAnsi(serviceUrlPtr), Marshal.PtrToStringAnsi(methodNamePtr)); // Make a guarantee that credentials_notify_from_plugin is invoked async to be compliant with c-core API. ThreadPool.QueueUserWorkItem(async(stateInfo) => await GetMetadataAsync(context, callbackPtr, userDataPtr)); } catch (Exception e) { Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionStatusMsg); Logger.Error(e, GetMetadataExceptionLogMsg); } }
private async void StartGetMetadata(string serviceUrl, IntPtr callbackPtr, IntPtr userDataPtr) { try { var metadata = new Metadata(); await interceptor(serviceUrl, metadata); using (var metadataArray = MetadataArraySafeHandle.Create(metadata)) { grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, metadataArray, StatusCode.OK, null); } } catch (Exception e) { grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg); Logger.Error(e, GetMetadataExceptionMsg); } }
private IObservable <Unit> GetMetadataAsync(AuthInterceptorContext context, IntPtr callbackPtr, IntPtr userDataPtr) { try { var metadata = new Metadata(); return(interceptor(context, metadata) .ForEachAsync(_ => { using (var metadataArray = MetadataArraySafeHandle.Create(metadata)) { Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, metadataArray, StatusCode.OK, null); } }) .Catch((Exception e) => { Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg); Logger.Error(e, GetMetadataExceptionMsg); return Observable.ReturnUnit(); })); } catch (Exception e) { Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg); Logger.Error(e, GetMetadataExceptionMsg); return(Observable.ReturnUnit()); } }
// TODO: this method is not Async, so it shouldn't be in AsyncCall class, but // it is reusing fair amount of code in this class, so we are leaving it here. /// <summary> /// Blocking unary request - unary response call. /// </summary> public TResponse UnaryCall(TRequest msg) { var profiler = Profilers.ForCurrentThread(); using (profiler.NewScope("AsyncCall.UnaryCall")) // Create a pluckable completion queue for the call. Avoid creating a completion queue when we know the channel has already // been shutdown. In such case, the call will fail with ObjectDisposedException immediately anyway and creating / destroying // a completion queue would lead to crash if this was the last channel in the application (and thus GrpcEnvironment has been shutdown). // See https://github.com/grpc/grpc/issues/19090 using (CompletionQueueSafeHandle cq = details.Channel.Handle.IsClosed ? null : CompletionQueueSafeHandle.CreateSync()) { bool callStartedOk = false; try { unaryResponseTcs = new TaskCompletionSource <TResponse>(); lock (myLock) { GrpcPreconditions.CheckState(!started); started = true; Initialize(cq); halfcloseRequested = true; readingDone = true; } using (var serializationScope = DefaultSerializationContext.GetInitializedThreadLocalScope()) using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { var payload = UnsafeSerialize(msg, serializationScope.Context); // do before metadata array? var ctx = details.Channel.Environment.BatchContextPool.Lease(); try { call.StartUnary(ctx, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); callStartedOk = true; var ev = cq.Pluck(ctx.Handle); bool success = (ev.success != 0); try { using (profiler.NewScope("AsyncCall.UnaryCall.HandleBatch")) { HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessageReader(), ctx.GetReceivedInitialMetadata()); } } catch (Exception e) { Logger.Error(e, "Exception occurred while invoking completion delegate."); } } finally { ctx.Recycle(); } } } finally { if (!callStartedOk) { lock (myLock) { OnFailedToStartCallLocked(); } } } // Once the blocking call returns, the result should be available synchronously. // Note that GetAwaiter().GetResult() doesn't wrap exceptions in AggregateException. return(unaryResponseTcs.Task.GetAwaiter().GetResult()); } }