Exemplo n.º 1
0
                /// <exception cref="System.Exception"/>
                public virtual IWritable Call(RPC.Server server, string protocol, IWritable writableRequest
                                              , long receiveTime)
                {
                    ProtobufRpcEngine.RpcRequestWrapper request = (ProtobufRpcEngine.RpcRequestWrapper
                                                                   )writableRequest;
                    ProtobufRpcEngineProtos.RequestHeaderProto rpcRequest = request.requestHeader;
                    string methodName    = rpcRequest.GetMethodName();
                    string protoName     = rpcRequest.GetDeclaringClassProtocolName();
                    long   clientVersion = rpcRequest.GetClientProtocolVersion();

                    if (server.verbose)
                    {
                        Log.Info("Call: protocol=" + protocol + ", method=" + methodName);
                    }
                    RPC.Server.ProtoClassProtoImpl protocolImpl = GetProtocolImpl(server, protoName,
                                                                                  clientVersion);
                    BlockingService service = (BlockingService)protocolImpl.protocolImpl;

                    Descriptors.MethodDescriptor methodDescriptor = service.GetDescriptorForType().FindMethodByName
                                                                        (methodName);
                    if (methodDescriptor == null)
                    {
                        string msg = "Unknown method " + methodName + " called on " + protocol + " protocol.";
                        Log.Warn(msg);
                        throw new RpcNoSuchMethodException(msg);
                    }
                    Message prototype = service.GetRequestPrototype(methodDescriptor);
                    Message param     = prototype.NewBuilderForType().MergeFrom(request.theRequestRead).Build
                                            ();
                    Message   result;
                    long      startTime = Time.Now();
                    int       qTime     = (int)(startTime - receiveTime);
                    Exception exception = null;

                    try
                    {
                        server.rpcDetailedMetrics.Init(protocolImpl.protocolClass);
                        result = service.CallBlockingMethod(methodDescriptor, null, param);
                    }
                    catch (ServiceException e)
                    {
                        exception = (Exception)e.InnerException;
                        throw (Exception)e.InnerException;
                    }
                    catch (Exception e)
                    {
                        exception = e;
                        throw;
                    }
                    finally
                    {
                        int processingTime = (int)(Time.Now() - startTime);
                        if (Log.IsDebugEnabled())
                        {
                            string msg = "Served: " + methodName + " queueTime= " + qTime + " procesingTime= "
                                         + processingTime;
                            if (exception != null)
                            {
                                msg += " exception= " + exception.GetType().Name;
                            }
                            Log.Debug(msg);
                        }
                        string detailedMetricsName = (exception == null) ? methodName : exception.GetType
                                                         ().Name;
                        server.rpcMetrics.AddRpcQueueTime(qTime);
                        server.rpcMetrics.AddRpcProcessingTime(processingTime);
                        server.rpcDetailedMetrics.AddProcessingTime(detailedMetricsName, processingTime);
                    }
                    return(new ProtobufRpcEngine.RpcResponseWrapper(result));
                }
Exemplo n.º 2
0
            /// <summary>This is the client side invoker of RPC method.</summary>
            /// <remarks>
            /// This is the client side invoker of RPC method. It only throws
            /// ServiceException, since the invocation proxy expects only
            /// ServiceException to be thrown by the method in case protobuf service.
            /// ServiceException has the following causes:
            /// <ol>
            /// <li>Exceptions encountered on the client side in this method are
            /// set as cause in ServiceException as is.</li>
            /// <li>Exceptions from the server are wrapped in RemoteException and are
            /// set as cause in ServiceException</li>
            /// </ol>
            /// Note that the client calling protobuf RPC methods, must handle
            /// ServiceException by getting the cause from the ServiceException. If the
            /// cause is RemoteException, then unwrap it to get the exception thrown by
            /// the server.
            /// </remarks>
            /// <exception cref="Com.Google.Protobuf.ServiceException"/>
            public virtual object Invoke(object proxy, MethodInfo method, object[] args)
            {
                long startTime = 0;

                if (Log.IsDebugEnabled())
                {
                    startTime = Time.Now();
                }
                if (args.Length != 2)
                {
                    // RpcController + Message
                    throw new ServiceException("Too many parameters for request. Method: [" + method.
                                               Name + "]" + ", Expected: 2, Actual: " + args.Length);
                }
                if (args[1] == null)
                {
                    throw new ServiceException("null param while calling Method: [" + method.Name + "]"
                                               );
                }
                TraceScope traceScope = null;

                // if Tracing is on then start a new span for this rpc.
                // guard it in the if statement to make sure there isn't
                // any extra string manipulation.
                if (Trace.IsTracing())
                {
                    traceScope = Trace.StartSpan(RpcClientUtil.MethodToTraceString(method));
                }
                ProtobufRpcEngineProtos.RequestHeaderProto rpcRequestHeader = ConstructRpcRequestHeader
                                                                                  (method);
                if (Log.IsTraceEnabled())
                {
                    Log.Trace(Thread.CurrentThread().GetId() + ": Call -> " + remoteId + ": "
                              + method.Name + " {" + TextFormat.ShortDebugString((Message)args[1]) + "}");
                }
                Message theRequest = (Message)args[1];

                ProtobufRpcEngine.RpcResponseWrapper val;
                try
                {
                    val = (ProtobufRpcEngine.RpcResponseWrapper)client.Call(RPC.RpcKind.RpcProtocolBuffer
                                                                            , new ProtobufRpcEngine.RpcRequestWrapper(rpcRequestHeader, theRequest), remoteId
                                                                            , fallbackToSimpleAuth);
                }
                catch (Exception e)
                {
                    if (Log.IsTraceEnabled())
                    {
                        Log.Trace(Thread.CurrentThread().GetId() + ": Exception <- " + remoteId +
                                  ": " + method.Name + " {" + e + "}");
                    }
                    if (Trace.IsTracing())
                    {
                        traceScope.GetSpan().AddTimelineAnnotation("Call got exception: " + e.Message);
                    }
                    throw new ServiceException(e);
                }
                finally
                {
                    if (traceScope != null)
                    {
                        traceScope.Close();
                    }
                }
                if (Log.IsDebugEnabled())
                {
                    long callTime = Time.Now() - startTime;
                    Log.Debug("Call: " + method.Name + " took " + callTime + "ms");
                }
                Message prototype = null;

                try
                {
                    prototype = GetReturnProtoType(method);
                }
                catch (Exception e)
                {
                    throw new ServiceException(e);
                }
                Message returnMessage;

                try
                {
                    returnMessage = prototype.NewBuilderForType().MergeFrom(val.theResponseRead).Build
                                        ();
                    if (Log.IsTraceEnabled())
                    {
                        Log.Trace(Thread.CurrentThread().GetId() + ": Response <- " + remoteId +
                                  ": " + method.Name + " {" + TextFormat.ShortDebugString(returnMessage) + "}");
                    }
                }
                catch (Exception e)
                {
                    throw new ServiceException(e);
                }
                return(returnMessage);
            }