Пример #1
0
        /// <summary>
        ///  DuplexStreaming メソッドを生成します。
        /// </summary>
        /// <typeparam name="TRequest">リクエストの型</typeparam>
        /// <typeparam name="TResponse">レスポンスの型</typeparam>
        /// <param name="builderContext">コンテキスト</param>
        /// <returns>メソッド</returns>
        private DuplexStreamingServerMethod <TRequest, TResponse> CreateDuplexStreamingServerMethod <TRequest, TResponse>(MethodBuildContext builderContext)
            where TRequest : class where TResponse : class
        {
            DuplexStreamingServerMethod <TRequest, TResponse> method = builderContext.MethodImpl.CreateDelegate(typeof(DuplexStreamingServerMethod <TRequest, TResponse>), builderContext.ServiceInstance) as DuplexStreamingServerMethod <TRequest, TResponse>;

            GrpcServerPerformanceListener performanceListener = builderContext.NeedNotifyPerformanceLog ? builderContext.Settings.PerformanceListener : null;

            return(async delegate(IAsyncStreamReader <TRequest> requestStream, IServerStreamWriter <TResponse> responseStream, ServerCallContext context)
            {
                try
                {
                    await OnExecutingServiceMethodAsync(context, builderContext.InvokingInterceptors, performanceListener).ConfigureAwait(false);

                    if (performanceListener != null)
                    {
                        performanceListener.NotifyMethodCalling(context);
                    }

                    Stopwatch watch = Stopwatch.StartNew();
                    double elapsd;

                    try
                    {
                        await method(
                            new RequestStreamReader <TRequest>(requestStream, context, performanceListener)
                            , new ResponseStreamWriter <TResponse>(responseStream, context, performanceListener)
                            , context
                            ).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        throw new GrpcServerMethodException(string.Format(Properties.MessageResources.ServerMethodFailed, context.Method) + ex.Message, ex, context);
                    }
                    finally
                    {
                        elapsd = GrpcPerformanceListener.GetMilliseconds(watch);
                        if (performanceListener != null)
                        {
                            performanceListener.NotifyMethodCalled(context, elapsd);
                        }
                    }

                    await OnExecutedServiceMethodAsync(context, builderContext.InvokedInterceptors, performanceListener).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    Exception wrapped;
                    if (HandleException(context, builderContext.ExceptionHandlers, performanceListener, ex, out wrapped))
                    {
                        GrpcExceptionListener.NotifyCatchServerException(context, wrapped);
                        throw wrapped;
                    }
                    else
                    {
                        GrpcExceptionListener.NotifyCatchServerException(context, ex);
                        throw;
                    }
                }
            });
        }
Пример #2
0
        /// <summary>
        /// サービスメソッド定義を生成します。
        /// </summary>
        /// <typeparam name="TRequest">リクエストの型</typeparam>
        /// <typeparam name="TResponse">レスポンスの型</typeparam>
        /// <param name="context">コンテキスト</param>
        /// <returns>サービスメソッド定義></returns>
        private Method <TRequest, TResponse> CreateServiceMethodFieldGeneric <TRequest, TResponse>(MethodBuildContext context)
        {
            string serviceName = context.GetServiceName();
            string methodName  = context.GetServiceMethodName();

            GrpcServerPerformanceListener performanceListener = context.NeedNotifyPerformanceLog ? context.Settings.PerformanceListener : null;

            Marshaller <TRequest>  request  = CreateMethodMarshaller <TRequest>(serviceName, methodName, performanceListener, context.Settings);
            Marshaller <TResponse> response = CreateMethodMarshaller <TResponse>(serviceName, methodName, performanceListener, context.Settings);

            return(new Method <TRequest, TResponse>(context.MethodType, serviceName, methodName, request, response));
        }
