Exemple #1
0
        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);
                    }
                }
            }));
        }
Exemple #4
0
        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);
        }