예제 #1
0
        void OnTick()
        {
            try
            {
                Queue <PointData> batch;
                lock (_queueLock)
                {
                    if (_queue.Count == 0)
                    {
                        return;
                    }

                    batch  = _queue;
                    _queue = new Queue <PointData>();
                }

                _parent.Emit(batch.ToArray());
            }
            catch (Exception ex)
            {
                CollectorLog.WriteLine("Failed to emit metrics batch: {0}", ex);
            }
            finally
            {
                lock (_stateLock)
                {
                    if (!_unloading)
                    {
                        _timer.Start(_interval);
                    }
                }
            }
        }
예제 #2
0
        Task OnTick()
        {
            try
            {
                Queue <PointData> batch;
                lock (_queueLock)
                {
                    if (_queue.Count == 0)
                    {
                        return(Task.Delay(0));
                    }

                    batch  = _queue;
                    _queue = new Queue <PointData>();
                }

                _parent.Emit(batch.ToArray());
            }
            catch (Exception ex)
            {
                CollectorLog.ReportError("Failed to emit metrics batch", ex);
            }
            finally
            {
                lock (_stateLock)
                {
                    if (!_unloading)
                    {
                        _timer.Start(_interval);
                    }
                }
            }

            return(Task.Delay(0));
        }
        /// <summary>
        /// Queues the span. If the reporter is being disposed, then the span is ignored.
        /// </summary>
        public void Report(ISpan span)
        {
            if (span == null)
            {
                return;
            }

            if (_unloading)
            {
                OnSpanDropped(1, DropReasonShutdown);
                return;
            }

            _queue.Enqueue(span);

            RemoveOldEntriesIfNecessary();

            if (!_started)
            {
                lock (_stateLock)
                {
                    if (_started || _unloading)
                    {
                        return;
                    }

                    _started = true;
                    _timer.Start(TimeSpan.Zero);
                }
            }
        }
예제 #4
0
        public void WhenDisposedWillThrow_OnStart()
        {
            var wasCalled = false;
            var timer     = new PortableTimer(async delegate { wasCalled = true; });

            timer.Start(TimeSpan.FromMilliseconds(100));
            timer.Dispose();

            Assert.False(wasCalled);
            Assert.Throws <ObjectDisposedException>(() => timer.Start(TimeSpan.Zero));
        }
예제 #5
0
    public void TimerShouldThrowExceptionOnStartWhenDisposed()
    {
        var wasCalled = false;
        var timer     = new PortableTimer(async() => { wasCalled = true; });

        timer.Start(TimeSpan.FromMilliseconds(100));
        timer.Dispose();

        wasCalled.ShouldBeFalse();
        Should.Throw <ObjectDisposedException>(() => timer.Start(TimeSpan.Zero)).ObjectName
        .ShouldBe(nameof(PortableTimer));
    }
예제 #6
0
        public void WhenOverlapsShouldProcessOneAtTime_OnTick()
        {
            var userHandlerOverlapped = false;

            PortableTimer timer = null;

            timer = new PortableTimer(
                async _ =>
            {
                if (Monitor.TryEnter(timer))
                {
                    try
                    {
                        // ReSharper disable once PossibleNullReferenceException
                        timer.Start(TimeSpan.Zero);
                        Thread.Sleep(20);
                    }
                    finally
                    {
                        Monitor.Exit(timer);
                    }
                }
                else
                {
                    userHandlerOverlapped = true;
                }
            });

            timer.Start(TimeSpan.FromMilliseconds(1));
            Thread.Sleep(50);
            timer.Dispose();

            Assert.False(userHandlerOverlapped);
        }
예제 #7
0
        public void WhenActiveShouldCancel_OnDispose()
        {
            bool wasCalled        = false;
            bool writtenToSelflog = false;

            SelfLog.Enable(_ => writtenToSelflog = true);

            var barrier = new Barrier(participantCount: 2);

            using (var timer = new PortableTimer(
                       async token =>
            {
                barrier.SignalAndWait();
                await Task.Delay(50);

                wasCalled = true;
                await Task.Delay(50, token);
            }))
            {
                timer.Start(TimeSpan.FromMilliseconds(20));
                barrier.SignalAndWait();
            }

            Assert.True(wasCalled, "tick handler wasn't called");
            Assert.True(writtenToSelflog, "message wasn't written to SelfLog");
        }
예제 #8
0
        public void WhenActiveShouldCancel_OnDispose()
        {
            var wasCalled        = false;
            var writtenToSelfLog = false;

            SelfLog.Enable(_ => writtenToSelfLog = true);

            var barrier = new Barrier(participantCount: 2);

            using (var timer = new PortableTimer(
                       async token =>
            {
                // ReSharper disable once MethodSupportsCancellation
                barrier.SignalAndWait();
                // ReSharper disable once MethodSupportsCancellation
                await Task.Delay(20);

                wasCalled = true;
                Interlocked.MemoryBarrier();
                await Task.Delay(100, token);
            }))
            {
                timer.Start(TimeSpan.FromMilliseconds(20));
                barrier.SignalAndWait();
            }

            Thread.Sleep(100);
            Interlocked.MemoryBarrier();

            Assert.True(wasCalled, "tick handler wasn't called");
            Assert.True(writtenToSelfLog, "message wasn't written to SelfLog");
        }
        Task OnTick()
        {
            try
            {
                Queue <PointData> batch;
                lock (_queueLock)
                {
                    if (_queue.Count == 0)
                    {
                        return(Task.Delay(0));
                    }

                    batch  = _queue;
                    _queue = new Queue <PointData>();
                }

                if (_maxBatchSize == null || batch.Count <= _maxBatchSize.Value)
                {
                    _parent.Emit(batch.ToArray());
                }
                else
                {
                    foreach (var chunk in batch.Batch(_maxBatchSize.Value))
                    {
                        _parent.Emit(chunk.ToArray());
                    }
                }
            }
            catch (Exception ex)
            {
                CollectorLog.ReportError("Failed to emit metrics batch", ex);
            }
            finally
            {
                lock (_stateLock)
                {
                    if (!_unloading)
                    {
                        _timer.Start(_interval);
                    }
                }
            }

            return(Task.Delay(0));
        }
