Example #1
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 ();
        }