Example #1
0
        public Task Handle(PlaceOrder message, IMessageHandlerContext context)
        {
            _processingCount++;

            _log.Info($"RECV {nameof(PlaceOrder)} [{_processingCount}], {nameof(message.Id)}: {message.Id}");

            var orderPlaced = new OrderPlaced {
                OrderId = message.Id, IsGrouped = message.IsGrouped
            };
            var task = context.Publish(orderPlaced);

            _log.Info($"POST {nameof(OrderPlaced)} [{_processingCount}], {nameof(orderPlaced.OrderId)}: {orderPlaced.OrderId}");

            if (message.IsGrouped != _groupItems)
            {
                // Grouping completed.
                if (_groupItems)
                {
                    _groupItems = false;
                    _log.Info(_sw.LogTimeToMessage("GROUP COMPLETE "));
                }
                // Grouping started;
                else
                {
                    _groupItems = true;
                    _sw         = StopwatchExtensions.CreateStartSW();
                }
            }

            return(task);
        }
        public async Task Consume(ConsumeContext <IPlaceOrderCommand> context)
        {
            _processingCount++;

            // TODO: Need to determine MassTransit logging services and not use console.
            await Console.Out.WriteLineAsync($"RECV {nameof(IPlaceOrderCommand)} [{_processingCount}], {nameof(context.Message.Id)}: {context.Message.Id}");

            //notify subscribers that a order is registered
            await context.Publish <IOrderPlacedEvent>(new { OrderId = context.Message.Id, context.Message.IsGrouped });

            await Console.Out.WriteLineAsync($"POST {nameof(IOrderPlacedEvent)} [{_processingCount}], {nameof(IOrderPlacedEvent.OrderId)}: {context.Message.Id}");

            if (context.Message.IsGrouped != _groupItems)
            {
                // Grouping completed.
                if (_groupItems)
                {
                    _groupItems = false;
                    _sw.LogTimeToConsole("GROUP COMPLETE ");
                }
                // Grouping started;
                else
                {
                    _groupItems = true;
                    _sw         = StopwatchExtensions.CreateStartSW();
                }
            }
        }
        private void DoAnalogKeyDown(object sender, DoWorkEventArgs args)
        {
            var watch      = new Stopwatch();
            var parameters = args.Argument;
            var worker     = sender as BackgroundWorker;
            var key        = (VirtualKeyCode)((Object[])parameters)[0];
            var amount     = (double)((Object[])parameters)[1];
            var onTime     = TimeSpan.FromTicks(StopwatchExtensions.NanoSecondsToTicks((long)(this.PwmIntervalNanoseconds * amount)));
            var offTime    = TimeSpan.FromTicks(StopwatchExtensions.NanoSecondsToTicks((long)(this.PwmIntervalNanoseconds))).Subtract(onTime);

            args.Result = key;

            while (!worker.CancellationPending)
            {
                GameWindow.WaitForFocus();
                this.KeyDown(key);

                Thread.Sleep(onTime);

                this.KeyUp(key);

                Thread.Sleep(offTime);
            }
            args.Cancel = true;
        }