Пример #3
0
        /// <summary>
        /// 例外を処理します。
        /// </summary>
        /// <param name="context">コンテキスト</param>
        /// <param name="exceptionHandlers">例外ハンドラ</param>
        /// <param name="performanceListener">パフォーマンスリスナー</param>
        /// <param name="original">発生した例外</param>
        /// <param name="alternate">代わりにスローする例外</param>
        /// <returns>例外がラップされた場合、true を返します。</returns>
        private bool HandleException(ServerCallContext context, IEnumerable <IGrpcServerMethodExceptionHandler> exceptionHandlers, GrpcServerPerformanceListener performanceListener, Exception original, out Exception alternate)
        {
            Exception alt = null;

            if (exceptionHandlers != null)
            {
                foreach (IGrpcServerMethodExceptionHandler handler in exceptionHandlers)
                {
                    if (handler == null)
                    {
                        continue;
                    }

                    Stopwatch watch = Stopwatch.StartNew();

                    try
                    {
                        if (handler.RelpaceException(context, original, out alt))
                        {
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new GrpcServerMethodException(string.Format(Properties.MessageResources.ServerMethodInterceptorFailed + ex.Message, context.Method, handler.Name), ex, context, handler);
                    }
                    finally
                    {
                        if (performanceListener != null)
                        {
                            performanceListener.NotifyMethodIntercepted(context, handler, GrpcPerformanceListener.GetMilliseconds(watch));
                        }
                    }
                }
            }

            if (alt == null)
            {
                alt = original;
            }

            RpcException rpc = alt as RpcException;

            if (rpc == null)
            {
                alternate = CreateRpcException(context, alt);
            }
            else
            {
                alternate = rpc;
            }

            return(!object.Equals(original, alternate));
        }
Пример #4
0
        /// <summary>
        /// サービスメソッドが呼び出されたときの処理を行います。
        /// </summary>
        /// <param name="context">コンテキスト</param>
        /// <param name="interceptors">割込処理</param>
        /// <param name="performanceListener">パフォーマンスリスナー</param>
        /// <returns></returns>
        private async Task OnExecutedServiceMethodAsync(ServerCallContext context, IEnumerable <IGrpcServerMethodInvokedInterceptor> interceptors, GrpcServerPerformanceListener performanceListener)
        {
            if (interceptors != null)
            {
                foreach (IGrpcServerMethodInvokedInterceptor interceptor in interceptors)
                {
                    if (interceptor == null)
                    {
                        continue;
                    }

                    Stopwatch watch = Stopwatch.StartNew();

                    try
                    {
                        await interceptor.OnInvokedAsync(context).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        throw new GrpcServerMethodException(string.Format(Properties.MessageResources.ServerMethodInterceptorFailed + ex.Message, context.Method, interceptor.Name), ex, context, interceptor);
                    }
                    finally
                    {
                        if (performanceListener != null)
                        {
                            performanceListener.NotifyMethodIntercepted(context, interceptor, GrpcPerformanceListener.GetMilliseconds(watch));
                        }
                    }
                }
            }
        }
Пример #5
0
        /// <summary>
        /// 指定されたメソッドに対するマーシャラーを生成します。
        /// </summary>
        /// <typeparam name="T">オブジェクトの型</typeparam>
        /// <param name="serviceName">サービス名</param>
        /// <param name="methodName">メソッド名</param>
        /// <param name="performanceListener">パフォーマンスリスナー</param>
        /// <param name="settings">動作設定</param>
        /// <returns>マーシャラ</returns>
        private Marshaller <T> CreateMethodMarshaller <T>(string serviceName, string methodName, GrpcServerPerformanceListener performanceListener, GrpcServiceBuilderSettings settings)
        {
            Marshaller <T> marshaller = settings.GetMarshallerFactoryOrDefault().GetMarshaller <T>();

            if (performanceListener == null)
            {
                return(marshaller);
            }

            string typeName = typeof(T).Name;

            return(new Marshaller <T>(

                       delegate(T arg)
            {
                try
                {
                    Stopwatch watch = Stopwatch.StartNew();
                    byte[] data = marshaller.Serializer(arg);
                    performanceListener.NotifySerialized(serviceName, methodName, typeName, GrpcPerformanceListener.GetMilliseconds(watch), data == null ? 0 : data.Length);
                    return data;
                }
                catch (Exception ex)
                {
                    GrpcExceptionListener.NotifyCatchSerializerException(serviceName, methodName, typeof(T), ex);
                    throw new GrpcSerializerException(ex.Message, ex, serviceName, methodName, typeName);
                }
            }

                       , delegate(byte[] data)
            {
                try
                {
                    Stopwatch watch = Stopwatch.StartNew();
                    T arg = marshaller.Deserializer(data);
                    performanceListener.NotifyDeserialized(serviceName, methodName, typeName, GrpcPerformanceListener.GetMilliseconds(watch), data == null ? 0 : data.Length);
                    return arg;
                }
                catch (Exception ex)
                {
                    GrpcExceptionListener.NotifyCatchSerializerException(serviceName, methodName, typeof(T), ex);
                    throw new GrpcSerializerException(ex.Message, ex, serviceName, methodName, typeName);
                }
            }

                       ));
        }