コード例 #1
0
        public async Task CanRecoverFromError()
        {
            int hits       = 0;
            var resetEvent = new AsyncAutoResetEvent(false);

            Task <DateTime?> Callback()
            {
                Interlocked.Increment(ref hits);
                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation("Callback called for the #{Hits} time", hits);
                }
                if (hits == 1)
                {
                    throw new Exception("Error in callback");
                }

                resetEvent.Set();
                return(Task.FromResult <DateTime?>(null));
            }

            using (var timer = new ScheduledTimer(Callback, loggerFactory: Log)) {
                timer.ScheduleNext();
                await resetEvent.WaitAsync(new CancellationTokenSource(800).Token);

                Assert.Equal(2, hits);
            }
        }
コード例 #2
0
        public async Task CanRunAndScheduleConcurrently()
        {
            Log.SetLogLevel <ScheduledTimer>(LogLevel.Trace);

            int hits  = 0;
            var timer = new ScheduledTimer(async() => {
                _logger.Info("Starting work.");
                Interlocked.Increment(ref hits);
                await Task.Delay(1000);
                _logger.Info("Finished work.");
                return(null);
            }, loggerFactory: Log);

            timer.ScheduleNext();
            await Task.Delay(1);

            timer.ScheduleNext();

            await Task.Delay(50);

            Assert.Equal(1, hits);

            await Task.Delay(1000);

            Assert.Equal(2, hits);
        }
コード例 #3
0
        public async Task CanRunConcurrent()
        {
            int hits = 0;

            Log.SetLogLevel <ScheduledTimer>(LogLevel.Trace);

            var timer = new ScheduledTimer(() => {
                int i = Interlocked.Increment(ref hits);
                _logger.Info($"Running {i}...");
                return(Task.FromResult <DateTime?>(null));
            }, minimumIntervalTime: TimeSpan.FromMilliseconds(250), loggerFactory: Log);

            for (int i = 0; i < 5; i++)
            {
                timer.ScheduleNext();
                await Task.Delay(5);
            }

            await Task.Delay(1000);

            Assert.Equal(2, hits);

            await Task.Delay(100);

            Assert.Equal(2, hits);
        }
コード例 #4
0
        public async Task CanRunWithMinimumInterval()
        {
            var countdown = new AsyncCountdownEvent(2);

            Func <Task <DateTime?> > callback = async() => {
                _logger.Info("Starting work.");
                countdown.Signal();
                await SystemClock.SleepAsync(500);

                _logger.Info("Finished work.");
                return(null);
            };

            using (var timer = new ScheduledTimer(callback, minimumIntervalTime: TimeSpan.FromMilliseconds(100), loggerFactory: Log)) {
                for (int i = 0; i < 4; i++)
                {
                    timer.ScheduleNext();
                    SystemClock.Sleep(1);
                }

                await countdown.WaitAsync(TimeSpan.FromMilliseconds(100));

                Assert.Equal(1, countdown.CurrentCount);

                await countdown.WaitAsync(TimeSpan.FromSeconds(1.5));

                Assert.Equal(0, countdown.CurrentCount);
            }
        }
コード例 #5
0
        public async Task CanRecoverFromError()
        {
            var resetEvent = new AsyncAutoResetEvent(false);

            int hits = 0;
            Func <Task <DateTime?> > callback = () => {
                Interlocked.Increment(ref hits);
                _logger.Info("Callback called for the #{time} time", hits);
                if (hits == 1)
                {
                    throw new Exception("Error in callback");
                }

                resetEvent.Set();
                return(Task.FromResult <DateTime?>(null));
            };

            using (var timer = new ScheduledTimer(callback, loggerFactory: Log)) {
                timer.ScheduleNext();

                await resetEvent.WaitAsync(new CancellationTokenSource(500).Token);

                Assert.Equal(2, hits);
            }
        }
コード例 #6
0
        public void StatusShouldBeStoppedWhenInstanceCreated()
        {
            const ScheduledTimerStatus expected = ScheduledTimerStatus.Stopped;

            var sut = new ScheduledTimer();

            Assert.That(sut.Status, Is.EqualTo(expected));
        }
コード例 #7
0
        public void IntervalShouldBeSetTo1WhenStartWithNoParameterIsCalled()
        {
            var sut = new ScheduledTimer();

            sut.Begin();

            Assert.That(sut.TimerObject.Interval, Is.EqualTo(1));
        }
コード例 #8
0
        public void SetStartTimeShouldUpdateTheTimerIntervalAccordingly()
        {
            var sut = new ScheduledTimer();

            sut.StartingAt(DateTime.Now.AddSeconds(3));

            // Becuase of the nature of time, give the interval a second of leeway
            Assert.That(sut.TimerObject.Interval, Is.InRange(2900d, 3000d));
        }
