Ejemplo n.º 1
0
        protected virtual async Task <TResponse> Execute <TResponse>(string method, object request, CallContext context)
        {
            AppHost.AssertFeatures(ServiceStack.Feature.Grpc);
            if (!Feature.DisableRequestParamsInHeaders)
            {
                PopulateRequestFromHeaders(request, context.CallOptions.Headers);
            }

            var req = new GrpcRequest(context, request, method);

            using var scope = req.StartScope();
            var ret = await RpcGateway.ExecuteAsync <TResponse>(request, req);

            if (req.Response.Dto == null)
            {
                req.Response.Dto = ret;
            }
            await WriteResponseHeadersAsync(req.Response, context);

            return(ret);
        }
Ejemplo n.º 2
0
        protected virtual async IAsyncEnumerable <TResponse> Stream <TRequest, TResponse>(TRequest request, CallContext context)
        {
            AppHost.AssertFeatures(ServiceStack.Feature.Grpc);
            if (!Feature.DisableRequestParamsInHeaders)
            {
                PopulateRequestFromHeaders(request, context.CallOptions.Headers);
            }

            if (!Feature.RequestServiceTypeMap.TryGetValue(typeof(TRequest), out var serviceType))
            {
                throw new NotSupportedException($"'{typeof(TRequest).Name}' was not registered in GrpcFeature.RegisterServices");
            }

            var service = (IStreamService <TRequest, TResponse>)AppHost.Container.Resolve(serviceType);

            using var disposableService = service as IDisposable;

            var req = new GrpcRequest(context, request, HttpMethods.Post);

            using var scope = req.StartScope();
            var res = req.Response;

            if (service is IRequiresRequest requiresRequest)
            {
                requiresRequest.Request = req;
            }

            IAsyncEnumerable <TResponse> response = default;

            try
            {
                if (AppHost.ApplyPreRequestFilters(req, req.Response))
                {
                    yield break;
                }

                await AppHost.ApplyRequestFiltersAsync(req, res, request);

                if (res.IsClosed)
                {
                    yield break;
                }

                response = service.Stream(request, context.CancellationToken);
            }
            catch (Exception e)
            {
                res.Dto = RpcGateway.CreateErrorResponse <TResponse>(res, e);
                await WriteResponseHeadersAsync(res, context);

                yield break; //written in headers
            }

            if (response != null)
            {
                var  enumerator = response.GetAsyncEnumerator();
                bool more;
                try
                {
                    more = await enumerator.MoveNextAsync();
                }
                catch (Exception e)
                {
                    // catch + handle first Exception
                    res.Dto = RpcGateway.CreateErrorResponse <TResponse>(res, e);
                    await WriteResponseHeadersAsync(res, context);

                    await enumerator.DisposeAsync();

                    yield break; //written in headers
                }
                yield return(enumerator.Current);

                while (more)
                {
                    try
                    {
                        more = await enumerator.MoveNextAsync();
                    }
                    catch (OperationCanceledException)
                    {
                        await enumerator.DisposeAsync();

                        yield break;
                    }
                    catch (Exception)
                    {
                        await enumerator.DisposeAsync();

                        yield break;
                    }
                    if (more)
                    {
                        yield return(enumerator.Current);
                    }
                }

                await enumerator.DisposeAsync();
            }
        }