BoundedSequenceLog Pennington.Tui
Thread-safe bounded queue of sequence-tagged entries. Producers run on arbitrary threads (Kestrel workers, the ILogger pipeline); the TUI drains new rows each tick on the terminal thread by tracking the last-seen sequence. Trims the oldest when capacity is exceeded; the minimum floor of 50 keeps the dashboard from rendering empty on a busy page even if a caller passes 0.
Constructors
.ctor
#public sealed class BoundedSequenceLog<T>(int capacity)
{
private readonly ConcurrentQueue<T> _entries = new();
private readonly int _capacity = Math.Max(50, capacity);
private long _sequence;
/// <summary>Assign the next sequence id, hand it to <paramref name="factory"/>, and enqueue the result.</summary>
public void Append(Func<long, T> factory)
{
var seq = Interlocked.Increment(ref _sequence);
_entries.Enqueue(factory(seq));
while (_entries.Count > _capacity && _entries.TryDequeue(out _)) { }
}
/// <summary>Snapshot of current entries, oldest first.</summary>
public IReadOnlyList<T> Snapshot() => [.. _entries];
}Thread-safe bounded queue of sequence-tagged entries. Producers run on arbitrary threads (Kestrel workers, the ILogger pipeline); the TUI drains new rows each tick on the terminal thread by tracking the last-seen sequence. Trims the oldest when capacity is exceeded; the minimum floor of 50 keeps the dashboard from rendering empty on a busy page even if a caller passes 0.
Parameters
capacityint
Methods
Pennington.Tui.BoundedSequenceLog
namespace Pennington.Tui;
/// Thread-safe bounded queue of sequence-tagged entries. Producers run on arbitrary threads (Kestrel workers, the ILogger pipeline); the TUI drains new rows each tick on the terminal thread by tracking the last-seen sequence. Trims the oldest when capacity is exceeded; the minimum floor of 50 keeps the dashboard from rendering empty on a busy page even if a caller passes 0.
public class BoundedSequenceLog
{
/// Thread-safe bounded queue of sequence-tagged entries. Producers run on arbitrary threads (Kestrel workers, the ILogger pipeline); the TUI drains new rows each tick on the terminal thread by tracking the last-seen sequence. Trims the oldest when capacity is exceeded; the minimum floor of 50 keeps the dashboard from rendering empty on a busy page even if a caller passes 0.
public sealed class BoundedSequenceLog<T>(int capacity)
{
private readonly ConcurrentQueue<T> _entries = new();
private readonly int _capacity = Math.Max(50, capacity);
private long _sequence;
/// <summary>Assign the next sequence id, hand it to <paramref name="factory"/>, and enqueue the result.</summary>
public void Append(Func<long, T> factory)
{
var seq = Interlocked.Increment(ref _sequence);
_entries.Enqueue(factory(seq));
while (_entries.Count > _capacity && _entries.TryDequeue(out _)) { }
}
/// <summary>Snapshot of current entries, oldest first.</summary>
public IReadOnlyList<T> Snapshot() => [.. _entries];
}
/// Assign the next sequence id, hand it to factory, and enqueue the result.
public void Append(Func<long, T> factory);
/// Snapshot of current entries, oldest first.
public IReadOnlyList<T> Snapshot();
}