Skip to content

Commit 7af8c3c

Browse files
committed
Wait for go routines to finish before cancelling the context
1 parent f8d98a4 commit 7af8c3c

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

picker_wrapper_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package grpc
2121
import (
2222
"context"
2323
"fmt"
24+
"sync"
2425
"sync/atomic"
2526
"testing"
2627
"time"
@@ -80,19 +81,24 @@ func (s) TestBlockingPick(t *testing.T) {
8081
var finishedCount uint64
8182
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
8283
defer cancel()
84+
wg := sync.WaitGroup{}
85+
wg.Add(goroutineCount)
8386
for i := goroutineCount; i > 0; i-- {
8487
go func() {
8588
if tr, _, err := bp.pick(ctx, true, balancer.PickInfo{}); err != nil || tr != testT {
8689
t.Errorf("bp.pick returned non-nil error: %v", err)
8790
}
8891
atomic.AddUint64(&finishedCount, 1)
92+
wg.Done()
8993
}()
9094
}
9195
time.Sleep(50 * time.Millisecond)
9296
if c := atomic.LoadUint64(&finishedCount); c != 0 {
9397
t.Errorf("finished goroutines count: %v, want 0", c)
9498
}
9599
bp.updatePicker(&testingPicker{sc: testSC, maxCalled: goroutineCount})
100+
// Wait for all pickers to finish before the context is cancelled.
101+
wg.Wait()
96102
}
97103

98104
func (s) TestBlockingPickNoSubAvailable(t *testing.T) {
@@ -102,19 +108,24 @@ func (s) TestBlockingPickNoSubAvailable(t *testing.T) {
102108
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
103109
defer cancel()
104110
// All goroutines should block because picker returns no subConn available.
111+
wg := sync.WaitGroup{}
112+
wg.Add(goroutineCount)
105113
for i := goroutineCount; i > 0; i-- {
106114
go func() {
107115
if tr, _, err := bp.pick(ctx, true, balancer.PickInfo{}); err != nil || tr != testT {
108116
t.Errorf("bp.pick returned non-nil error: %v", err)
109117
}
110118
atomic.AddUint64(&finishedCount, 1)
119+
wg.Done()
111120
}()
112121
}
113122
time.Sleep(50 * time.Millisecond)
114123
if c := atomic.LoadUint64(&finishedCount); c != 0 {
115124
t.Errorf("finished goroutines count: %v, want 0", c)
116125
}
117126
bp.updatePicker(&testingPicker{sc: testSC, maxCalled: goroutineCount})
127+
// Wait for all pickers to finish before the context is cancelled.
128+
wg.Wait()
118129
}
119130

120131
func (s) TestBlockingPickTransientWaitforready(t *testing.T) {
@@ -125,19 +136,24 @@ func (s) TestBlockingPickTransientWaitforready(t *testing.T) {
125136
defer cancel()
126137
// All goroutines should block because picker returns transientFailure and
127138
// picks are not failfast.
139+
wg := sync.WaitGroup{}
140+
wg.Add(goroutineCount)
128141
for i := goroutineCount; i > 0; i-- {
129142
go func() {
130143
if tr, _, err := bp.pick(ctx, false, balancer.PickInfo{}); err != nil || tr != testT {
131144
t.Errorf("bp.pick returned non-nil error: %v", err)
132145
}
133146
atomic.AddUint64(&finishedCount, 1)
147+
wg.Done()
134148
}()
135149
}
136150
time.Sleep(time.Millisecond)
137151
if c := atomic.LoadUint64(&finishedCount); c != 0 {
138152
t.Errorf("finished goroutines count: %v, want 0", c)
139153
}
140154
bp.updatePicker(&testingPicker{sc: testSC, maxCalled: goroutineCount})
155+
// Wait for all pickers to finish before the context is cancelled.
156+
wg.Wait()
141157
}
142158

143159
func (s) TestBlockingPickSCNotReady(t *testing.T) {
@@ -147,17 +163,22 @@ func (s) TestBlockingPickSCNotReady(t *testing.T) {
147163
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
148164
defer cancel()
149165
// All goroutines should block because subConn is not ready.
166+
wg := sync.WaitGroup{}
167+
wg.Add(goroutineCount)
150168
for i := goroutineCount; i > 0; i-- {
151169
go func() {
152170
if tr, _, err := bp.pick(ctx, true, balancer.PickInfo{}); err != nil || tr != testT {
153171
t.Errorf("bp.pick returned non-nil error: %v", err)
154172
}
155173
atomic.AddUint64(&finishedCount, 1)
174+
wg.Done()
156175
}()
157176
}
158177
time.Sleep(time.Millisecond)
159178
if c := atomic.LoadUint64(&finishedCount); c != 0 {
160179
t.Errorf("finished goroutines count: %v, want 0", c)
161180
}
162181
bp.updatePicker(&testingPicker{sc: testSC, maxCalled: goroutineCount})
182+
// Wait for all pickers to finish before the context is cancelled.
183+
wg.Wait()
163184
}

0 commit comments

Comments
 (0)