Example #1
0
        void RPCServerUpdate()
        {
            rpcTimer.Reset();
            rpcTimer.Start();
            rpcPollTimeout.Reset();
            rpcPollTimer.Reset();
            rpcExecTimer.Reset();
            var   config = Configuration.Instance;
            long  maxTimePerUpdateTicks = StopwatchExtensions.MicrosecondsToTicks(config.MaxTimePerUpdate);
            long  recvTimeoutTicks      = StopwatchExtensions.MicrosecondsToTicks(config.RecvTimeout);
            ulong rpcsExecuted          = 0;

            rpcYieldedContinuations.Clear();
            for (int i = 0; i < Servers.Count; i++)
            {
                Servers [i].RPCServer.Update();
            }

            while (true)
            {
                // Poll for RPCs
                rpcPollTimer.Start();
                rpcPollTimeout.Reset();
                rpcPollTimeout.Start();
                while (true)
                {
                    PollRequests(rpcYieldedContinuations);
                    if (!config.BlockingRecv)
                    {
                        break;
                    }
                    if (rpcPollTimeout.ElapsedTicks > recvTimeoutTicks)
                    {
                        break;
                    }
                    if (rpcTimer.ElapsedTicks > maxTimePerUpdateTicks)
                    {
                        break;
                    }
                    if (rpcContinuations.Count > 0)
                    {
                        break;
                    }
                }
                rpcPollTimer.Stop();

                if (rpcContinuations.Count == 0)
                {
                    break;
                }

                // Execute RPCs
                rpcExecTimer.Start();
                for (int i = 0; i < rpcContinuations.Count; i++)
                {
                    var continuation = rpcContinuations [i];

                    // Ignore the continuation if the client has disconnected
                    if (!continuation.Client.Connected)
                    {
                        continue;
                    }

                    // Max exec time exceeded, delay to next update
                    if (rpcTimer.ElapsedTicks > maxTimePerUpdateTicks)
                    {
                        rpcYieldedContinuations.Add(continuation);
                        continue;
                    }

                    // Execute the continuation
                    try {
                        ExecuteContinuation(continuation);
                    } catch (YieldException e) {
                        rpcYieldedContinuations.Add((RequestContinuation)e.Continuation);
                    }
                    rpcsExecuted++;
                }
                rpcContinuations.Clear();
                rpcExecTimer.Stop();

                // Exit if only execute one RPC per update
                if (config.OneRPCPerUpdate)
                {
                    break;
                }

                // Exit if max exec time exceeded
                if (rpcTimer.ElapsedTicks > maxTimePerUpdateTicks)
                {
                    break;
                }
            }

            // Run yielded continuations on the next update
            var tmp = rpcContinuations;

            rpcContinuations        = rpcYieldedContinuations;
            rpcYieldedContinuations = tmp;

            rpcTimer.Stop();

            RPCsExecuted        += rpcsExecuted;
            TimePerRPCUpdate     = (float)rpcTimer.ElapsedSeconds();
            PollTimePerRPCUpdate = (float)rpcPollTimer.ElapsedSeconds();
            ExecTimePerRPCUpdate = (float)rpcExecTimer.ElapsedSeconds();
        }
Example #2
0
        /// <summary>
        /// Update the RPC server, called once every FixedUpdate.
        /// This method receives and executes RPCs, for up to MaxTimePerUpdate microseconds.
        /// RPCs are delayed to the next update if this time expires. If AdaptiveRateControl
        /// is true, MaxTimePerUpdate will be automatically adjusted to achieve a target framerate.
        /// If NonBlockingUpdate is false, this call will block waiting for new RPCs for up to
        /// MaxPollTimePerUpdate microseconds. If NonBlockingUpdate is true, a single non-blocking call
        /// will be made to check for new RPCs.
        /// </summary>
        void RPCServerUpdate()
        {
            var   timer                 = Stopwatch.StartNew();
            var   pollTimeout           = new Stopwatch();
            var   pollTimer             = new Stopwatch();
            var   execTimer             = new Stopwatch();
            long  maxTimePerUpdateTicks = StopwatchExtensions.MicrosecondsToTicks(MaxTimePerUpdate);
            long  recvTimeoutTicks      = StopwatchExtensions.MicrosecondsToTicks(RecvTimeout);
            ulong rpcsExecuted          = 0;

            var yieldedContinuations = new List <RequestContinuation> ();

            rpcServer.Update();

            while (true)
            {
                // Poll for RPCs
                pollTimer.Start();
                pollTimeout.Reset();
                pollTimeout.Start();
                while (true)
                {
                    PollRequests(yieldedContinuations);
                    if (!BlockingRecv)
                    {
                        break;
                    }
                    if (pollTimeout.ElapsedTicks > recvTimeoutTicks)
                    {
                        break;
                    }
                    if (timer.ElapsedTicks > maxTimePerUpdateTicks)
                    {
                        break;
                    }
                    if (continuations.Any())
                    {
                        break;
                    }
                }
                pollTimer.Stop();

                if (!continuations.Any())
                {
                    break;
                }

                // Execute RPCs
                execTimer.Start();
                foreach (var continuation in continuations)
                {
                    // Ignore the continuation if the client has disconnected
                    if (!continuation.Client.Connected)
                    {
                        continue;
                    }

                    // Max exec time exceeded, delay to next update
                    if (timer.ElapsedTicks > maxTimePerUpdateTicks)
                    {
                        yieldedContinuations.Add(continuation);
                        continue;
                    }

                    // Execute the continuation
                    try {
                        ExecuteContinuation(continuation);
                    } catch (YieldException e) {
                        yieldedContinuations.Add((RequestContinuation)e.Continuation);
                    }
                    rpcsExecuted++;
                }
                continuations.Clear();
                execTimer.Stop();

                // Exit if only execute one RPC per update
                if (OneRPCPerUpdate)
                {
                    break;
                }

                // Exit if max exec time exceeded
                if (timer.ElapsedTicks > maxTimePerUpdateTicks)
                {
                    break;
                }
            }

            // Run yielded continuations on the next update
            continuations = yieldedContinuations;

            timer.Stop();

            RPCsExecuted        += rpcsExecuted;
            TimePerRPCUpdate     = (float)timer.ElapsedSeconds();
            PollTimePerRPCUpdate = (float)pollTimer.ElapsedSeconds();
            ExecTimePerRPCUpdate = (float)execTimer.ElapsedSeconds();
        }