fix: don't hold stripe lock during i/o

Signed-off-by: x1unix <9203548+x1unix@users.noreply.github.com>
This commit is contained in:
x1unix 2026-03-19 15:38:36 -04:00
parent 687f3021d4
commit c8109f607a
No known key found for this signature in database
GPG key ID: 9A37F16B8645A398

View file

@ -347,14 +347,20 @@ func (s *seriesSnapshot) LastSampleTimestamp() int64 {
func (s *stripeSeries) Iterate() iter.Seq[ActiveSeries] {
return func(yield func(ActiveSeries) bool) {
stop := false
var buf []*memSeries
for i := 0; i < s.size; i++ {
// Collect pointers under RLock to avoid blocking appenders during I/O.
s.locks[i].RLock()
buf = buf[:0]
for _, series := range s.series[i] {
// Copy fields under the series lock, then release it
// before yielding so that disk I/O in the consumer
// does not block appends to this series.
buf = append(buf, series)
}
s.locks[i].RUnlock()
// Snapshot and yield outside the stripe lock so that
// slow consumers (e.g. checkpoint disk I/O) do not
// block appends that need a write lock on this stripe.
for _, series := range buf {
series.Lock()
snapshot := seriesSnapshot{
ref: series.ref,
@ -364,15 +370,9 @@ func (s *stripeSeries) Iterate() iter.Seq[ActiveSeries] {
series.Unlock()
if !yield(&snapshot) {
stop = true
break
return
}
}
s.locks[i].RUnlock()
if stop {
return
}
}
}
}