コード例 #9
0
        public void StartWithNoParameterShouldUpdateTheStatusToRunning()
        {
            const ScheduledTimerStatus expected = ScheduledTimerStatus.Running;

            var sut = new ScheduledTimer();

            sut.Begin();

            Assert.That(sut.Status, Is.EqualTo(expected));
        }
コード例 #10
0
        public void TimerShouldWaitForDoMethodByDefault()
        {
            int count = 0;
            var sut   = new ScheduledTimer()
                        .Do(() => { Interlocked.Add(ref count, 1); Thread.Sleep(10000); })
                        .Every(TimeSpan.FromMilliseconds(100))
                        .StartingAt(DateTime.Now)
                        .Begin();

            Thread.Sleep(1000);
            Assert.That(count, Is.EqualTo(1));
        }
コード例 #11
0
        public void StartingAtShouldWaitToStart()
        {
            int count = 0;
            var sut   = new ScheduledTimer()
                        .Do(() => Interlocked.Add(ref count, 1))
                        .Every(TimeSpan.FromMilliseconds(100))
                        .StartingAt(DateTime.Now.AddMinutes(1))
                        .Begin();

            Thread.Sleep(1000);
            Assert.That(count, Is.LessThanOrEqualTo(0));
        }
コード例 #12
0
        public async Task CanRun()
        {
            var resetEvent = new AsyncAutoResetEvent();
            Func <Task <DateTime?> > callback = () => {
                resetEvent.Set();
                return(null);
            };

            using (var timer = new ScheduledTimer(callback, loggerFactory: Log)) {
                timer.ScheduleNext();
                await resetEvent.WaitAsync(new CancellationTokenSource(500).Token);
            }
        }
コード例 #13
0
        public void SettingStartTimeShouldOverwriteIntervalPreviouslySet()
        {
            var sut = new ScheduledTimer();

            sut.Every(new TimeSpan(0, 0, 0, 1));

            Assert.That(sut.TimerObject.Interval, Is.EqualTo(1000));

            sut.StartingAt(DateTime.Now.AddSeconds(3));

            // Becuase of the nature of time, give the interval a second of leeway
            Assert.That(sut.TimerObject.Interval, Is.InRange(2900d, 3000d));
        }
コード例 #14
0
        public void TimerShouldNotWaitWhenSet()
        {
            int count = 0;
            var sut   = new ScheduledTimer()
                        .Do(() => { Interlocked.Add(ref count, 1); Thread.Sleep(10000); })
                        .Every(TimeSpan.FromMilliseconds(100))
                        .DontWait()
                        .StartingAt(DateTime.Now)
                        .Begin();

            Thread.Sleep(1000);
            Assert.That(count, Is.GreaterThan(5));
        }
コード例 #15
0
        public MetricsQueueBehavior(IMetricsClient metrics, string metricsPrefix = null, ILoggerFactory loggerFactory = null)
        {
            _logger        = loggerFactory?.CreateLogger <MetricsQueueBehavior <T> >() ?? NullLogger.Instance;
            _metricsClient = metrics ?? NullMetricsClient.Instance;

            if (!String.IsNullOrEmpty(metricsPrefix) && !metricsPrefix.EndsWith("."))
            {
                metricsPrefix += ".";
            }

            metricsPrefix += typeof(T).Name.ToLowerInvariant();
            _metricsPrefix = metricsPrefix;
            _timer         = new ScheduledTimer(ReportQueueCountAsync, minimumIntervalTime: TimeSpan.FromMilliseconds(500), loggerFactory: loggerFactory);
        }
コード例 #16
0
        public void StatusShouldBeStoppedWhenFluentDoesNotSpecifyBegin()
        {
            int count = 0;
            const ScheduledTimerStatus expected = ScheduledTimerStatus.Stopped;

            var sut = new ScheduledTimer()
                      .Do(() => Interlocked.Increment(ref count))
                      .StartingAt(DateTime.Now)
                      .Every(TimeSpan.FromMilliseconds(10));

            Thread.Sleep(100);
            Assert.That(sut.Status, Is.EqualTo(expected));
            Assert.That(count, Is.EqualTo(0));
        }
コード例 #17
0
        public void DisposeWithTimerStoppedShouldDisposeInternalTimer()
        {
            const ScheduledTimerStatus expected = ScheduledTimerStatus.Stopped;

            var sut = new ScheduledTimer();

            var disposed = false;

            sut.TimerObject.Disposed += ((sender, args) => disposed = true);

            sut.Dispose();

            Assert.That(sut.Status, Is.EqualTo(expected));
            Assert.That(disposed, Is.True);
        }
