/// <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); }
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(); }
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()); }
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"); }
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(); }
// Handlers private void MainPage_Loaded(object sender, RoutedEventArgs e) { lock (_syncRoot) { // Require if (_operateTimer != null) return; // Begin _operateTimer = new PortableTimer(this.Timer_Ticked, 500); } }
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)); }
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()); }
private void MainPage_Unloaded(object sender, RoutedEventArgs e) { lock (_syncRoot) { // Require if (_operateTimer == null) return; // End _operateTimer.Dispose(); _operateTimer = null; } }
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()); }
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); }
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"); }
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(); }
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(); }
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(); }
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); }
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(); }