Exemple #1
0
        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);
            }
        }
Exemple #2
0
 /// <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));
     }
 }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
 /// <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);
         }
     }
 }
Exemple #8
0
        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();
        }
Exemple #10
0
        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);
                }
            }
        }
Exemple #12
0
 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);
        }
Exemple #16
0
 public ValueTask ReleaseAsync(GrpcActivatorHandle <TGrpcService> service)
 {
     Released = true;
     return(new ValueTask(_tcs.Task));
 }