コード例 #18
0
        public void StartThenStopShouldUpdateStatusToStopped()
        {
            const ScheduledTimerStatus expectedRunning = ScheduledTimerStatus.Running;
            const ScheduledTimerStatus expectedStopped = ScheduledTimerStatus.Stopped;

            var sut = new ScheduledTimer();

            sut.Begin();

            Assert.That(sut.Status, Is.EqualTo(expectedRunning));

            sut.End();

            Assert.That(sut.Status, Is.EqualTo(expectedStopped));
        }
コード例 #19
0
        public async Task CanRun()
        {
            var countdown = new AsyncCountdownEvent(1);
            Func <Task <DateTime?> > callback = () => {
                countdown.Signal();
                return(null);
            };

            using (var timer = new ScheduledTimer(callback, loggerFactory: Log)) {
                timer.ScheduleNext();
                await countdown.WaitAsync(TimeSpan.FromMilliseconds(100));

                Assert.Equal(0, countdown.CurrentCount);
            }
        }
コード例 #20
0
        public void SetReplicationIntervalShouldUpdateTheTimerIntervalAndAutoResetAccordingly()
        {
            var sut = new ScheduledTimer();

            var counter = 0;

            sut.Do(() => Interlocked.Increment(ref counter)).Every(TimeSpan.FromMilliseconds(100));

            Assert.That(sut.TimerObject.Interval, Is.EqualTo(100));

            sut.Begin();

            Thread.Sleep(550);

            Assert.That(counter, Is.GreaterThanOrEqualTo(5));
        }
コード例 #21
0
        public void ScheduleTimerShouldOnlyCallDoOnceEvenWithMultipleBeginRequests()
        {
            int count = 0;

            var sut = new ScheduledTimer()
                      .Do(() => Interlocked.Increment(ref count))
                      .StartingAt(DateTime.Now)
                      .Every(TimeSpan.FromMilliseconds(1000));

            Task.Run(() => sut.Begin());
            Task.Run(() => sut.Begin());
            Task.Run(() => sut.Begin());

            Thread.Sleep(200);
            Assert.That(count, Is.EqualTo(1));
        }
コード例 #22
0
        public async Task CanRun()
        {
            Log.SetLogLevel <ScheduledTimer>(LogLevel.Trace);

            int hits  = 0;
            var timer = new ScheduledTimer(async() => {
                Interlocked.Increment(ref hits);
                await Task.Delay(50);
                return(null);
            }, loggerFactory: Log);

            timer.ScheduleNext();

            await Task.Delay(50);

            Assert.Equal(1, hits);
        }
コード例 #23
0
        public void IntervalUpdatedBeforeStartShouldChangeTheIntervalUntilStartHasBeenCalled()
        {
            var sut = new ScheduledTimer();

            sut.Every(TimeSpan.FromMilliseconds(100));

            Assert.That(sut.TimerObject.Interval, Is.EqualTo(100));

            sut.StartingAt(DateTime.Now.AddMilliseconds(200));

            // Becuase of the nature of time, give the interval a second of leeway
            Assert.That(sut.TimerObject.Interval, Is.InRange(200d, 300d));

            sut.Begin();

            Thread.Sleep(300);

            Assert.That(sut.TimerObject.Interval, Is.EqualTo(100));
        }
コード例 #24
0
        public MetricsQueueBehavior(IMetricsClient metrics, string metricsPrefix = null, TimeSpan?reportCountsInterval = null, ILoggerFactory loggerFactory = null)
        {
            _logger        = loggerFactory.CreateLogger <MetricsQueueBehavior <T> >();
            _metricsClient = metrics ?? NullMetricsClient.Instance;

            if (!reportCountsInterval.HasValue)
            {
                reportCountsInterval = TimeSpan.FromMilliseconds(500);
            }

            _reportInterval = reportCountsInterval.Value > TimeSpan.Zero ? reportCountsInterval.Value : TimeSpan.FromMilliseconds(250);
            if (!String.IsNullOrEmpty(metricsPrefix) && !metricsPrefix.EndsWith("."))
            {
                metricsPrefix += ".";
            }

            metricsPrefix += typeof(T).Name.ToLowerInvariant();
            _metricsPrefix = metricsPrefix;
            _timer         = new ScheduledTimer(ReportQueueCountAsync, loggerFactory: loggerFactory);
        }
