/// <summary> /// Sends the log entry: creates the sender if necessary and manages the buffer. /// </summary> /// <param name="monitor">The monitor to use.</param> /// <param name="logEvent">The log entry to send.</param> /// <returns>The awaitable.</returns> /// <exception cref="CKException"> /// If the sender has not been created yet and the application identity is ready /// but CreateSenderAsync returned null: the exception will remove this handler from the sink's handler list. /// </exception> public virtual async ValueTask HandleAsync(IActivityMonitor monitor, IMulticastLogEntry logEvent) { if (_sender == null && SenderCanBeCreated) { _sender = await CreateSenderAsync(monitor); if (_sender == null) { throw new CKException($"Unable to create the sender."); } } if (_sender != null) { if (_buffer.Count > 0) { while (_buffer.Count > 0) { if (!_sender.IsActuallyConnected || !await _sender.TrySendAsync(monitor, _buffer.Peek())) { _buffer.Push(logEvent); return; } _buffer.Pop(); } } if (!_sender.IsActuallyConnected || !await _sender.TrySendAsync(monitor, logEvent)) { _buffer.Push(logEvent); } else if (!_firstSuccess) { _firstSuccess = true; if (_buffer.Capacity != _config.LostBufferSize) { monitor.Info($"Successfully sent the first logs: resizing buffer from '{_buffer.Capacity}' to '{_config.LostBufferSize}'."); _buffer.Capacity = _config.LostBufferSize; } } } else { _buffer.Push(logEvent); } }
public void FIFO_supports_Peek_and_PeekLast() { FIFOBuffer <int> f = new FIFOBuffer <int>(0); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[-1])); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[0])); Assert.Throws <InvalidOperationException>(() => f.Peek()); Assert.Throws <InvalidOperationException>(() => f.PeekLast()); f.Push(5); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[0])); Assert.Throws <InvalidOperationException>(() => f.Peek()); Assert.Throws <InvalidOperationException>(() => f.PeekLast()); f.Capacity = 1; TestWithInternalOffsets(f, b => { b.Push(5); Assert.That(b[0], Is.EqualTo(5)); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.That(b.Peek(), Is.EqualTo(5)); Assert.That(b.PeekLast(), Is.EqualTo(5)); b.Push(6); Assert.That(b[0], Is.EqualTo(6), "Only one item in it."); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.That(b.Peek(), Is.EqualTo(6)); Assert.That(b.PeekLast(), Is.EqualTo(6)); }); f.Clear(); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[0])); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[1])); Assert.Throws <InvalidOperationException>(() => f.Peek()); Assert.Throws <InvalidOperationException>(() => f.PeekLast()); f.Capacity = 2; TestWithInternalOffsets(f, b => { b.Push(5); Assert.That(b[0], Is.EqualTo(5)); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.That(b.Peek(), Is.EqualTo(5)); Assert.That(b.PeekLast(), Is.EqualTo(5)); b.Push(6); Assert.That(b[0], Is.EqualTo(5)); Assert.That(b[1], Is.EqualTo(6)); Assert.That(b.Peek(), Is.EqualTo(5)); Assert.That(b.PeekLast(), Is.EqualTo(6)); b.Pop(); Assert.That(b[0], Is.EqualTo(6)); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.That(b.Peek(), Is.EqualTo(6)); Assert.That(b.PeekLast(), Is.EqualTo(6)); b.Pop(); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[0])); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(b[1])); Assert.Throws <InvalidOperationException>(() => b.Peek()); Assert.Throws <InvalidOperationException>(() => b.PeekLast()); b.Push(7); b.Push(8); b.Push(9); Assert.That(b[0], Is.EqualTo(8)); Assert.That(b[1], Is.EqualTo(9)); CollectionAssert.AreEqual(b.ToArray(), new int[] { 8, 9 }); Assert.That(b.Peek(), Is.EqualTo(8)); Assert.That(b.PeekLast(), Is.EqualTo(9)); Assert.That(b.Pop(), Is.EqualTo(8)); Assert.That(b.Pop(), Is.EqualTo(9)); AssertEmpty(b); b.Push(10); b.Push(11); b.Push(12); Assert.That(b[0], Is.EqualTo(11)); Assert.That(b[1], Is.EqualTo(12)); Assert.That(b.Peek(), Is.EqualTo(11)); Assert.That(b.PeekLast(), Is.EqualTo(12)); Assert.That(b.PopLast(), Is.EqualTo(12)); Assert.That(b.Peek(), Is.EqualTo(11)); Assert.That(b.PeekLast(), Is.EqualTo(11)); Assert.That(b.PopLast(), Is.EqualTo(11)); AssertEmpty(b); }); f.Capacity = 3; TestWithInternalOffsets(f, b => { b.Push(11); b.Push(12); b.Push(13); Assert.That(b[0], Is.EqualTo(11)); Assert.That(b[1], Is.EqualTo(12)); Assert.That(b[2], Is.EqualTo(13)); }); f.Capacity = 4; f.Push(11); f.Push(12); f.Push(13); TestWithInternalOffsets(f, b => { b.Push(14); Assert.That(b[0], Is.EqualTo(11)); Assert.That(b[1], Is.EqualTo(12)); Assert.That(b[2], Is.EqualTo(13)); Assert.That(b[3], Is.EqualTo(14)); b.Push(15); Assert.That(b[0], Is.EqualTo(12)); Assert.That(b[1], Is.EqualTo(13)); Assert.That(b[2], Is.EqualTo(14)); Assert.That(b[3], Is.EqualTo(15)); b.Push(16); Assert.That(b[0], Is.EqualTo(13)); Assert.That(b[1], Is.EqualTo(14)); Assert.That(b[2], Is.EqualTo(15)); Assert.That(b[3], Is.EqualTo(16)); }); f.Capacity = 5; AssertContains(f, 11, 12, 13); TestWithInternalOffsets(f, b => { b.Push(14); b.Push(15); b.Push(16); b.Push(17); Assert.That(b[0], Is.EqualTo(13)); Assert.That(b[1], Is.EqualTo(14)); Assert.That(b[2], Is.EqualTo(15)); Assert.That(b[3], Is.EqualTo(16)); Assert.That(b[4], Is.EqualTo(17)); Assert.Throws <IndexOutOfRangeException>(() => Console.Write(f[5])); }); }