Example #4
0
        public static StopwatchExtensions.TimedThreadedExecutionSummary ExecuteThreaded
            (Action action,
            int iterations                = 1,
            TimeSpan?maxAverage           = null,
            TimeSpan?maxTotal             = null,
            bool timeIndividualExecutions = false,
            string description            = "",
            string timeFormat             = DefaultTimeFormat,
            int maxTries = 3)
        {
            maxAverage = maxAverage != default(TimeSpan) ? maxAverage : TimeSpan.MaxValue;
            maxTotal   = maxTotal != default(TimeSpan) ? maxTotal : TimeSpan.MaxValue;

            StopwatchExtensions.TimedThreadedExecutionSummary executionSummary = null;

            Func <TimeSpan?, string> format = date => date?.ToString(timeFormat) ?? "";

            Action printResults = () =>
            {
                PrintSummary(iterations, maxAverage, maxTotal, description, format, executionSummary);

                Console.WriteLine(
                    $@"  
    Individual execution times    
    Average: {format(executionSummary.IndividualExecutionTimes.Average())}
    Min:     {format(executionSummary.IndividualExecutionTimes.Min())}
    Max:     {format(executionSummary.IndividualExecutionTimes.Max())}
    Sum:     {format(executionSummary.IndividualExecutionTimes.Sum())}");
            };

            for (int tries = 1; tries <= maxTries; tries++)
            {
                executionSummary = StopwatchExtensions.TimeExecutionThreaded(action: action, iterations: iterations, timeIndividualExecutions: timeIndividualExecutions);
                try
                {
                    RunAsserts(maxAverage, maxTotal, executionSummary, format);
                }
                catch (Exception e)
                {
                    Debug.WriteLine($"Try: {tries} {e.GetType().FullName}: {e.Message}");
                    if (tries >= maxTries)
                    {
                        printResults();
                        throw;
                    }
                    continue;
                }
                printResults();
                break;
            }


            printResults();
            RunAsserts(maxAverage, maxTotal, executionSummary, format);

            return(executionSummary);
        }
        public void RunTest()
        {
            var ts = StopwatchExtensions.Run(s =>
            {
                Thread.Sleep(100);
                return(s.ElapsedMilliseconds);
            });

            Assert.True(ts >= 100);
        }
Example #6
0
        public Int32 CalculateFps()
        {
            long totalTime = 0;

            for (int i = 0; i < history.Length; i++)
            {
                totalTime += history[i];
            }
            return((Int32)(history.Length * 1000d / (Double)StopwatchExtensions.StopwatchTicksAsDoubleMilliseconds(totalTime)));
        }
Example #7
0
        /// <summary>
        /// Handles GPIO changes (rising and falling PPM signal), recording them to the decoder queue.
        /// </summary>
        /// <param name="sender">Event source, the <see cref="GpioPin"/> which changed.</param>
        /// <param name="arguments">Information about the GPIO pin value change.</param>
        /// <remarks>
        /// Main hardware routine which triggers the input translation process.
        /// This code must run as quickly as possible else we could miss the next event!
        /// </remarks>
        private void OnInputPinValueChanged(GpioPin sender, GpioPinValueChangedEventArgs arguments)
        {
            // Get PPM value
            var time  = StopwatchExtensions.GetTimestampInMicroseconds();
            var level = arguments.Edge == GpioPinEdge.RisingEdge;
            var value = new PpmPulse(time, level);

            // Queue for processing
            _pulseBuffer.Enqueue(value);
            _pulseTrigger.Set();
        }
Example #8
0
        private async Task SubmitSnippetPostFeedback(string snippetId, string connectionId, long startTimestamp)
        {
            SnippetResult result;

            try {
                result = await hostConnector.RunSnippetAsync(snippetId);
            }
            catch (Exception ex) {
                result = new SnippetResult()
                {
                    status = SnippetStatus.InitializationError, exception = ex.Message
                };
            }

            var hubContext = GlobalHost.ConnectionManager.GetHubContext <ResultHub>();

            result.totalTime = StopwatchExtensions.GetTimestampMillis() - startTimestamp;
            hubContext.Clients.Client(connectionId).SendResult(connectionId, snippetId, result, result.status.ToHealth().ToColor());
        }
Example #9
0
        public void Concurrent_read_only_access_to_aggregate_history_can_occur_in_paralell()
        {
            var user = new User();

            user.Register("*****@*****.**", "password", Guid.NewGuid());
            using (var session = OpenSession(CreateStore()))
            {
                session.Save(user);
            }

            var iterations = 20;
            var delayEachTransactionByMilliseconds = 100;

            Action readUserHistory = () =>
            {
                using (var session = OpenSession(CreateStore()))
                {
                    using (var transaction = new TransactionScope())
                    {
                        ((IEventStoreReader)session).GetHistory(user.Id);
                        Thread.Sleep(TimeSpanExtensions.Milliseconds(delayEachTransactionByMilliseconds));
                        transaction.Complete();
                    }
                }
            };

            readUserHistory();//one warmup to get consistent times later.
            var timeForSingleTransactionalRead = (int)StopwatchExtensions.TimeExecution(readUserHistory).TotalMilliseconds;

            var timingsSummary = TimeAsserter.ExecuteThreaded(
                readUserHistory,
                iterations: iterations,
                timeIndividualExecutions: true,
                maxTotal: ((iterations * timeForSingleTransactionalRead) / 2).Milliseconds(),
                description: $"If access is serialized the time will be approximately {iterations * timeForSingleTransactionalRead} milliseconds. If parelellized it should be far below this value.");

            timingsSummary.Average.Should().BeLessThan(delayEachTransactionByMilliseconds.Milliseconds());

            timingsSummary.IndividualExecutionTimes.Sum().Should().BeGreaterThan(timingsSummary.Total);
        }
Example #10
0
        public async Task Consume(ConsumeContext <IOrderPlacedEvent> context)
        {
            _processingCount++;
            // TODO: Need to determine MassTransit logging services and not use console.
            await Console.Out.WriteLineAsync($"RECV {nameof(IOrderPlacedEvent)} [{_processingCount}], {nameof(context.Message.OrderId)}: {context.Message.OrderId}");

            if (context.Message.IsGrouped != _groupItems)
            {
                // Grouping completed.
                if (_groupItems)
                {
                    _groupItems = false;
                    _sw.LogTimeToConsole("GROUP COMPLETE ");
                }
                // Grouping started;
                else
                {
                    _groupItems = true;
                    _sw         = StopwatchExtensions.CreateStartSW();
                }
            }
        }
Example #11
0
        public static StopwatchExtensions.TimedExecutionSummary Execute
            (Action action,
            int iterations      = 1,
            TimeSpan?maxAverage = null,
            TimeSpan?maxTotal   = null,
            string description  = "",
            string timeFormat   = DefaultTimeFormat,
            int maxTries        = 3)
        {
            maxAverage = maxAverage != default(TimeSpan) ? maxAverage : TimeSpan.MaxValue;
            maxTotal   = maxTotal != default(TimeSpan) ? maxTotal : TimeSpan.MaxValue;

            Func <TimeSpan?, string> format = date => date?.ToString(timeFormat) ?? "";

            StopwatchExtensions.TimedExecutionSummary executionSummary = null;
            for (int tries = 1; tries <= maxTries; tries++)
            {
                executionSummary = StopwatchExtensions.TimeExecution(action: action, iterations: iterations);
                try
                {
                    RunAsserts(maxAverage, maxTotal, executionSummary, format);
                }
                catch (Exception e)
                {
                    Debug.WriteLine($"Try: {tries} {e.GetType().FullName}: {e.Message}");
                    if (tries >= maxTries)
                    {
                        PrintSummary(iterations, maxAverage, maxTotal, description, format, executionSummary);
                        throw;
                    }
                    continue;
                }
                PrintSummary(iterations, maxAverage, maxTotal, description, format, executionSummary);
                break;
            }

            return(executionSummary);
        }
Example #12
0
        public async Task <ActionResult> SubmitRequest(string snippetId, string connectionId)
        {
            long startTimestamp = StopwatchExtensions.GetTimestampMillis();

            if (String.IsNullOrEmpty(snippetId))
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            if (connectionId != null)
            {
                Task.Run(() => SubmitSnippetPostFeedback(snippetId, connectionId, startTimestamp)).FireAndForget();
                return(new HttpStatusCodeResult(HttpStatusCode.Accepted));
            }
            else
            {
                SnippetResult result = await hostConnector.RunSnippetAsync(snippetId);

                result.totalTime    = StopwatchExtensions.GetTimestampMillis() - startTimestamp;
                Response.StatusCode = (int)HttpStatusCode.OK;
                return(Json(new { connectionId = connectionId, message = result, newStatus = result.status.ToHealth().ToColor() }));
            }
        }
Example #13
0
        private static async Task SendOrders(IMessageSession endpointInstance)
        {
            Console.WriteLine("Press enter to send 1 message or a number + enter to send X messages.");
            Console.WriteLine("Type 'exit' to exit");
            Console.WriteLine();

            while (true)
            {
                var keys = Console.ReadLine();
                int count;

                if (keys == "")
                {
                    count = 1;
                }
                else if (string.Compare(keys, "exit", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    return;
                }
                else
                {
                    if (!int.TryParse(keys, out count))
                    {
                        await Console.Out.WriteLineAsync("Keys Not Recognized.");
                    }
                }
                var sw = StopwatchExtensions.CreateStartSW();
                for (var inc = 0; inc < count; inc++)
                {
                    await SendOrder(endpointInstance, count > 1 && inc != count - 1);
                }
                if (count > 1)
                {
                    await sw.LogTimeToConsoleAsync($"GROUP COMPLETE ");
                }
            }
        }
        public Task Handle(OrderPlaced message, IMessageHandlerContext context)
        {
            _processingCount++;

            _log.Info($"RECV {nameof(OrderPlaced)} [{_processingCount}], {nameof(message.OrderId)}: {message.OrderId}");

            if (message.IsGrouped != _groupItems)
            {
                // Grouping completed.
                if (_groupItems)
                {
                    _groupItems = false;
                    _log.Info(_sw.LogTimeToMessage("GROUP COMPLETE "));
                }
                // Grouping started;
                else
                {
                    _groupItems = true;
                    _sw         = StopwatchExtensions.CreateStartSW();
                }
            }

            return(Task.CompletedTask);
        }
Example #15
0
        private void WatchdogThreadFunc()
        {
            while (!isExiting)
            {
                // This is a watchdog; it does not need to be precise.
                // It can be improved by recomputing the next check time (i.e. when a snippet expires)
                // at each submission, but for now we are good.

                // We sleep for a while, than check
                try {
                    //Thread.Sleep(1000);
                    HostEvent hostEvent;
                    if (defaultDomainManager.GetHostMessage(1000, out hostEvent))
                    {
                        System.Diagnostics.Debug.WriteLine("Watchdog: message from host for AppDomain " + hostEvent.appDomainId);
                        // Process event
                        switch ((HostEventType)hostEvent.eventType)
                        {
                        case HostEventType.OutOfTasks: {
                            PooledDomainData poolDomain = FindByAppDomainId(hostEvent.appDomainId);
                            if (poolDomain != null)
                            {
                                if (Interlocked.CompareExchange(ref poolDomain.isAborting, 1, 0) == 0)
                                {
                                    poolDomain.mainThread.Abort(threadsExaustedAbortToken);
                                }
                            }
                        }
                        break;
                        }
                    }
                    else
                    {
                        long currentTime = StopwatchExtensions.GetTimestampMillis();
                        //System.Diagnostics.Debug.WriteLine("Watchdog: check at " + currentTime);

                        for (int i = 0; i < NumberOfDomainsInPool; ++i)
                        {
                            // Something is running?
                            PooledDomainData poolDomain = null;
                            lock (poolLock) {
                                poolDomain = poolDomains[i];
                            }

                            if (poolDomain != null)
                            {
                                long snippetStartTime = Thread.VolatileRead(ref poolDomain.timeOfSubmission);
                                if (snippetStartTime > 0)
                                {
                                    // For too long?
                                    long millisRunning = currentTime - snippetStartTime;
                                    if (millisRunning > runningThreshold)
                                    {
                                        // Abort Thread i / Unload domain i
                                        // Calling abort here is fine: the host will escalate it for us if it times
                                        // out. Otherwise, we can still catch it and reuse the AppDomain
                                        System.Diagnostics.Debug.WriteLine("Timeout: aborting thread #{0} in domain {1} ({2} ms)", i, poolDomains[i].domainId, millisRunning);

                                        // Avoid to call Abort twice
                                        Thread.VolatileWrite(ref poolDomains[i].timeOfSubmission, 0);
                                        poolDomains[i].mainThread.Abort(timeoutAbortToken);
                                    }
                                    // Check also for appDomain.MonitoringTotalProcessorTime
                                    //else if (poolDomains[i].appDomain.MonitoringTotalProcessorTime > MaxCpuTime)
                                    //   //TODO
                                    //}
                                }

                                // If our thread was aborted rudely, we need to create a new one
                                if (poolDomain.mainThread == null || poolDomain.mainThread.ThreadState == System.Threading.ThreadState.Aborted)
                                {
                                    defaultDomainManager.HostUnloadDomain(poolDomain.domainId);
                                    poolDomains[i] = new PooledDomainData();
                                    var thread = CreateDomainThread(i);
                                    thread.Start();
                                }
                            }
                        }
                    }

                    // Ensure there is at least a thread in the pool
                    if (numberOfThreadsInPool < 1)
                    {
                        poolDomains[0] = new PooledDomainData();
                        var thread = CreateDomainThread(0);
                        thread.Start();
                    }
                }
                catch (ThreadInterruptedException) {
                    // Do we need to exit? Simply cycle back to check exit status
                }
            }
        }
Example #16
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 #17
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();
        }
        private static void RunAsserts(TimeSpan? maxAverage, TimeSpan? maxTotal, StopwatchExtensions.TimedExecutionSummary executionSummary, Func<TimeSpan?, string> format)
        {
            if(maxTotal.HasValue && executionSummary.Total > maxTotal.Value)
            {
                throw new Exception($"{nameof(maxTotal)}: {format(maxTotal)} exceeded. Was: {format(executionSummary.Total)}");
            }

            if(maxAverage.HasValue && executionSummary.Average > maxAverage.Value)
            {
                throw new Exception($"{nameof(maxAverage)} exceeded");
            }
        }
Example #19
0
        private Thread CreateDomainThread(int threadIndex)
        {
            System.Diagnostics.Debug.WriteLine("CreateDomainThread: " + threadIndex);

            var myPoolDomain = poolDomains[threadIndex];

            var thread = new Thread(() => {
                Interlocked.Increment(ref numberOfThreadsInPool);
                // Here we enforce the "one domain, one thread" relationship
                try {
                    var appDomain = AppDomainHelpers.CreateSandbox("Host Sandbox");
                    var manager   = (SimpleHostAppDomainManager)appDomain.DomainManager;

                    lock (poolLock) {
                        myPoolDomain.domainId = appDomain.Id;
                    }

                    while (!snippetsQueue.IsCompleted)
                    {
                        defaultDomainManager.ResetContextFor(myPoolDomain);

                        // And here is were we "rent" one AppDomain and use it to run a snippet
                        SnippetInfo snippetToRun = null;
                        try {
                            snippetToRun = snippetsQueue.Take();
                        }
                        catch (InvalidOperationException) {
                            // Someone called "complete". No more snippets in this process.
                            // We want to exit the pool.
                            return;
                        }

                        if (snippetToRun != null)
                        {
                            System.Diagnostics.Debug.WriteLine("Starting snippet '" + snippetToRun.methodName + "' in domain " + myPoolDomain.domainId);

                            SnippetResult result = new SnippetResult();
                            bool recycleDomain   = false;

                            try {
                                Interlocked.Increment(ref myPoolDomain.numberOfUsages);
                                // Record when we started
                                long startTimestamp = StopwatchExtensions.GetTimestampMillis();
                                System.Diagnostics.Debug.WriteLine("Starting execution at " + startTimestamp);
                                Thread.VolatileWrite(ref myPoolDomain.timeOfSubmission, startTimestamp);

                                // Thread transitions into the AppDomain
                                // This function DOES NOT throw
                                result = manager.InternalRun(appDomain, snippetToRun.assemblyFile, snippetToRun.mainTypeName, snippetToRun.methodName, true);


                                // ...back to the main AppDomain
                                Debug.Assert(AppDomain.CurrentDomain.IsDefaultAppDomain());
                                long currentTime     = StopwatchExtensions.GetTimestampMillis();
                                result.executionTime = currentTime - Thread.VolatileRead(ref myPoolDomain.timeOfSubmission);
                                // Flag it as "not executing"
                                Thread.VolatileWrite(ref myPoolDomain.timeOfSubmission, 0);
                            }
                            catch (ThreadAbortException ex) {
                                // Someone called abort on us.
                                result.exception = ex.Message;

                                // It may be possible to use this domain again, otherwise we will recycle
                                if (Object.Equals(ex.ExceptionState, timeoutAbortToken))
                                {
                                    // The abort was issued by us because we timed out
                                    System.Diagnostics.Debug.WriteLine("Thread Abort due to timeout");
                                    result.status = SnippetStatus.Timeout;
                                }
                                else if (Object.Equals(ex.ExceptionState, threadsExaustedAbortToken))
                                {
                                    System.Diagnostics.Debug.WriteLine("Thread Abort due to thread exaustion");
                                    result.status = SnippetStatus.ResourceError;
                                }
                                else
                                {
                                    // If it wasn't us, give us time to record the result; we will recycle (unload) the domain
                                    System.Diagnostics.Debug.WriteLine("Thread Abort due to external factors");
                                    result.status = SnippetStatus.CriticalError;
                                    recycleDomain = true;
                                }

                                // Give us time to record the result; if needed, we will recycle (unload) the domain later
                                Thread.ResetAbort();
                            }
                            catch (Exception ex) {
                                result.exception = ex.Message;
                                // Check if someone is misbehaving, throwing something else to "mask" the TAE
                                if (Thread.CurrentThread.ThreadState == System.Threading.ThreadState.AbortRequested)
                                {
                                    result.status = SnippetStatus.CriticalError;
                                    recycleDomain = true;

                                    // Give us time to record the result; we will recycle (unload) the domain
                                    Thread.ResetAbort();
                                }
                                else
                                {
                                    result.status = SnippetStatus.ExecutionError;
                                }
                            }
                            // "Although C# only allows you to throw objects of type Exception and types deriving from it,
                            // other languages don’t have any such restriction."
                            // http://weblogs.asp.net/kennykerr/introduction-to-msil-part-5-exception-handling
                            // It turns out this is no longer necessary
                            // http://blogs.msdn.com/b/jmanning/archive/2005/09/16/469091.aspx
                            // catch { }

                            // No need to catch StackOverflowException; the Host will escalate to a (rude) domain unload
                            // for us
                            // TODO: check that AppDomain.DomainUnload is called anyway!

                            // Before looping, check if we are OK; we reuse the domain only if we are not leaking
                            int threadsInDomain = defaultDomainManager.GetThreadCount(appDomain.Id);
                            int memoryUsage     = defaultDomainManager.GetMemoryUsage(appDomain.Id);

                            System.Diagnostics.Debug.WriteLine("============= AppDomain {0} =============", appDomain.Id);
                            System.Diagnostics.Debug.WriteLine("Finished in: {0}", result.executionTime);
                            System.Diagnostics.Debug.WriteLine("Status: {0}", result.status);
                            if (result.exception != null)
                            {
                                System.Diagnostics.Debug.WriteLine("Exception: " + result.exception);
                            }
                            System.Diagnostics.Debug.WriteLine("Threads: {0}", threadsInDomain);
                            System.Diagnostics.Debug.WriteLine("Memory: {0}", memoryUsage);
                            System.Diagnostics.Debug.WriteLine("========================================");

                            if (threadsInDomain > 1)
                            {
                                // The snippet is leaking threads

                                // Flag snippet as "leaking"
                                result.status = SnippetStatus.CriticalError;
                                System.Diagnostics.Debug.WriteLine("Leaking snippet");

                                recycleDomain = true;
                            }
                            else if (MaxReuse > 0 && myPoolDomain.numberOfUsages >= MaxReuse)
                            {
                                System.Diagnostics.Debug.WriteLine("Domain too old");

                                // Same if the domain is too old
                                recycleDomain = true;
                            }

                            // Return the result to the caller
                            if (!String.IsNullOrEmpty(snippetToRun.submissionId))
                            {
                                var completion = submissionMap[snippetToRun.submissionId];
                                // TCS is thread-safe (can be called cross-thread)
                                completion.TrySetResult(result);
                            }

                            if (recycleDomain)
                            {
                                System.Diagnostics.Debug.WriteLine("Recycling domain...");
                                RecycleDomain(threadIndex);
                            }
                            else
                            {
                                // Otherwise, ensure that what was allocated by the snippet is freed
                                GC.Collect();
                                System.Diagnostics.Debug.WriteLine("MonitoringSurvivedMemorySize {0}", appDomain.MonitoringSurvivedMemorySize);
                                System.Diagnostics.Debug.WriteLine("MonitoringTotalAllocatedMemorySize {0}", appDomain.MonitoringTotalAllocatedMemorySize);
                                System.Diagnostics.Debug.WriteLine("MonitoringTotalProcessorTime {0}", appDomain.MonitoringTotalProcessorTime);
                            }
                        }
                    }
                }
                catch (Exception ex) {
                    System.Diagnostics.Debug.WriteLine("Exception caught:\n" + ex.ToString());
                    RecycleDomain(threadIndex);
                }
            });

            thread.Name             = "DomainPool thread " + threadIndex;
            myPoolDomain.mainThread = thread;
            thread.Priority         = ThreadPriority.BelowNormal;
            return(thread);
        }
     private static void PrintSummary
         (int iterations, TimeSpan? maxAverage, TimeSpan? maxTotal, string description, Func<TimeSpan?, string> format, StopwatchExtensions.TimedExecutionSummary executionSummary)
     {
         if(iterations > 1)
         {
             Console.WriteLine(
                 $@"Executed {iterations:N} iterations of {description}  
 Total:   {format(executionSummary.Total)} Limit: {format(maxTotal)} 
 Average: {format
                     (executionSummary.Average)} Limit: {format(maxAverage)}");
         }
         else
         {
             Console.WriteLine(
                 $@"Executed {iterations} iterations of {description}  
 Total:   {format(executionSummary.Total)} Limit: {format(maxTotal)}");
         }
     }
Example #21
0
        protected override void Update(GameTime gameTime)
        {
            Int64 now = Stopwatch.GetTimestamp();

            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            //
            // Update controls
            //
            KeyboardState keyboardState = Keyboard.GetState();

            playerPositionControl.Update(keyboardState, ref playerPosition);

            //
            // Update Background Color
            //
            backgroundColor = new Color((Int32)((gameTime.TotalGameTime.Seconds * 100) & 0xFF), 100, 100);

            //
            // Create Center Translation Matrix
            //
            if (viewWidth != GraphicsDevice.Viewport.Width || viewHeightHalf != GraphicsDevice.Viewport.Height)
            {
                // Window size changed
                viewWidth     = GraphicsDevice.Viewport.Width;
                viewWidthHalf = viewWidth / 2;

                viewHeight     = GraphicsDevice.Viewport.Height;
                viewHeightHalf = viewHeight / 2;

                maxWidthOrHeight     = (viewWidth >= viewHeight) ? viewWidth : viewHeight;
                maxWidthOrHeightHalf = maxWidthOrHeight / 2;

                windowCenterTranslationMatrix = Matrix.CreateTranslation(viewWidthHalf, viewHeightHalf, 0);
            }

            //
            // Update Game World rotation
            //
            //gameWorldRotationMatrix = gameWorldRotationMatrix * Matrix.CreateRotationZ((float)gameTime.ElapsedGameTime.Ticks * .00000001f);

            gameWorldMatrix = gameWorldRotationMatrix * windowCenterTranslationMatrix;



            //
            // Add new Update Obstacles
            //
            while (lastObstacleUpdateTime < now)
            {
                for (int i = 0; i < obstacles.Count; i++)
                {
                    obstacleDistances[i] -= 1;
                }

                //
                // Check if first obstacle must be removed
                //
                if (obstacles.Count > 0 && obstacleDistances[0] <= 0)
                {
                    obstacles.RemoveAt(0);
                    obstacleDistances.RemoveAt(0);
                }

                //
                // Keep adding obstacles till distance is good
                //
                GenerateObstacles();

                lastObstacleUpdateTime += StopwatchExtensions.MillisToStopwatchTicks(1);
            }
        }