コード例 #25
0
        public async Task CanRunWithMinimumInterval()
        {
            Log.SetLogLevel <ScheduledTimer>(LogLevel.Trace);

            int hits  = 0;
            var timer = new ScheduledTimer(async() => {
                Interlocked.Increment(ref hits);
                await Task.Delay(50);
                return(null);
            }, minimumIntervalTime: TimeSpan.FromMilliseconds(50), loggerFactory: Log);

            timer.Run();
            timer.Run();

            await Task.Delay(1);

            Assert.Equal(1, hits);

            await Task.Delay(100);

            Assert.Equal(2, hits);
        }
コード例 #26
0
        public async Task CanRunWithMinimumInterval()
        {
            Log.SetLogLevel <ScheduledTimer>(LogLevel.Trace);
            var resetEvent = new AsyncAutoResetEvent(false);

            int hits  = 0;
            var timer = new ScheduledTimer(() => {
                Interlocked.Increment(ref hits);
                resetEvent.Set();
                return(Task.FromResult <DateTime?>(null));
            }, minimumIntervalTime: TimeSpan.FromMilliseconds(100), loggerFactory: Log);

            timer.ScheduleNext();
            await Task.Delay(1);

            timer.ScheduleNext();
            await Task.Delay(1);

            timer.ScheduleNext();

            await resetEvent.WaitAsync(new CancellationTokenSource(100).Token);

            var sw = Stopwatch.StartNew();

            Assert.Equal(1, hits);

            await resetEvent.WaitAsync(new CancellationTokenSource(500).Token);

            sw.Stop();
            Assert.Equal(2, hits);

            Assert.Throws <TaskCanceledException>(() => {
                resetEvent.Wait(new CancellationTokenSource(100).Token);
            });

            await Task.Delay(110);

            Assert.Equal(2, hits);
        }
コード例 #27
0
        private async Task CanRunConcurrentlyAsync(TimeSpan?minimumIntervalTime = null)
        {
            Log.MinimumLevel = LogLevel.Trace;
            const int iterations = 2;
            var       countdown  = new AsyncCountdownEvent(iterations);

            async Task <DateTime?> Callback()
            {
                _logger.LogInformation("Starting work.");
                await SystemClock.SleepAsync(250);

                countdown.Signal();
                _logger.LogInformation("Finished work.");
                return(null);
            }

            using (var timer = new ScheduledTimer(Callback, minimumIntervalTime: minimumIntervalTime, loggerFactory: Log)) {
                timer.ScheduleNext();
                var t = Task.Run(async() => {
                    for (int i = 0; i < iterations; i++)
                    {
                        await SystemClock.SleepAsync(10);
                        timer.ScheduleNext();
                    }
                });

                _logger.LogInformation("Waiting for 300ms");
                await countdown.WaitAsync(TimeSpan.FromMilliseconds(300));

                _logger.LogInformation("Finished waiting for 300ms");
                Assert.Equal(iterations - 1, countdown.CurrentCount);

                _logger.LogInformation("Waiting for 1.5 seconds");
                await countdown.WaitAsync(TimeSpan.FromSeconds(1.5));

                _logger.LogInformation("Finished waiting for 1.5 seconds");
                Assert.Equal(0, countdown.CurrentCount);
            }
        }
コード例 #28
0
        private async Task CanRunConcurrentlyAsync(TimeSpan?minimumIntervalTime = null)
        {
            var countdown = new AsyncCountdownEvent(2);

            Func <Task <DateTime?> > callback = async() => {
                _logger.Info("Starting work.");
                countdown.Signal();
                await SystemClock.SleepAsync(500);

                _logger.Info("Finished work.");
                return(null);
            };

            using (var timer = new ScheduledTimer(callback, minimumIntervalTime: minimumIntervalTime, loggerFactory: Log)) {
                timer.ScheduleNext();
                var t = Task.Run(async() => {
                    for (int i = 0; i < 3; i++)
                    {
                        await SystemClock.SleepAsync(10);
                        timer.ScheduleNext();
                    }
                });

                _logger.Info("Waiting for 300ms");
                await countdown.WaitAsync(TimeSpan.FromMilliseconds(300));

                _logger.Info("Finished waiting for 300ms");
                Assert.Equal(1, countdown.CurrentCount);

                _logger.Info("Waiting for 1.5 seconds");
                await countdown.WaitAsync(TimeSpan.FromSeconds(1.5));

                _logger.Info("Finished waiting for 1.5 seconds");
                Assert.Equal(0, countdown.CurrentCount);
            }
        }
コード例 #29
0
        public void ObjectCreationShouldCreateTheTimerObject()
        {
            var sut = new ScheduledTimer();

            Assert.That(sut.TimerObject, Is.Not.Null);
        }
コード例 #30
0
        public void CreateInstance()
        {
            var sut = new ScheduledTimer();

            Assert.That(sut, Is.Not.Null);
        }