Esempio n. 1
0
        /// <summary>
        /// 指定された例外を処理し、実行結果を返します。
        /// </summary>
        /// <typeparam name="TRequest">リクエストの型</typeparam>
        /// <typeparam name="TResponse">レスポンスの型</typeparam>
        /// <typeparam name="TResult">実行結果の型</typeparam>
        /// <param name="call">呼び出しオブジェクト</param>
        /// <param name="ex">例外</param>
        /// <returns>実行結果</returns>
        private static GrpcResult <IList <TResult> > HandleResponseListException <TRequest, TResponse, TResult>(AsyncDuplexStreamingCall <TRequest, TResponse> call, Exception ex)
        {
            Exception actual = GrpcExceptionUtility.GetActualException(ex);

            GrpcCallState state;

            if (GrpcCallInvokerContext.TryGetState(call, out state))
            {
                GrpcExceptionListener.NotifyCatchClientException(state.Method, state.Host, state.Options, actual);
            }

            return(GrpcResult.Create <IList <TResult> >(actual));
        }
Esempio n. 2
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);
                }
            }

                       ));
        }
Esempio n. 3
0
        /// <summary>
        /// Unary メソッドを非同期で呼び出します。
        /// </summary>
        /// <typeparam name="TRequest">リクエストの型</typeparam>
        /// <typeparam name="TResponse">レスポンスの型</typeparam>
        /// <param name="method">メソッド</param>
        /// <param name="host">ホスト</param>
        /// <param name="options">オプション</param>
        /// <param name="request">リクエスト</param>
        /// <returns>呼び出しオブジェクト</returns>
        public override AsyncUnaryCall <TResponse> AsyncUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request)
        {
            double elapsed = 0;

            try
            {
                method = GetCustomMethod <TRequest, TResponse>(method);

                OnInvokingMethod(method, host, options, request);

                Stopwatch watch = null;
                AsyncUnaryCall <TResponse> call;

                try
                {
                    watch = Stopwatch.StartNew();
                    call  = m_Invoker.AsyncUnaryCall(method, host, options, request);
                }
                finally
                {
                    elapsed = GrpcPerformanceListener.GetMilliseconds(watch);
                }

                OnInvokedMethod(method, host, options, request, elapsed);

                // 待機されると dispose が呼ばれず、解放されずに残ってしまう
                // ストリーム操作もないため、監視しない
                // return GrcpCallInvokerContext.Regist<TRequest, TResponse>(call, method, host, options);
                return(call);
            }
            catch (Exception ex)
            {
                GrpcExceptionListener.NotifyCatchClientException(method, host, options, ex);

                Exception alternate;

                if (HandleException(method, host, options, ex, out alternate))
                {
                    throw alternate;
                }
                else
                {
                    throw;
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// 例外をキャッチしたときの処理を行います。
        /// </summary>
        /// <typeparam name="TRequest">リクエストの型</typeparam>
        /// <typeparam name="TResponse">レスポンスの型</typeparam>
        /// <param name="method">メソッド</param>
        /// <param name="host">ホスト</param>
        /// <param name="options">オプション</param>
        /// <param name="original">キャッチした例外</param>
        /// <param name="alternate">代わりにスローさせる例外</param>
        /// <returns>処理された場合、true を返します。</returns>
        private bool HandleException <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, Exception original, out Exception alternate)
        {
            Exception alt = null;

            foreach (IGrpcClientMethodExceptionHandler interceptor in m_Settings.InvokingInterceptors)
            {
                if (interceptor == null)
                {
                    continue;
                }

                Stopwatch watch = Stopwatch.StartNew();

                try
                {
                    bool wrapped = interceptor.ReplaceException(method, host, options, original, out alt);

                    if (m_Settings.PerformanceListener != null)
                    {
                        m_Settings.PerformanceListener.NotifyMethodIntercepted(method, host, options, interceptor, GrpcPerformanceListener.GetMilliseconds(watch));
                    }

                    if (wrapped)
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    GrpcExceptionListener.NotifyCatchClientException(method, host, options, ex);
                    throw new GrpcClientMethodException(string.Format(Properties.MessageResources.ClientMethodInterceptorFailed + ex.Message, method.FullName, interceptor.Name), ex, method, host, options, interceptor);
                }
            }

            if (alt != null && !object.Equals(alt, original))
            {
                alternate = alt;
                return(true);
            }
            else
            {
                alternate = null;
                return(false);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Unary メソッドを呼び出します。
        /// </summary>
        /// <typeparam name="TRequest">リクエストの型</typeparam>
        /// <typeparam name="TResponse">レスポンスの型</typeparam>
        /// <param name="method">メソッド</param>
        /// <param name="host">ホスト</param>
        /// <param name="options">オプション</param>
        /// <param name="request">リクエスト</param>
        /// <returns>レスポンス</returns>
        public override TResponse BlockingUnaryCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request)
        {
            double elapsed = 0;

            try
            {
                method = GetCustomMethod <TRequest, TResponse>(method);

                OnInvokingMethod(method, host, options, request);

                Stopwatch watch = null;

                TResponse result;

                try
                {
                    watch  = Stopwatch.StartNew();
                    result = m_Invoker.BlockingUnaryCall(method, host, options, request);
                }
                finally
                {
                    elapsed = GrpcPerformanceListener.GetMilliseconds(watch);
                }

                OnInvokedMethod(method, host, options, request, elapsed);

                return(result);
            }
            catch (Exception ex)
            {
                GrpcExceptionListener.NotifyCatchClientException(method, host, options, ex);

                Exception alternate;

                if (HandleException(method, host, options, ex, out alternate))
                {
                    throw alternate;
                }
                else
                {
                    throw;
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// ServerStreaming メソッドを非同期で呼び出します。
        /// </summary>
        /// <typeparam name="TRequest">リクエストの型</typeparam>
        /// <typeparam name="TResponse">レスポンスの型</typeparam>
        /// <param name="method">メソッド</param>
        /// <param name="host">ホスト</param>
        /// <param name="options">オプション</param>
        /// <param name="request">リクエスト</param>
        /// <returns>呼び出しオブジェクト</returns>
        public override AsyncServerStreamingCall <TResponse> AsyncServerStreamingCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options, TRequest request)
        {
            double elapsed = 0;

            try
            {
                method = GetCustomMethod <TRequest, TResponse>(method);

                OnInvokingMethod(method, host, options, request);

                Stopwatch watch = null;
                AsyncServerStreamingCall <TResponse> call;

                try
                {
                    watch = Stopwatch.StartNew();
                    call  = m_Invoker.AsyncServerStreamingCall(method, host, options, request);
                }
                finally
                {
                    elapsed = GrpcPerformanceListener.GetMilliseconds(watch);
                }

                OnInvokedMethod(method, host, options, request, elapsed);

                return(GrpcCallInvokerContext.Regist <TRequest, TResponse>(call, method, host, options, m_Settings.PerformanceListener));
            }
            catch (Exception ex)
            {
                GrpcExceptionListener.NotifyCatchClientException(method, host, options, ex);

                Exception alternate;

                if (HandleException(method, host, options, ex, out alternate))
                {
                    throw alternate;
                }
                else
                {
                    throw;
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// ClientStreaming メソッドを生成します。
        /// </summary>
        /// <typeparam name="TRequest">リクエストの型</typeparam>
        /// <typeparam name="TResponse">レスポンスの型</typeparam>
        /// <param name="builderContext">コンテキスト</param>
        /// <returns>メソッド</returns>
        private ClientStreamingServerMethod <TRequest, TResponse> CreateClientStreamingServerMethod <TRequest, TResponse>(MethodBuildContext builderContext)
            where TRequest : class where TResponse : class
        {
            ClientStreamingServerMethod <TRequest, TResponse> method = builderContext.MethodImpl.CreateDelegate(typeof(ClientStreamingServerMethod <TRequest, TResponse>), builderContext.ServiceInstance) as ClientStreamingServerMethod <TRequest, TResponse>;

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

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

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

                    TResponse result;

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

                    try
                    {
                        result = await method(
                            new RequestStreamReader <TRequest>(requestStream, 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);

                    return result;
                }
                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;
                    }
                }
            });
        }