예제 #10
0
    public void TimerShouldThrowExceptionOnStartWithNegativeInterval()
    {
        var wasCalled = false;

        using var timer = new PortableTimer(async() => { wasCalled = true; });

        Should.Throw <ArgumentOutOfRangeException>(() => timer.Start(TimeSpan.MinValue)).ParamName
        .ShouldBe("interval");
        wasCalled.ShouldBeFalse();
    }
        void SetTimer()
        {
            // Note, called under _stateLock
            var infiniteTimespan = Timeout.InfiniteTimeSpan;

#if NO_TIMER
            _timer.Start(_connectionSchedule.NextInterval);
#else
            _timer.Change(_connectionSchedule.NextInterval, infiniteTimespan);
#endif
        }
예제 #12
0
        public void CanBeDisposedFromMultipleThreads()
        {
            PortableTimer timer = null;

            timer = new PortableTimer(async _ => timer.Start(TimeSpan.FromMilliseconds(1)));

            timer.Start(TimeSpan.Zero);
            Thread.Sleep(50);

            Parallel.For(0, Environment.ProcessorCount * 2, _ => timer.Dispose());
        }
예제 #13
0
        public void CanBeDisposedFromMultipleThreads()
        {
            PortableTimer timer = null;

            // ReSharper disable once PossibleNullReferenceException
            timer = new PortableTimer(async _ => timer.Start(TimeSpan.FromMilliseconds(1)));

            timer.Start(TimeSpan.Zero);
            Thread.Sleep(50);

            Parallel.For(0, Environment.ProcessorCount * 2, _ => timer.Dispose());
        }
예제 #14
0
        public void WhenWaitingShouldCancel_OnDispose()
        {
            var wasCalled        = false;
            var writtenToSelfLog = false;

            SelfLog.Enable(_ => writtenToSelfLog = true);

            using (var timer = new PortableTimer(async delegate { await Task.Delay(50); wasCalled = true; }))
            {
                timer.Start(TimeSpan.FromMilliseconds(20));
            }

            Thread.Sleep(100);

            Assert.False(wasCalled, "tick handler was called");
            Assert.False(writtenToSelfLog, "message was written to SelfLog");
        }
예제 #15
0
    public void TimerShouldNotProcessEventWhenWaiting()
    {
        var wasCalled = false;

        using (var timer = new PortableTimer(async() =>
        {
            await Task.Delay(50);
            wasCalled = true;
        }))
        {
            timer.Start(TimeSpan.FromMilliseconds(20));
        }

        Thread.Sleep(100);

        wasCalled.ShouldBeFalse();
    }
예제 #16
0
    public void TimerShouldWaitUntilEventHandlerOnDispose()
    {
        var wasCalled = false;
        var barrier   = new Barrier(2);

        using (var timer = new PortableTimer(async() =>
        {
            barrier.SignalAndWait();
            await Task.Delay(100);
            wasCalled = true;
        }))
        {
            timer.Start(TimeSpan.Zero);
            barrier.SignalAndWait();
        }

        wasCalled.ShouldBeTrue();
    }
예제 #17
0
        public void WhenItStartsItWaitsUntilHandled_OnDispose()
        {
            var wasCalled = false;

            var barrier = new Barrier(participantCount: 2);

            using (var timer = new PortableTimer(
                       async delegate
            {
                barrier.SignalAndWait();
                await Task.Delay(100);
                wasCalled = true;
            }))
            {
                timer.Start(TimeSpan.Zero);
                barrier.SignalAndWait();
            }

            Assert.True(wasCalled);
        }
예제 #18
0
    public void EventShouldBeProcessedOneAtTimeWhenOverlaps()
    {
        var userHandlerOverlapped = false;

        // ReSharper disable AccessToModifiedClosure
        PortableTimer timer = null !;

        timer = new PortableTimer(
            async() =>
        {
            if (Monitor.TryEnter(timer !))
            {
                try
                {
                    // ReSharper disable once PossibleNullReferenceException
                    timer.Start(TimeSpan.Zero);
                    Thread.Sleep(20);
                }
                finally
                {
                    Monitor.Exit(timer);
                }
            }
예제 #19
0
 private void SetTimer()
 {
     // Note, called under stateLock
     timer.Start(connectionSchedule.NextInterval);
 }
예제 #20
0
 void SetTimer()
 {
     // Note, called under _stateLock
     _timer.Start(_connectionSchedule.NextInterval);
 }