Skip to content

Commit 4901a5c

Browse files
fix: not owned stream count (#13030)
Signed-off-by: Vladyslav Diachenko <[email protected]>
1 parent 8101e21 commit 4901a5c

File tree

3 files changed

+57
-12
lines changed

3 files changed

+57
-12
lines changed

pkg/ingester/limiter_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func TestStreamCountLimiter_AssertNewStreamAllowed(t *testing.T) {
2424
expected error
2525
useOwnedStreamService bool
2626
fixedLimit int32
27-
ownedStreamCount int64
27+
ownedStreamCount int
2828
}{
2929
"both local and global limit are disabled": {
3030
maxLocalStreamsPerUser: 0,
@@ -147,7 +147,7 @@ func TestStreamCountLimiter_AssertNewStreamAllowed(t *testing.T) {
147147

148148
ownedStreamSvc := &ownedStreamService{
149149
fixedLimit: atomic.NewInt32(testData.fixedLimit),
150-
ownedStreamCount: atomic.NewInt64(testData.ownedStreamCount),
150+
ownedStreamCount: testData.ownedStreamCount,
151151
}
152152
limiter := NewLimiter(limits, NilMetrics, ring, testData.ringReplicationFactor)
153153
defaultCountSupplier := func() int {

pkg/ingester/owned_streams.go

+24-9
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,36 @@
11
package ingester
22

3-
import "go.uber.org/atomic"
3+
import (
4+
"sync"
5+
6+
"go.uber.org/atomic"
7+
)
48

59
type ownedStreamService struct {
610
tenantID string
711
limiter *Limiter
812
fixedLimit *atomic.Int32
913

1014
//todo: implement job to recalculate it
11-
ownedStreamCount *atomic.Int64
15+
ownedStreamCount int
16+
notOwnedStreamCount int
17+
lock sync.RWMutex
1218
}
1319

1420
func newOwnedStreamService(tenantID string, limiter *Limiter) *ownedStreamService {
1521
svc := &ownedStreamService{
16-
tenantID: tenantID,
17-
limiter: limiter,
18-
ownedStreamCount: atomic.NewInt64(0),
19-
fixedLimit: atomic.NewInt32(0),
22+
tenantID: tenantID,
23+
limiter: limiter,
24+
fixedLimit: atomic.NewInt32(0),
2025
}
2126
svc.updateFixedLimit()
2227
return svc
2328
}
2429

2530
func (s *ownedStreamService) getOwnedStreamCount() int {
26-
return int(s.ownedStreamCount.Load())
31+
s.lock.RLock()
32+
defer s.lock.RUnlock()
33+
return s.ownedStreamCount
2734
}
2835

2936
func (s *ownedStreamService) updateFixedLimit() {
@@ -36,9 +43,17 @@ func (s *ownedStreamService) getFixedLimit() int {
3643
}
3744

3845
func (s *ownedStreamService) incOwnedStreamCount() {
39-
s.ownedStreamCount.Inc()
46+
s.lock.Lock()
47+
defer s.lock.Unlock()
48+
s.ownedStreamCount++
4049
}
4150

4251
func (s *ownedStreamService) decOwnedStreamCount() {
43-
s.ownedStreamCount.Dec()
52+
s.lock.Lock()
53+
defer s.lock.Unlock()
54+
if s.notOwnedStreamCount > 0 {
55+
s.notOwnedStreamCount--
56+
return
57+
}
58+
s.ownedStreamCount--
4459
}

pkg/ingester/owned_streams_test.go

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ingester
22

33
import (
4+
"sync"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -29,8 +30,37 @@ func Test_OwnedStreamService(t *testing.T) {
2930

3031
service.incOwnedStreamCount()
3132
service.incOwnedStreamCount()
32-
require.Equal(t, 2, service.getOwnedStreamCount())
33+
service.incOwnedStreamCount()
34+
require.Equal(t, 3, service.getOwnedStreamCount())
35+
36+
// simulate the effect from the recalculation job
37+
service.notOwnedStreamCount = 1
38+
service.ownedStreamCount = 2
39+
40+
service.decOwnedStreamCount()
41+
require.Equal(t, 2, service.getOwnedStreamCount(), "owned stream count must be decremented only when notOwnedStreamCount is set to 0")
42+
require.Equal(t, 0, service.notOwnedStreamCount)
3343

3444
service.decOwnedStreamCount()
3545
require.Equal(t, 1, service.getOwnedStreamCount())
46+
require.Equal(t, 0, service.notOwnedStreamCount, "notOwnedStreamCount must not be decremented lower than 0")
47+
48+
group := sync.WaitGroup{}
49+
group.Add(200)
50+
for i := 0; i < 100; i++ {
51+
go func() {
52+
defer group.Done()
53+
service.incOwnedStreamCount()
54+
}()
55+
}
56+
57+
for i := 0; i < 100; i++ {
58+
go func() {
59+
defer group.Done()
60+
service.decOwnedStreamCount()
61+
}()
62+
}
63+
group.Wait()
64+
65+
require.Equal(t, 1, service.getOwnedStreamCount(), "owned stream count must not be changed")
3666
}

0 commit comments

Comments
 (0)