more code

This commit is contained in:
developer committed 2026-09-27 11:34:26 +00:00
1 parent f24fd63e9a
commit ee72257c64
29 files changed
+5636 -440

No files matched your search

+16 -6
View File
@@ -90,8 +90,11 @@ type Logger struct {
// seq assigns monotonic ids so the UI can detect drops.
seq atomic.Uint64
// live is a fixed-size ring of the most recent entries.
live []liveEntry
// live is a fixed-size ring of the most recent entries. Each slot is a
// pointer, so a writer on the query path never races a reader walking the
// ring: publishing is one atomic word, and a reader sees either the whole
// entry or the one it replaced.
live []atomic.Pointer[liveEntry]
livePos atomic.Uint32
liveMu sync.RWMutex
liveCond *sync.Cond
@@ -184,7 +187,7 @@ func New(opt Options) (*Logger, error) {
}
l := &Logger{
opts: opt,
live: make([]liveEntry, opt.LiveBuffer),
live: make([]atomic.Pointer[liveEntry], opt.LiveBuffer),
counts: newDomainCounts(opt.TopDomains, opt.TopTTL),
subs: make(map[int]chan Entry),
stop: make(chan struct{}),
@@ -258,9 +261,11 @@ func (l *Logger) Log(e Entry) {
e.ID = l.seq.Add(1)
l.counts.observe(e)
// Live ring.
// Live ring. The slot is published with a single atomic store; a reader
// walking the ring concurrently gets either the old or the new entry,
// never a half-written one.
pos := l.livePos.Add(1) - 1
l.live[pos%uint32(len(l.live))] = liveEntry{entry: e}
l.live[pos%uint32(len(l.live))].Store(&liveEntry{entry: e})
// Fan out to SSE subscribers (non-blocking: a slow consumer drops entries
// rather than stalling the query path).
@@ -435,7 +440,12 @@ func (l *Logger) Recent(limit int) []Entry {
}
for i := uint32(0); i < total; i++ {
idx := (pos - 1 - i) % uint32(len(l.live))
out = append(out, l.live[idx].entry)
le := l.live[idx].Load()
if le == nil {
// Never written (or already aged out of the window).
continue
}
out = append(out, le.entry)
if len(out) >= limit {
break
}