public ServerStreamingServerCallHandler( Method <TRequest, TResponse> method, ServerStreamingServerMethod <TService, TRequest, TResponse> invoker, GrpcServiceOptions serviceOptions, ILoggerFactory loggerFactory, IGrpcServiceActivator <TService> serviceActivator, IServiceProvider serviceProvider) : base(method, serviceOptions, loggerFactory, serviceActivator, serviceProvider) { _invoker = invoker; if (ServiceOptions.HasInterceptors) { ServerStreamingServerMethod <TRequest, TResponse> resolvedInvoker = async(resolvedRequest, responseStream, resolvedContext) => { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(resolvedContext.GetHttpContext().RequestServices); await _invoker(serviceHandle.Instance, resolvedRequest, responseStream, resolvedContext); } finally { if (serviceHandle.Instance != null) { ServiceActivator.Release(serviceHandle); } } }; var interceptorPipeline = new InterceptorPipelineBuilder <TRequest, TResponse>(ServiceOptions.Interceptors, ServiceProvider); _pipelineInvoker = interceptorPipeline.ServerStreamingPipeline(resolvedInvoker); } }
/// <summary> /// Invoke the client streaming method with the specified <see cref="HttpContext"/>. /// </summary> /// <param name="httpContext">The <see cref="HttpContext"/> for the current request.</param> /// <param name="serverCallContext">The <see cref="ServerCallContext"/>.</param> /// <param name="requestStream">The <typeparamref name="TRequest"/> reader.</param> /// <returns>A <see cref="Task{TResponse}"/> that represents the asynchronous method. The <see cref="Task{TResponse}.Result"/> /// property returns the <typeparamref name="TResponse"/> message.</returns> public async Task <TResponse> Invoke(HttpContext httpContext, ServerCallContext serverCallContext, IAsyncStreamReader <TRequest> requestStream) { if (_pipelineInvoker == null) { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(httpContext.RequestServices); return(await _invoker( serviceHandle.Instance, requestStream, serverCallContext)); } finally { if (serviceHandle.Instance != null) { await ServiceActivator.ReleaseAsync(serviceHandle); } } } else { return(await _pipelineInvoker( requestStream, serverCallContext)); } }
protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext) { // Decode request var request = await httpContext.Request.BodyReader.ReadSingleMessageAsync <TRequest>(serverCallContext, Method.RequestMarshaller.ContextualDeserializer); if (_pipelineInvoker == null) { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(httpContext.RequestServices); await _invoker( serviceHandle.Instance, request, new HttpContextStreamWriter <TResponse>(serverCallContext, Method.ResponseMarshaller.ContextualSerializer), serverCallContext); } finally { if (serviceHandle.Instance != null) { ServiceActivator.Release(serviceHandle); } } } else { await _pipelineInvoker( request, new HttpContextStreamWriter <TResponse>(serverCallContext, Method.ResponseMarshaller.ContextualSerializer), serverCallContext); } }
/// <summary> /// Invoke the server streaming method with the specified <see cref="HttpContext"/>. /// </summary> /// <param name="httpContext">The <see cref="HttpContext"/> for the current request.</param> /// <param name="serverCallContext">The <see cref="ServerCallContext"/>.</param> /// <param name="request">The <typeparamref name="TRequest"/> message.</param> /// <param name="streamWriter">The <typeparamref name="TResponse"/> stream writer.</param> /// <returns>A <see cref="Task"/> that represents the asynchronous method.</returns> public async Task Invoke(HttpContext httpContext, ServerCallContext serverCallContext, TRequest request, IServerStreamWriter <TResponse> streamWriter) { if (_pipelineInvoker == null) { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(httpContext.RequestServices); await _invoker( serviceHandle.Instance, request, streamWriter, serverCallContext); } finally { if (serviceHandle.Instance != null) { await ServiceActivator.ReleaseAsync(serviceHandle); } } } else { await _pipelineInvoker( request, streamWriter, serverCallContext); } }
protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext) { // Disable request body data rate for client streaming DisableMinRequestBodyDataRateAndMaxRequestBodySize(httpContext); if (_pipelineInvoker == null) { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(httpContext.RequestServices); await _invoker( serviceHandle.Instance, new HttpContextStreamReader <TRequest>(serverCallContext, Method.RequestMarshaller.ContextualDeserializer), new HttpContextStreamWriter <TResponse>(serverCallContext, Method.ResponseMarshaller.ContextualSerializer), serverCallContext); } finally { if (serviceHandle.Instance != null) { ServiceActivator.Release(serviceHandle); } } } else { await _pipelineInvoker( new HttpContextStreamReader <TRequest>(serverCallContext, Method.RequestMarshaller.ContextualDeserializer), new HttpContextStreamWriter <TResponse>(serverCallContext, Method.ResponseMarshaller.ContextualSerializer), serverCallContext); } }
/// <summary> /// Invoke the unary method with the specified <see cref="HttpContext"/>. /// </summary> /// <param name="httpContext">The <see cref="HttpContext"/> for the current request.</param> /// <param name="serverCallContext">The <see cref="ServerCallContext"/>.</param> /// <param name="request">The <typeparamref name="TRequest"/> message.</param> /// <returns>A <see cref="Task{TResponse}"/> that represents the asynchronous method. The <see cref="Task{TResponse}.Result"/> /// property returns the <typeparamref name="TResponse"/> message.</returns> public Task <TResponse> Invoke(HttpContext httpContext, ServerCallContext serverCallContext, TRequest request) { if (_pipelineInvoker == null) { GrpcActivatorHandle <TService> serviceHandle = default; Task <TResponse>?invokerTask = null; try { serviceHandle = ServiceActivator.Create(httpContext.RequestServices); invokerTask = _invoker( serviceHandle.Instance, request, serverCallContext); } catch (Exception ex) { // Invoker calls user code. User code may throw an exception instead // of a faulted task. We need to catch the exception, ensure cleanup // runs and convert exception into a faulted task. if (serviceHandle.Instance != null) { var releaseTask = ServiceActivator.ReleaseAsync(serviceHandle); if (!releaseTask.IsCompletedSuccessfully) { // Capture the current exception state so we can rethrow it after awaiting // with the same stack trace. var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(ex); return(AwaitServiceReleaseAndThrow(releaseTask, exceptionDispatchInfo)); } } return(Task.FromException <TResponse>(ex)); } if (invokerTask.IsCompletedSuccessfully && serviceHandle.Instance != null) { var releaseTask = ServiceActivator.ReleaseAsync(serviceHandle); if (!releaseTask.IsCompletedSuccessfully) { return(AwaitServiceReleaseAndReturn(invokerTask.Result, serviceHandle)); } return(invokerTask); } return(AwaitInvoker(invokerTask, serviceHandle)); } else { return(_pipelineInvoker( request, serverCallContext)); } }
private async Task <TResponse> AwaitInvoker(Task <TResponse> invokerTask, GrpcActivatorHandle <TService> serviceHandle) { try { return(await invokerTask); } finally { if (serviceHandle.Instance != null) { await ServiceActivator.ReleaseAsync(serviceHandle); } } }
private async Task <TResponse> ResolvedInterceptorInvoker(TRequest resolvedRequest, ServerCallContext resolvedContext) { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(resolvedContext.GetHttpContext().RequestServices); return(await _invoker(serviceHandle.Instance, resolvedRequest, resolvedContext)); } finally { if (serviceHandle.Instance != null) { await ServiceActivator.ReleaseAsync(serviceHandle); } } }
protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext) { var requestPayload = await httpContext.Request.BodyReader.ReadSingleMessageAsync(serverCallContext); serverCallContext.DeserializationContext.SetPayload(requestPayload); var request = Method.RequestMarshaller.ContextualDeserializer(serverCallContext.DeserializationContext); serverCallContext.DeserializationContext.SetPayload(null); GrpcEventSource.Log.MessageReceived(); TResponse?response = null; if (_pipelineInvoker == null) { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(httpContext.RequestServices); response = await _invoker(serviceHandle.Instance, request, serverCallContext); } finally { if (serviceHandle.Instance != null) { ServiceActivator.Release(serviceHandle); } } } else { response = await _pipelineInvoker(request, serverCallContext); } if (response == null) { // This is consistent with Grpc.Core when a null value is returned throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method.")); } var responseBodyWriter = httpContext.Response.BodyWriter; await responseBodyWriter.WriteMessageAsync(response, serverCallContext, Method.ResponseMarshaller.ContextualSerializer, canFlush : false); GrpcEventSource.Log.MessageSent(); }
protected override async Task HandleCallAsyncCore(HttpContext httpContext, HttpContextServerCallContext serverCallContext) { // Disable request body data rate for client streaming DisableMinRequestBodyDataRateAndMaxRequestBodySize(httpContext); TResponse?response = null; if (_pipelineInvoker == null) { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(httpContext.RequestServices); response = await _invoker( serviceHandle.Instance, new HttpContextStreamReader <TRequest>(serverCallContext, Method.RequestMarshaller.ContextualDeserializer), serverCallContext); } finally { if (serviceHandle.Instance != null) { ServiceActivator.Release(serviceHandle); } } } else { response = await _pipelineInvoker( new HttpContextStreamReader <TRequest>(serverCallContext, Method.RequestMarshaller.ContextualDeserializer), serverCallContext); } if (response == null) { // This is consistent with Grpc.Core when a null value is returned throw new RpcException(new Status(StatusCode.Cancelled, "No message returned from method.")); } var responseBodyWriter = httpContext.Response.BodyWriter; await responseBodyWriter.WriteMessageAsync(response, serverCallContext, Method.ResponseMarshaller.ContextualSerializer, canFlush : false); GrpcEventSource.Log.MessageSent(); }
private async Task ResolvedInterceptorInvoker(IAsyncStreamReader <TRequest> requestStream, IServerStreamWriter <TResponse> responseStream, ServerCallContext resolvedContext) { GrpcActivatorHandle <TService> serviceHandle = default; try { serviceHandle = ServiceActivator.Create(resolvedContext.GetHttpContext().RequestServices); await _invoker( serviceHandle.Instance, requestStream, responseStream, resolvedContext); } finally { if (serviceHandle.Instance != null) { await ServiceActivator.ReleaseAsync(serviceHandle); } } }
public ValueTask ReleaseAsync(GrpcActivatorHandle <TGrpcService> service) { throw new NotImplementedException(); }
public ValueTask ReleaseAsync(GrpcActivatorHandle <Interceptor> interceptor) { return(default);
public ValueTask ReleaseAsync(GrpcActivatorHandle <TGrpcService> service) { return(default);
private async Task <TResponse> AwaitServiceReleaseAndReturn(TResponse invokerResult, GrpcActivatorHandle <TService> serviceHandle) { await ServiceActivator.ReleaseAsync(serviceHandle); return(invokerResult); }
public ValueTask ReleaseAsync(GrpcActivatorHandle <TGrpcService> service) { Released = true; return(new ValueTask(_tcs.Task)); }