예제 #1
0
        public async Task PerformanceTest_HundredsOfTimingEventsFinishesInAFewSeconds()
        {
            // create the orchestrator
            var context = new EventContext();

            context.AddLogAction(
                (m) => output.WriteLine(m.ToString())
                );

            var time = DateTime.Parse("01/01/2018 10:00AM");

            // create a consumer that when it receives a time event, that matches it's schedule, it will trigger a log write event
            var timeEventConsumer = new TimeEventConsumer();

            timeEventConsumer.EventAction = (triggerTime) => context.RaiseEvent(
                new LogEvent(context)
            {
                Message = $"Log of: TimeEvent hit at: {triggerTime.Ticks}",
                Time    = context.GetTimeNow()
            }, timeEventConsumer
                );

            // create a schedule that will only fire the Action when the time matches the event time
            timeEventConsumer.Schedules.Add(new Schedule {
                Frequency = ScheduleFrequency.OncePerDay, TimeToRun = time
            });

            var totalEventsSent = 100;

            // create a consumer that will see the evenets and write to the log
            var logWriteConsumer = new LogEventConsumer();

            context.RegisterConsumer <TimeEvent>(timeEventConsumer);
            context.RegisterConsumer <LogEvent>(logWriteConsumer);

            // run and ensure the listeners are all responding
            context.Initialize();

            var tasks = Enumerable.Range(1, totalEventsSent)
                        .Select(index => Task.Run(() => context.RaiseEvent(new TimeEvent(context, time.AddDays(-1 * index)), null)));

            await Task.WhenAll(tasks);

            context.AssertEventExists <TimeEvent>(totalEventsSent);
            context.AssertEventExists <LogEvent>(totalEventsSent);

            output.WriteLine(Environment.NewLine + "Warehouse Contents:");

            Parallel.ForEach(logWriteConsumer.LogLines,
                             new ParallelOptions {
                MaxDegreeOfParallelism = 10
            },
                             (line) =>
            {
                output.WriteLine(line);
            }
                             );

            logWriteConsumer.LogLines.Count().Should().Be(totalEventsSent + 1);
        }
예제 #2
0
        public void AddScheduledAction(Schedule schedule, Action <DateTime> actionToPerform)
        {
            var consumer = new TimeEventConsumer();

            consumer.Schedules.Add(schedule);
            consumer.EventAction = (time) => actionToPerform(time);
            RegisterConsumer <TimeEvent>(consumer);
        }
예제 #3
0
        public void TimeEventShouldTriggerOneAndOnlyOneSchedule()
        {
            // create the orchestrator
            var context = new EventContext();

            context.AddLogAction(
                (m) => output.WriteLine(m.ToString())
                );

            var time = DateTime.Parse("01/01/2018 10:00AM");

            // create a consumer that when it receives a time event, that matches it's schedule, it will trigger a log write event
            var timeEventConsumer = new TimeEventConsumer();

            timeEventConsumer.EventAction = (triggerTime) => context.RaiseEvent(
                new LogEvent(context)
            {
                Message = $"Log of: TimeEvent hit at: {triggerTime.Ticks}",
                Time    = context.GetTimeNow()
            }, timeEventConsumer
                );

            // create a schedule that will only fire the Action when the time matches the event time
            timeEventConsumer.Schedules.Add(new Schedule {
                Frequency = ScheduleFrequency.OncePerDay, TimeToRun = time
            });

            // create a consumer that will see the evenets and write to the log
            var logWriteConsumer = new LogEventConsumer();

            context.RegisterConsumer <TimeEvent>(timeEventConsumer);
            context.RegisterConsumer <LogEvent>(logWriteConsumer);

            // run and ensure the listeners are all responding
            context.Initialize();

            context.RaiseEvent(new TimeEvent(context, time), null);
            context.RaiseEvent(new TimeEvent(context, time.AddDays(-10)), null);
            context.RaiseEvent(new TimeEvent(context, time.AddDays(10)), null);

            Thread.Sleep(500);             // just wait a bit for the events to be handled

            context.AssertEventExists <TimeEvent>(3);
            context.AssertEventExists <LogEvent>(3);

            output.WriteLine(Environment.NewLine + "Warehouse Contents:");
            logWriteConsumer.LogLines.ForEach(output.WriteLine);
            logWriteConsumer.LogLines.Count().Should().Be(4);
        }
예제 #4
0
        public async Task PerformanceTest_HundredsOfHeterogeneousEventsFinishesInAFewSeconds()
        {
            // create the orchestrator
            var context = new EventContext();

            var time = DateTime.Parse("01/01/2018 10:00AM");

            // create a consumer that when it receives a time event, that matches it's schedule, it will trigger a log write event
            var timeEventConsumer = new TimeEventConsumer();

            timeEventConsumer.EventAction = (triggerTime) => context.RaiseEvent(
                new LogEvent(context)
            {
                Message = $"Log of: TimeEvent hit at: {triggerTime.Ticks}",
                Time    = context.GetTimeNow()
            }, timeEventConsumer
                );

            // create a schedule that will only fire the Action when the time matches the event time
            timeEventConsumer.Schedules.Add(new Schedule {
                Frequency = ScheduleFrequency.OncePerDay, TimeToRun = time
            });

            var totalEventsSent = 10_000;

            // create a consumer that will see the evenets and write to the log
            var logWriteConsumer = new LogEventConsumer();

            context.RegisterConsumer <TimeEvent>(timeEventConsumer);
            context.RegisterConsumer <LogEvent>(logWriteConsumer);

            // run and ensure the listeners are all responding
            context.Initialize();

            var stopwatch = new Stopwatch();

            var overheadTime = 0m;

            stopwatch.Start();

            Parallel.ForEach(Enumerable.Range(1, totalEventsSent), new ParallelOptions {
                MaxDegreeOfParallelism = 10
            },
                             (index) => { }    //context.RaiseEvent(new TimeEvent(context, time.AddDays(-1 * index)), null)
                             );

            stopwatch.Stop();

            overheadTime = stopwatch.ElapsedMilliseconds;

            // see how long it takes for the events to be emitted and then responded too
            stopwatch.Restart();

            var tasks = Enumerable.Range(1, totalEventsSent)
                        .Select(index => Task.Run(() => context.RaiseEvent(new TimeEvent(context, time.AddDays(-1 * index)), null)));

            await Task.WhenAll(tasks);

            stopwatch.Stop();

            var netRunTime = stopwatch.ElapsedMilliseconds - overheadTime;

            output.WriteLine($"Total Events: totalEventsSent, Total runtime: {stopwatch.ElapsedMilliseconds}, Runtime: {netRunTime}ms. Avg Event Time: {(netRunTime/totalEventsSent).ToString("G")} ms/event. Events/Second: {(totalEventsSent/netRunTime).ToString("0.0000")} events/ms");

            // it should be able to process a hundred events in under a second
            stopwatch.ElapsedMilliseconds.Should().BeLessThan(totalEventsSent * (long)2);             // each event should never take longer trhan 1.5milliseconds to run
        }