/// <summary>
 /// Construct a sink posting to the specified database.
 /// </summary>
 /// <param name="batchSizeLimit">The maximum number of events to include in a single batch.</param>
 /// <param name="period">The time to wait between checking for event batches.</param>
 protected PortablePeriodicBatchingSink(int batchSizeLimit, TimeSpan period)
 {
     _batchSizeLimit = batchSizeLimit;
     _queue = new Queue<LogEvent>();
     _timer = new PortableTimer(cancel => OnTick());
     _status = new PortableBatchedConnectionStatus(period);
 }
Example #2
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");
        }
        public HttpLogShipper(
            string serverUrl,
            string bufferBaseFilename,
            string apiKey,
            int batchPostingLimit,
            TimeSpan period,
            long?eventBodyLimitBytes,
            LoggingLevelSwitch levelControlSwitch,
            HttpMessageHandler messageHandler,
            long?retainedInvalidPayloadsLimitBytes,
            long?bufferSizeLimitBytes)
        {
            _apiKey              = apiKey;
            _batchPostingLimit   = batchPostingLimit;
            _eventBodyLimitBytes = eventBodyLimitBytes;
            _controlledSwitch    = new ControlledLevelSwitch(levelControlSwitch);
            _connectionSchedule  = new ExponentialBackoffConnectionSchedule(period);
            _retainedInvalidPayloadsLimitBytes = retainedInvalidPayloadsLimitBytes;
            _bufferSizeLimitBytes   = bufferSizeLimitBytes;
            _httpClient             = messageHandler != null ? new HttpClient(messageHandler) : new HttpClient();
            _httpClient.BaseAddress = new Uri(SeqApi.NormalizeServerBaseAddress(serverUrl));
            _fileSet = new FileSet(bufferBaseFilename);
            _timer   = new PortableTimer(c => OnTick());

            SetTimer();
        }
Example #4
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);
        }
        public HttpLogShipper(
            IHttpClient client,
            string requestUri,
            string bufferBaseFilename,
            int batchPostingLimit,
            TimeSpan period,
            IBatchFormatter batchFormatter)
        {
            if (bufferBaseFilename == null)
            {
                throw new ArgumentNullException(nameof(bufferBaseFilename));
            }
            if (batchPostingLimit <= 0)
            {
                throw new ArgumentException("batchPostingLimit must be 1 or greater", nameof(batchPostingLimit));
            }

            this.client            = client ?? throw new ArgumentNullException(nameof(client));
            this.requestUri        = requestUri ?? throw new ArgumentNullException(nameof(requestUri));
            this.batchPostingLimit = batchPostingLimit;
            this.batchFormatter    = batchFormatter ?? throw new ArgumentNullException(nameof(batchFormatter));

            bookmarkFilename    = Path.GetFullPath(bufferBaseFilename + ".bookmark");
            logFolder           = Path.GetDirectoryName(bookmarkFilename);
            candidateSearchPath = Path.GetFileName(bufferBaseFilename) + "*.json";
            connectionSchedule  = new ExponentialBackoffConnectionSchedule(period);
            timer = new PortableTimer(OnTick);

            SetTimer();
        }
 public IntervalBatcher(TimeSpan interval, int?maxBatchSize, IPointEmitter parent)
 {
     _parent       = parent;
     _interval     = interval;
     _maxBatchSize = maxBatchSize;
     _timer        = new PortableTimer(cancel => OnTick());
 }
Example #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");
        }
Example #8
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();
    }
Example #9
0
        // Handlers
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            lock (_syncRoot)
            {
                // Require
                if (_operateTimer != null) return;

                // Begin
                _operateTimer = new PortableTimer(this.Timer_Ticked, 500);
            }
        }
Example #10
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));
        }
Example #11
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());
        }
Example #12
0
        private void MainPage_Unloaded(object sender, RoutedEventArgs e)
        {
            lock (_syncRoot)
            {
                // Require
                if (_operateTimer == null) return;

                // End
                _operateTimer.Dispose();
                _operateTimer = null;
            }
        }
Example #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());
        }
