public void Can_Report_Pitaya_Metrics() { var cm = new CustomMetricsSpec(); cm.Counters.Add(new CustomCounter() { Subsystem = "subsystem", Name = "nameC", Help = "help" }); cm.Gauges.Add(new CustomGauge() { Subsystem = "subsystem", Name = "nameG", Help = "help" }); cm.Summaries.Add(new CustomSummary() { Subsystem = "subsystem", Name = "nameS", Help = "help", Objectives = null }); var prometheusMR = new PrometheusMetricsReporter("default", "game", 9090, null, null, cm); MetricsReporters.AddMetricReporter(prometheusMR); for (var i = 0; i < 5; ++i) { new Thread(() => { Thread.CurrentThread.IsBackground = true; MetricsReporters.ReportTimer("success", "game.remoteGame.test", "rpc", "", Stopwatch.StartNew()); MetricsReporters.ReportMessageProccessDelay("game.remoteGame.test", "rpc", Stopwatch.StartNew()); MetricsReporters.ReportNumberOfConnectedClients(1); MetricsReporters.ReportSummary("nameS", new Dictionary <string, string>(), 1); MetricsReporters.ReportGauge("nameG", new Dictionary <string, string>(), 1); MetricsReporters.ReportCount("nameC", new Dictionary <string, string>(), 1); }).Start(); } }
private static async Task HandleIncomingRpc(IntPtr cRpcPtr) { var sw = Stopwatch.StartNew(); var res = new MemoryBuffer(); bool success = false; string route = ""; IntPtr resPtr; try { var cRpc = (CRpc)Marshal.PtrToStructure(cRpcPtr, typeof(CRpc)); var req = BuildRequestData(cRpc.reqBufferPtr); route = req.Msg.Route; res = await RPCCbFuncImpl(req, sw); success = true; } catch (Exception e) { var innerMostException = e; while (innerMostException.InnerException != null) { innerMostException = innerMostException.InnerException; } Logger.Error("Exception thrown in handler, error:{0}", innerMostException.Message); // TODO externalize method and only print stacktrace when debug #if NPITAYA_DEBUG // If we are compiling with a Debug define, we want to print a stacktrace whenever a route // throws an exception. Logger.Error("Stacktrace: {0}", innerMostException.StackTrace); #endif var protosResponse = GetErrorResponse("PIT-500", innerMostException.Message); var responseBytes = protosResponse.ToByteArray(); res.data = ByteArrayToIntPtr(responseBytes); res.size = responseBytes.Length; } finally { resPtr = Marshal.AllocHGlobal(Marshal.SizeOf(res)); Marshal.StructureToPtr(res, resPtr, false); tfg_pitc_FinishRpcCall(resPtr, cRpcPtr); Marshal.FreeHGlobal(res.data); Marshal.FreeHGlobal(resPtr); if (success) { MetricsReporters.ReportTimer(Metrics.Constants.Status.success.ToString(), route, "handler", "", sw); } else { MetricsReporters.ReportTimer(Metrics.Constants.Status.fail.ToString(), route, "handler", "PIT-500", sw); } } }
public static unsafe Task <T> Rpc <T>(string serverId, Route route, object msg) { return(_rpcTaskFactory.StartNew(() => { MemoryBuffer *memBufPtr = null; var retError = new Error(); var ok = false; Stopwatch sw = null; try { var data = SerializerUtils.SerializeOrRaw(msg, _serializer); sw = Stopwatch.StartNew(); fixed(byte *p = data) { ok = RPCInternal(serverId, route.ToString(), (IntPtr)p, data.Length, &memBufPtr, ref retError); } sw.Stop(); if (!ok) // error { if (retError.code == "PIT-504") { throw new PitayaTimeoutException($"Timeout on RPC call: ({retError.code}: {retError.msg})"); } if (retError.code == "PIT-404") { throw new PitayaRouteNotFoundException($"Route not found on RPC call: ({retError.code}: {retError.msg})"); } throw new PitayaException($"RPC call failed: ({retError.code}: {retError.msg})"); } var protoRet = GetProtoMessageFromMemoryBuffer <T>(*memBufPtr); return protoRet; } finally { if (sw != null) { if (ok) { MetricsReporters.ReportTimer(Metrics.Constants.Status.success.ToString(), route.ToString(), "rpc", "", sw); } else { MetricsReporters.ReportTimer(Metrics.Constants.Status.fail.ToString(), route.ToString(), "rpc", $"{retError.code}", sw); } } if (memBufPtr != null) { FreeMemoryBufferInternal(memBufPtr); } } })); }
public void Can_Report_Pitaya_Metrics() { var statsdMR = new StatsdMetricsReporter("localhost", 5000, "game"); MetricsReporters.AddMetricReporter(statsdMR); for (var i = 0; i < 5; ++i) { new Thread(() => { Thread.CurrentThread.IsBackground = true; MetricsReporters.ReportTimer("success", "game.remoteGame.test", "rpc", "", Stopwatch.StartNew()); MetricsReporters.ReportMessageProccessDelay("game.remoteGame.test", "rpc", Stopwatch.StartNew()); MetricsReporters.ReportNumberOfConnectedClients(1); MetricsReporters.ReportSummary("nameS", new Dictionary <string, string>(), 1); MetricsReporters.ReportGauge("nameG", new Dictionary <string, string>(), 1); MetricsReporters.ReportCount("nameC", new Dictionary <string, string>(), 1); }).Start(); } }
static void Main(string[] args) { Logger.SetLevel(LogLevel.DEBUG); Console.WriteLine("c# prog running"); string serverId = System.Guid.NewGuid().ToString(); var sdConfig = new SDConfig( endpoints: "http://127.0.0.1:2379", etcdPrefix: "pitaya/", serverTypeFilters: new List <string>(), heartbeatTTLSec: 60, logHeartbeat: true, logServerSync: true, logServerDetails: true, syncServersIntervalSec: 30, maxNumberOfRetries: 0, retryDelayMilliseconds: 0); var sv = new Server( id: serverId, type: "csharp", metadata: "", hostname: "localhost", frontend: false); var natsConfig = new NatsConfig( endpoint: "127.0.0.1:4222", connectionTimeoutMs: 2000, requestTimeoutMs: 1000, serverShutdownDeadlineMs: 3, serverMaxNumberOfRpcs: 100, maxConnectionRetries: 3, maxPendingMessages: 1000, reconnectBufSize: 4 * 1024 * 1024); var grpcConfig = new GrpcConfig( host: "127.0.0.1", port: 5444, serverShutdownDeadlineMs: 2000, serverMaxNumberOfRpcs: 200, clientRpcTimeoutMs: 10000 ); Dictionary <string, string> constantTags = new Dictionary <string, string> { { "game", "game" }, { "serverType", "svType" } }; var statsdMR = new StatsdMetricsReporter("localhost", 5000, "game", constantTags); MetricsReporters.AddMetricReporter(statsdMR); var prometheusMR = new PrometheusMetricsReporter("default", "game", 9090); MetricsReporters.AddMetricReporter(prometheusMR); PitayaCluster.AddSignalHandler(() => { Logger.Info("Calling terminate on cluster"); PitayaCluster.Terminate(); Logger.Info("Cluster terminated, exiting app"); Environment.Exit(1); //Environment.FailFast("oops"); }); try { PitayaCluster.Initialize( grpcConfig, sdConfig, sv, NativeLogLevel.Debug, new PitayaCluster.ServiceDiscoveryListener((action, server) => { switch (action) { case PitayaCluster.ServiceDiscoveryAction.ServerAdded: Console.WriteLine("Server was added"); Console.WriteLine(" id: " + server.id); Console.WriteLine(" type: " + server.type); break; case PitayaCluster.ServiceDiscoveryAction.ServerRemoved: Console.WriteLine("Server was removed"); Console.WriteLine(" id: " + server.id); Console.WriteLine(" type: " + server.type); break; default: throw new ArgumentOutOfRangeException(nameof(action), action, null); } })); //PitayaCluster.Initialize(natsConfig, sdConfig, sv, NativeLogLevel.Debug, ""); } catch (PitayaException exc) { Logger.Error("Failed to create cluster: {0}", exc.Message); Environment.Exit(1); } Logger.Info("pitaya lib initialized successfully :)"); var tr = new TestRemote(); PitayaCluster.RegisterRemote(tr); var th = new TestHandler(); PitayaCluster.RegisterHandler(th); Thread.Sleep(1000); TrySendRpc(); Console.ReadKey(); PitayaCluster.Terminate(); }
public static void Terminate() { RemoveServiceDiscoveryListener(_serviceDiscoveryListener); TerminateInternal(); MetricsReporters.Terminate(); }
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); }