Skip to content

Commit 4a5edf1

Browse files
authored
perf: Replace channel check with atomic bool in tailer.send() (#12976)
1 parent e7fdeb9 commit 4a5edf1

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

pkg/ingester/tailer.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/binary"
55
"hash/fnv"
66
"sync"
7+
"sync/atomic"
78
"time"
89

910
"github.com/go-kit/log/level"
@@ -46,6 +47,7 @@ type tailer struct {
4647
// and the loop and senders should stop
4748
closeChan chan struct{}
4849
closeOnce sync.Once
50+
closed atomic.Bool
4951

5052
blockedAt *time.Time
5153
blockedMtx sync.RWMutex
@@ -74,6 +76,7 @@ func newTailer(orgID string, expr syntax.LogSelectorExpr, conn TailServer, maxDr
7476
maxDroppedStreams: maxDroppedStreams,
7577
id: generateUniqueID(orgID, expr.String()),
7678
closeChan: make(chan struct{}),
79+
closed: atomic.Bool{},
7780
pipeline: pipeline,
7881
}, nil
7982
}
@@ -227,17 +230,13 @@ func isMatching(lbs labels.Labels, matchers []*labels.Matcher) bool {
227230
}
228231

229232
func (t *tailer) isClosed() bool {
230-
select {
231-
case <-t.closeChan:
232-
return true
233-
default:
234-
return false
235-
}
233+
return t.closed.Load()
236234
}
237235

238236
func (t *tailer) close() {
239237
t.closeOnce.Do(func() {
240-
// Signal the close channel
238+
// Signal the close channel & flip the atomic bool so tailers will exit
239+
t.closed.Store(true)
241240
close(t.closeChan)
242241

243242
// We intentionally do not close sendChan in order to avoid a panic on

pkg/ingester/tailer_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
)
1818

1919
func TestTailer_RoundTrip(t *testing.T) {
20+
t.Parallel()
2021
server := &fakeTailServer{}
2122

2223
lbs := makeRandomLabels()
@@ -66,6 +67,7 @@ func TestTailer_RoundTrip(t *testing.T) {
6667
}
6768

6869
func TestTailer_sendRaceConditionOnSendWhileClosing(t *testing.T) {
70+
t.Parallel()
6971
runs := 100
7072

7173
stream := logproto.Stream{
@@ -103,6 +105,7 @@ func TestTailer_sendRaceConditionOnSendWhileClosing(t *testing.T) {
103105
}
104106

105107
func Test_dropstream(t *testing.T) {
108+
t.Parallel()
106109
maxDroppedStreams := 10
107110

108111
entry := logproto.Entry{Timestamp: time.Now(), Line: "foo"}
@@ -224,6 +227,7 @@ func Test_TailerSendRace(t *testing.T) {
224227
}
225228

226229
func Test_IsMatching(t *testing.T) {
230+
t.Parallel()
227231
for _, tt := range []struct {
228232
name string
229233
lbs labels.Labels
@@ -241,6 +245,7 @@ func Test_IsMatching(t *testing.T) {
241245
}
242246

243247
func Test_StructuredMetadata(t *testing.T) {
248+
t.Parallel()
244249
lbs := makeRandomLabels()
245250

246251
for _, tc := range []struct {
@@ -364,3 +369,21 @@ func Test_StructuredMetadata(t *testing.T) {
364369
})
365370
}
366371
}
372+
373+
func Benchmark_isClosed(t *testing.B) {
374+
var server fakeTailServer
375+
expr, err := syntax.ParseLogSelector(`{app="foo"}`, true)
376+
require.NoError(t, err)
377+
tail, err := newTailer("foo", expr, &server, 0)
378+
require.NoError(t, err)
379+
380+
require.Equal(t, false, tail.isClosed())
381+
382+
t.ResetTimer()
383+
for i := 0; i < t.N; i++ {
384+
tail.isClosed()
385+
}
386+
387+
tail.close()
388+
require.Equal(t, true, tail.isClosed())
389+
}

0 commit comments

Comments
 (0)