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"); } } } } }); }
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); }