Example #14
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));
    }
        protected BatchReporterBase(BatchReporterOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            options.Validate();

            _options = options;
            _status  = new TimerStatus(options.FlushInterval, options.MinBackoffPeriod, options.MaxBackoffPeriod);
            _timer   = new PortableTimer(_ => OnTick(), OnError);
        }
Example #16
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");
        }
Example #17
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();
    }
        internal ElasticsearchLogShipper(ElasticsearchSinkState state)
        {
            _state = state;
            _connectionSchedule = new ExponentialBackoffConnectionSchedule(_state.Options.BufferLogShippingInterval ?? TimeSpan.FromSeconds(5));

            _batchPostingLimit   = _state.Options.BatchPostingLimit;
            _bookmarkFilename    = Path.GetFullPath(_state.Options.BufferBaseFilename + ".bookmark");
            _logFolder           = Path.GetDirectoryName(_bookmarkFilename);
            _candidateSearchPath = Path.GetFileName(_state.Options.BufferBaseFilename) + "*.json";

#if NO_TIMER
            _timer = new PortableTimer(cancel => OnTick());
#else
            _timer = new Timer(s => OnTick(), null, -1, -1);
#endif
            SetTimer();
        }
Example #19
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();
    }
Example #20
0
        public HttpLogShipper(
            IHttpClient client,
            string requestUri,
            string bufferPathFormat,
            int batchPostingLimit,
            TimeSpan period,
            IBatchFormatter batchFormatter)
        {
            if (bufferPathFormat == null)
            {
                throw new ArgumentNullException(nameof(bufferPathFormat));
            }
            if (bufferPathFormat != bufferPathFormat.Trim())
            {
                throw new ArgumentException("bufferPathFormat must not contain any leading or trailing whitespaces", nameof(bufferPathFormat));
            }
            if (batchPostingLimit <= 0)
            {
                throw new ArgumentException("batchPostingLimit must be 1 or greater", nameof(batchPostingLimit));
            }

            this.client            = client ?? throw new ArgumentNullException(nameof(client));
            this.requestUri        = requestUri ?? throw new ArgumentNullException(nameof(requestUri));
            this.batchPostingLimit = batchPostingLimit;
            this.batchFormatter    = batchFormatter ?? throw new ArgumentNullException(nameof(batchFormatter));

            var bufferPathFormatMatch = BufferPathFormatRegex.Match(bufferPathFormat);

            if (!bufferPathFormatMatch.Success)
            {
                throw new ArgumentException($"bufferPathFormat must include one of the date formats [{string.Join(", ", Enum.GetNames(typeof(DateFormats)))}]");
            }

            var prefix  = bufferPathFormatMatch.Groups["prefix"];
            var postfix = bufferPathFormatMatch.Groups["postfix"];

            bookmarkFilename    = Path.GetFullPath(prefix.Value.TrimEnd(new char[] { '-' }) + ".bookmark");
            logFolder           = Path.GetDirectoryName(bookmarkFilename);
            candidateSearchPath = $"{Path.GetFileName(prefix.Value)}*{postfix.Value}";
            connectionSchedule  = new ExponentialBackoffConnectionSchedule(period);
            timer = new PortableTimer(OnTick);

            SetTimer();
        }
Example #21
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);
        }
Example #22
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);
                }
            }
        public HttpLogShipper(
            IHttpClient client,
            string requestUri,
            IBufferFiles bufferFiles,
            int batchPostingLimit,
            TimeSpan period,
            IBatchFormatter batchFormatter)
        {
            if (batchPostingLimit <= 0)
            {
                throw new ArgumentException("batchPostingLimit must be 1 or greater", nameof(batchPostingLimit));
            }

            this.client            = client ?? throw new ArgumentNullException(nameof(client));
            this.requestUri        = requestUri ?? throw new ArgumentNullException(nameof(requestUri));
            this.bufferFiles       = bufferFiles ?? throw new ArgumentNullException(nameof(bufferFiles));
            this.batchPostingLimit = batchPostingLimit;
            this.batchFormatter    = batchFormatter ?? throw new ArgumentNullException(nameof(batchFormatter));

            connectionSchedule = new ExponentialBackoffConnectionSchedule(period);
            timer = new PortableTimer(OnTick);

            SetTimer();
        }