public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args) { // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle. // Doing so would make object finalizer crash if we end up abandoning the handle. GrpcEnvironment.GrpcNativeInit(); return Native.grpcsharp_server_create(cq, args); }
public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, CompletionRegistry completionRegistry, BatchCompletionDelegate callback) { var ctx = BatchContextSafeHandle.Create(); completionRegistry.RegisterBatchCompletion(ctx, callback); Native.grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx); }
public CallSafeHandle CreateCall(CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials) { var result = Native.grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline); if (credentials != null) { result.SetCredentials(credentials); } result.Initialize(cq); return result; }
public CallSafeHandle CreateCall(CompletionRegistry registry, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CredentialsSafeHandle credentials) { using (Profilers.ForCurrentThread().NewScope("ChannelSafeHandle.CreateCall")) { var result = grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline); if (credentials != null) { result.SetCredentials(credentials); } result.SetCompletionRegistry(registry); return result; } }
public void Start() { lock (myLock) { if (cq != null) { throw new InvalidOperationException("Already started."); } cq = CompletionQueueSafeHandle.Create(); for (int i = 0; i < poolSize; i++) { threads.Add(CreateAndStartThread(i)); } } }
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer <TRequest, TResponse>( method.ResponseMarshaller.Serializer, method.RequestMarshaller.Deserializer, newRpc.Server); asyncCall.Initialize(newRpc.Call, cq); var finishedTask = asyncCall.ServerSideCallAsync(); var requestStream = new ServerRequestStream <TRequest, TResponse>(asyncCall); var responseStream = new ServerResponseStream <TRequest, TResponse>(asyncCall); Status status; AsyncCallServer <TRequest, TResponse> .ResponseWithFlags?responseWithFlags = null; var context = HandlerUtils.NewContext(newRpc, responseStream, asyncCall.CancellationToken); try { GrpcPreconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false)); var request = requestStream.Current; var response = await handler(request, context).ConfigureAwait(false); status = context.Status; responseWithFlags = new AsyncCallServer <TRequest, TResponse> .ResponseWithFlags(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); } catch (Exception e) { if (!(e is RpcException)) { Logger.Warning(e, "Exception occured in handler."); } status = HandlerUtils.GetStatusFromExceptionAndMergeTrailers(e, context.ResponseTrailers); } try { await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseWithFlags).ConfigureAwait(false); } catch (Exception) { asyncCall.Cancel(); throw; } await finishedTask.ConfigureAwait(false); }
private INativeCall CreateNativeCall(CompletionQueueSafeHandle cq) { if (injectedNativeCall != null) { return injectedNativeCall; // allows injecting a mock INativeCall in tests. } var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance; var credentials = details.Options.Credentials; using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null) { var result = details.Channel.Handle.CreateCall( parentCall, ContextPropagationToken.DefaultMask, cq, details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials); return result; } }
public async Task HandleCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq) { // We don't care about the payload type here. var asyncCall = new AsyncCallServer <byte[], byte[]>( (payload) => payload, (payload) => payload); asyncCall.Initialize(call); var finishedTask = asyncCall.ServerSideCallAsync(); var requestStream = new ServerRequestStream <byte[], byte[]>(asyncCall); var responseStream = new ServerResponseStream <byte[], byte[]>(asyncCall); await responseStream.WriteStatus(new Status(StatusCode.Unimplemented, "No such method.")); // TODO(jtattermusch): if we don't read what client has sent, the server call never gets disposed. await requestStream.ToList(); await finishedTask; }
public void StartCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer <TRequest, TResponse>( method.ResponseMarshaller.Serializer, method.RequestMarshaller.Deserializer); asyncCall.Initialize(call); var requestObserver = new RecordingObserver <TRequest>(); var finishedTask = asyncCall.ServerSideCallAsync(requestObserver); var request = requestObserver.ToList().Result.Single(); var responseObserver = new ServerStreamingOutputObserver <TRequest, TResponse>(asyncCall); handler(request, responseObserver); finishedTask.Wait(); }
public async Task HandleCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer <TRequest, TResponse>( method.ResponseMarshaller.Serializer, method.RequestMarshaller.Deserializer); asyncCall.Initialize(call); var finishedTask = asyncCall.ServerSideCallAsync(); var requestStream = new ServerRequestStream <TRequest, TResponse>(asyncCall); var responseStream = new ServerResponseStream <TRequest, TResponse>(asyncCall); var context = new ServerCallContext(); // TODO(jtattermusch): initialize the context Status status = Status.DefaultSuccess; try { var result = await handler(context, requestStream); try { await responseStream.WriteAsync(result); } catch (OperationCanceledException) { status = Status.DefaultCancelled; } } catch (Exception e) { Console.WriteLine("Exception occured in handler: " + e); status = HandlerUtils.StatusFromException(e); } try { await responseStream.WriteStatusAsync(status); } catch (OperationCanceledException) { // Call has been already cancelled. } await finishedTask; }
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer <TRequest, TResponse>( method.ResponseMarshaller.Serializer, method.RequestMarshaller.Deserializer, newRpc.Server); asyncCall.Initialize(newRpc.Call, cq); var finishedTask = asyncCall.ServerSideCallAsync(); var requestStream = new ServerRequestStream <TRequest, TResponse>(asyncCall); var responseStream = new ServerResponseStream <TRequest, TResponse>(asyncCall); Status status; Tuple <TResponse, WriteFlags> responseTuple = null; var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken); try { var response = await handler(requestStream, context).ConfigureAwait(false); status = context.Status; responseTuple = Tuple.Create(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); } catch (Exception e) { if (!(e is RpcException)) { Logger.Warning(e, "Exception occured in handler."); } status = HandlerUtils.StatusFromException(e); } try { await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseTuple).ConfigureAwait(false); } catch (Exception) { asyncCall.Cancel(); throw; } await finishedTask.ConfigureAwait(false); }
// 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) { using (CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create()) { byte[] payload = UnsafeSerialize(msg); unaryResponseTcs = new TaskCompletionSource <TResponse>(); lock (myLock) { Preconditions.CheckState(!started); started = true; Initialize(cq); halfcloseRequested = true; readingDone = true; } using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { using (var ctx = BatchContextSafeHandle.Create()) { call.StartUnary(ctx, payload, metadataArray, GetWriteFlagsForCall()); var ev = cq.Pluck(ctx.Handle); bool success = (ev.success != 0); try { HandleUnaryResponse(success, ctx); } catch (Exception e) { Logger.Error(e, "Exception occured while invoking completion delegate."); } } } // 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 INativeCall CreateNativeCall(CompletionQueueSafeHandle cq) { using (Profilers.ForCurrentThread().NewScope("AsyncCall.CreateNativeCall")) { if (injectedNativeCall != null) { return(injectedNativeCall); // allows injecting a mock INativeCall in tests. } var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance; var credentials = details.Options.Credentials; using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null) { var result = details.Channel.Handle.CreateCall(environment.CompletionRegistry, parentCall, ContextPropagationToken.DefaultMask, cq, details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials); return(result); } } }
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer <TRequest, TResponse>( method.ResponseMarshaller.ContextualSerializer, method.RequestMarshaller.ContextualDeserializer, newRpc.Server); asyncCall.Initialize(newRpc.Call, cq); var finishedTask = asyncCall.ServerSideCallAsync(); var requestStream = new ServerRequestStream <TRequest, TResponse>(asyncCall); var responseStream = new ServerResponseStream <TRequest, TResponse>(asyncCall); Status status; var context = HandlerUtils.NewContext(newRpc, responseStream, asyncCall.CancellationToken); try { await handler(requestStream, responseStream, context).ConfigureAwait(false); status = context.Status; } catch (Exception e) { if (!(e is RpcException)) { Logger.Warning(e, "Exception occurred in the handler or an interceptor."); } status = HandlerUtils.GetStatusFromExceptionAndMergeTrailers(e, context.ResponseTrailers); } try { await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, null).ConfigureAwait(false); } catch (Exception) { asyncCall.Cancel(); throw; } await finishedTask.ConfigureAwait(false); }
public async Task HandleCall(string methodName, CallSafeHandle call, CompletionQueueSafeHandle cq) { var asyncCall = new AsyncCallServer <TRequest, TResponse>( method.ResponseMarshaller.Serializer, method.RequestMarshaller.Deserializer); asyncCall.Initialize(call); var finishedTask = asyncCall.ServerSideCallAsync(); var requestStream = new ServerRequestStream <TRequest, TResponse>(asyncCall); var responseStream = new ServerResponseStream <TRequest, TResponse>(asyncCall); Status status = Status.DefaultSuccess; try { Preconditions.CheckArgument(await requestStream.MoveNext()); var request = requestStream.Current; // TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated. Preconditions.CheckArgument(!await requestStream.MoveNext()); var context = new ServerCallContext(); // TODO(jtattermusch): initialize the context await handler(context, request, responseStream); } catch (Exception e) { Console.WriteLine("Exception occured in handler: " + e); status = HandlerUtils.StatusFromException(e); } try { await responseStream.WriteStatusAsync(status); } catch (OperationCanceledException) { // Call has been already cancelled. } await finishedTask; }
/// <summary> /// Body of the polling thread. /// </summary> private void RunHandlerLoop(CompletionQueueSafeHandle cq) { CompletionQueueEvent ev; do { ev = cq.Next(); if (ev.type == CompletionQueueEvent.CompletionType.OpComplete) { bool success = (ev.success != 0); IntPtr tag = ev.tag; try { var callback = cq.CompletionRegistry.Extract(tag); callback(success); } catch (Exception e) { Logger.Error(e, "Exception occured while invoking completion delegate"); } } }while (ev.type != CompletionQueueEvent.CompletionType.Shutdown && !cq.IsClosed); }
/// <summary> /// Body of the polling thread. /// </summary> private void RunHandlerLoop(CompletionQueueSafeHandle cq, IProfiler optionalProfiler) { if (optionalProfiler != null) { Profilers.SetForCurrentThread(optionalProfiler); } CompletionQueueEvent ev; do { ev = cq.Next(); if (ev.type == CompletionQueueEvent.CompletionType.OpComplete) { bool success = (ev.success != 0); IntPtr tag = ev.tag; try { var callback = cq.CompletionRegistry.Extract(tag); // Use cached delegates to avoid unnecessary allocations if (!inlineHandlers) { ThreadPool.QueueUserWorkItem(success ? RunCompletionQueueEventCallbackSuccess : RunCompletionQueueEventCallbackFailure, callback); } else { RunCompletionQueueEventCallback(callback, success); } } catch (Exception e) { Logger.Error(e, "Exception occured while extracting event from completion registry."); } } }while (ev.type != CompletionQueueEvent.CompletionType.Shutdown); }
void IPlatformInvocation.grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq) { grpcsharp_completion_queue_shutdown(cq); }
static extern CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq);
void IPlatformInvocation.grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx) { grpcsharp_channel_watch_connectivity_state(channel, lastObservedState, deadline, cq, ctx); }
void IPlatformInvocation.grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx) { grpcsharp_server_shutdown_and_notify_callback(server, cq, ctx); }
ServerSafeHandle IPlatformInvocation.grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args) { return(grpcsharp_server_create(cq, args)); }
static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, IntPtr args) { return grpcsharp_server_create(cq, args); }
static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, IntPtr args);
public UsageScope(CompletionQueueSafeHandle cq) { this.cq = cq; this.cq.BeginOp(); }
CompletionQueueEvent IPlatformInvocation.grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag) { return grpcsharp_completion_queue_pluck(cq, tag); }
public void RequestCall(CompletionQueueSafeHandle cq, CompletionCallbackDelegate callback) { AssertCallOk(grpcsharp_server_request_call(this, cq, callback)); }
static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
static extern GRPCCompletionType grpcsharp_completion_queue_next_with_callback(CompletionQueueSafeHandle cq);
static extern void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
// 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()); } }
GRPCCallError IPlatformInvocation.grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx) { return(grpcsharp_server_request_call(server, cq, ctx)); }
ServerSafeHandle IPlatformInvocation.grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args) { return grpcsharp_server_create(cq, args); }
CallSafeHandle IPlatformInvocation.grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline) { return grpcsharp_channel_create_call(channel, parentCall, propagationMask, cq, method, host, deadline); }
static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq);
internal static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
static extern CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag);
internal static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq);
CompletionQueueEvent IPlatformInvocation.grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq) { return grpcsharp_completion_queue_next(cq); }
internal static extern CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag);
static extern void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
GRPCCallError IPlatformInvocation.grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx) { return grpcsharp_server_request_call(server, cq, ctx); }
public void Initialize(CompletionQueueSafeHandle completionQueue) { this.completionQueue = completionQueue; }
CallSafeHandle IPlatformInvocation.grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline) { return(grpcsharp_channel_create_call(channel, parentCall, propagationMask, cq, method, host, deadline)); }
internal static extern void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
internal static extern CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq);
static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
CompletionQueueEvent IPlatformInvocation.grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq) { return(grpcsharp_completion_queue_next(cq)); }
public CallSafeHandle CreateCall(CompletionRegistry registry, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline) { var result = grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline); result.SetCompletionRegistry(registry); return result; }
CompletionQueueEvent IPlatformInvocation.grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag) { return(grpcsharp_completion_queue_pluck(cq, tag)); }