Example #1
0
        static void DispatchRpc(RpcClient rpcClient, IntPtr rpc, Protos.Request req)
        {
            Task.Run(async() => {
                var start = Stopwatch.StartNew();
                var res   = new Protos.Response();
                try
                {
                    res = await HandleRpc(rpcClient, req, req.Type);
                }
                catch (Exception e)
                {
                    res = GetErrorResponse("PIT-500", e.Message);

                    var innerMostException = e;
                    while (innerMostException.InnerException != null)
                    {
                        innerMostException = innerMostException.InnerException;
                    }

                    Logger.Error("Exception thrown in handler: {0}", innerMostException.Message);
#if NPITAYA_DEBUG
                    Logger.Error("StackTrace: {0}", e.StackTrace);
#endif
                }
                finally
                {
                    start.Stop();
                    _metricsReporter?.ObserveHistogram(RPC_LATENCY_METRIC, (float)start.Elapsed.TotalSeconds, null);
                    unsafe
                    {
                        byte[] responseData = res.ToByteArray();
                        Int32 responseLen   = responseData.Length;

                        fixed(byte *p = responseData)
                        {
                            IntPtr err = pitaya_rpc_respond(rpc, (IntPtr)p, responseLen);
                            if (err != IntPtr.Zero)
                            {
                                pitaya_error_drop(err);
                                Logger.Error("Failed to respond to rpc");
                            }
                        }
                    }
                }
            });
        }
        static void DispatchRpc(RpcClient rpcClient, IntPtr rpc, Protos.Request req)
        {
            Task.Run(async() => {
                var res = new Protos.Response();
                try
                {
                    res = await HandleRpc(rpcClient, req, req.Type);
                }
                catch (Exception e)
                {
                    res = GetErrorResponse("PIT-500", e.Message);

                    var innerMostException = e;
                    while (innerMostException.InnerException != null)
                    {
                        innerMostException = innerMostException.InnerException;
                    }

                    Logger.Error("Exception thrown in handler: {0}", innerMostException.Message);
#if NPITAYA_DEBUG
                    Logger.Error("StackTrace: {0}", e.StackTrace);
#endif
                }
                finally
                {
                    unsafe
                    {
                        byte[] responseData = res.ToByteArray();
                        Int32 responseLen   = responseData.Length;

                        fixed(byte *p = responseData)
                        {
                            IntPtr err = pitaya_rpc_respond(rpc, (IntPtr)p, responseLen);
                            if (err != IntPtr.Zero)
                            {
                                pitaya_error_drop(err);
                                Logger.Error("Failed to respond to rpc");
                            }
                        }
                    }
                }
            });
        }
Example #3
0
        static void HandleRpcCallback(IntPtr userData, IntPtr rpc)
        {
            Int32  len;
            IntPtr rawData = pitaya_rpc_request(rpc, out len);

            byte[] data = GetDataFromRawPointer(rawData, len);

            try
            {
                var req = new Protos.Request();
                req.MergeFrom(new CodedInputStream(data));

                DispatchRpc(_rpcClient, rpc, req);
            }
            catch (Exception e)
            {
                Logger.Error("Failed to decode request, error:{0}", e.Message);
            }
        }
        internal static async Task <Response> HandleRpc(Protos.Request req, RPCType type, Stopwatch sw)
        {
            byte[] data  = req.Msg.Data.ToByteArray();
            Route  route = Route.FromString(req.Msg.Route);

            string handlerName = $"{route.service}.{route.method}";

            PitayaSession s        = null;
            var           response = new Response();

            RemoteMethod handler;

            if (type == RPCType.Sys)
            {
                s = new Models.PitayaSession(req.Session, req.FrontendID);
                if (!HandlersDict.ContainsKey(handlerName))
                {
                    response = GetErrorResponse("PIT-404",
                                                $"remote/handler not found! remote/handler name: {handlerName}");
                    return(response);
                }

                handler = HandlersDict[handlerName];
                MetricsReporters.ReportMessageProccessDelay(req.Msg.Route, "local", sw);
            }
            else
            {
                if (!RemotesDict.ContainsKey(handlerName))
                {
                    response = GetErrorResponse("PIT-404",
                                                $"remote/handler not found! remote/handler name: {handlerName}");
                    return(response);
                }

                handler = RemotesDict[handlerName];
                MetricsReporters.ReportMessageProccessDelay(req.Msg.Route, "remote", sw);
            }

            Task ans;

            if (handler.ArgType != null)
            {
                var arg = _serializer.Unmarshal(data, handler.ArgType);
                if (type == RPCType.Sys)
                {
                    ans = handler.Method.Invoke(handler.Obj, new[] { s, arg }) as Task;
                }
                else
                {
                    ans = handler.Method.Invoke(handler.Obj, new[] { arg }) as Task;
                }
            }
            else
            {
                if (type == RPCType.Sys)
                {
                    ans = handler.Method.Invoke(handler.Obj, new object[] { s }) as Task;
                }
                else
                {
                    ans = handler.Method.Invoke(handler.Obj, new object[] { }) as Task;
                }
            }

            await ans;

            byte[] ansBytes;

            if (handler.ReturnType != typeof(void))
            {
                ansBytes = SerializerUtils.SerializeOrRaw(ans.GetType().
                                                          GetProperty("Result")
                                                          ?.GetValue(ans), _serializer);
            }
            else
            {
                ansBytes = new byte[] {};
            }
            response.Data = ByteString.CopyFrom(ansBytes);
            return(response);
        }