/// <summary> /// /// </summary> /// <returns></returns> protected virtual async Task OnTick() { try { int count; do { count = 0; using (var bookmarkFile = _fileSet.OpenBookmarkFile()) { var position = bookmarkFile.TryReadBookmark(); var files = _fileSet.GetBufferFiles(); if (position.File == null || !IOFile.Exists(position.File)) { position = new FileSetPosition(0, files.FirstOrDefault()); } TPayload payload; if (position.File == null) { payload = _payloadReader.GetNoPayload(); count = 0; } else { payload = _payloadReader.ReadPayload(_batchPostingLimit, _eventBodyLimitBytes, ref position, ref count, position.File); } if (count > 0 || _controlledSwitch.IsActive && _nextRequiredLevelCheckUtc < DateTime.UtcNow) { _nextRequiredLevelCheckUtc = DateTime.UtcNow.Add(RequiredLevelCheckInterval); var result = await _logClient.SendPayloadAsync(payload).ConfigureAwait(false); if (result.Success) { _connectionSchedule.MarkSuccess(); if (result.InvalidResult != null) { DumpInvalidPayload(result.InvalidResult.StatusCode, result.InvalidResult.Content, result.InvalidResult.BadPayLoad); } bookmarkFile.WriteBookmark(position); } else { _connectionSchedule.MarkFailure(); if (_bufferSizeLimitBytes.HasValue) { _fileSet.CleanUpBufferFiles(_bufferSizeLimitBytes.Value, 2); } break; } } else if (position.File == null) { break; } else { // For whatever reason, there's nothing waiting to send. This means we should try connecting again at the // regular interval, so mark the attempt as successful. _connectionSchedule.MarkSuccess(); // Only advance the bookmark if no other process has the // current file locked, and its length is as we found it. if (files.Length == 2 && files.First() == position.File && FileIsUnlockedAndUnextended(position)) { bookmarkFile.WriteBookmark(new FileSetPosition(0, files[1])); } if (files.Length > 2) { // By this point, we expect writers to have relinquished locks // on the oldest file. IOFile.Delete(files[0]); } } } } while (count == _batchPostingLimit); } catch (Exception ex) { _connectionSchedule.MarkFailure(); SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, ex); if (_bufferSizeLimitBytes.HasValue) { _fileSet.CleanUpBufferFiles(_bufferSizeLimitBytes.Value, 2); } } finally { lock (_stateLock) { if (!_unloading) { SetTimer(); } } } }