Skip to content

Commit ae38068

Browse files
committed
bugfix: TestConnectionHandlerOpenUpdateClose data race
It is better to use atomic counters. Part of #218
1 parent 0d6e397 commit ae38068

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

connection_pool/connection_pool_test.go

+24-20
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"reflect"
88
"strings"
99
"sync"
10+
"sync/atomic"
1011
"testing"
1112
"time"
1213

@@ -235,9 +236,8 @@ func TestClose(t *testing.T) {
235236
}
236237

237238
type testHandler struct {
238-
discovered, deactivated int
239+
discovered, deactivated uint32
239240
errs []error
240-
mutex sync.Mutex
241241
}
242242

243243
func (h *testHandler) addErr(err error) {
@@ -246,10 +246,7 @@ func (h *testHandler) addErr(err error) {
246246

247247
func (h *testHandler) Discovered(conn *tarantool.Connection,
248248
role connection_pool.Role) error {
249-
h.mutex.Lock()
250-
defer h.mutex.Unlock()
251-
252-
h.discovered++
249+
discovered := atomic.AddUint32(&h.discovered, 1)
253250

254251
if conn == nil {
255252
h.addErr(fmt.Errorf("discovered conn == nil"))
@@ -260,14 +257,14 @@ func (h *testHandler) Discovered(conn *tarantool.Connection,
260257
// discovered >= 3 - update a connection after a role update
261258
addr := conn.Addr()
262259
if addr == servers[0] {
263-
if h.discovered < 3 && role != connection_pool.MasterRole {
260+
if discovered < 3 && role != connection_pool.MasterRole {
264261
h.addErr(fmt.Errorf("unexpected init role %d for addr %s", role, addr))
265262
}
266-
if h.discovered >= 3 && role != connection_pool.ReplicaRole {
263+
if discovered >= 3 && role != connection_pool.ReplicaRole {
267264
h.addErr(fmt.Errorf("unexpected updated role %d for addr %s", role, addr))
268265
}
269266
} else if addr == servers[1] {
270-
if h.discovered >= 3 {
267+
if discovered >= 3 {
271268
h.addErr(fmt.Errorf("unexpected discovery for addr %s", addr))
272269
}
273270
if role != connection_pool.ReplicaRole {
@@ -282,18 +279,15 @@ func (h *testHandler) Discovered(conn *tarantool.Connection,
282279

283280
func (h *testHandler) Deactivated(conn *tarantool.Connection,
284281
role connection_pool.Role) error {
285-
h.mutex.Lock()
286-
defer h.mutex.Unlock()
287-
288-
h.deactivated++
282+
deactivated := atomic.AddUint32(&h.deactivated, 1)
289283

290284
if conn == nil {
291285
h.addErr(fmt.Errorf("removed conn == nil"))
292286
return nil
293287
}
294288

295289
addr := conn.Addr()
296-
if h.deactivated == 1 && addr == servers[0] {
290+
if deactivated == 1 && addr == servers[0] {
297291
// A first close is a role update.
298292
if role != connection_pool.MasterRole {
299293
h.addErr(fmt.Errorf("unexpected removed role %d for addr %s", role, addr))
@@ -337,19 +331,24 @@ func TestConnectionHandlerOpenUpdateClose(t *testing.T) {
337331
for i := 0; i < 100; i++ {
338332
// Wait for read_only update, it should report about close connection
339333
// with old role.
340-
if h.discovered >= 3 {
334+
if atomic.LoadUint32(&h.discovered) >= 3 {
341335
break
342336
}
343337
time.Sleep(poolOpts.CheckTimeout)
344338
}
345-
require.Equalf(t, h.deactivated, 1, "updated not reported as deactivated")
346-
require.Equalf(t, h.discovered, 3, "updated not reported as discovered")
339+
340+
discovered := atomic.LoadUint32(&h.discovered)
341+
deactivated := atomic.LoadUint32(&h.deactivated)
342+
require.Equalf(t, uint32(3), discovered,
343+
"updated not reported as discovered")
344+
require.Equalf(t, uint32(1), deactivated,
345+
"updated not reported as deactivated")
347346

348347
pool.Close()
349348

350349
for i := 0; i < 100; i++ {
351350
// Wait for close of all connections.
352-
if h.deactivated >= 3 {
351+
if atomic.LoadUint32(&h.deactivated) >= 3 {
353352
break
354353
}
355354
time.Sleep(poolOpts.CheckTimeout)
@@ -361,8 +360,13 @@ func TestConnectionHandlerOpenUpdateClose(t *testing.T) {
361360
connected, err := pool.ConnectedNow(connection_pool.ANY)
362361
require.Nilf(t, err, "failed to get connected state")
363362
require.Falsef(t, connected, "connection pool still be connected")
364-
require.Equalf(t, len(poolServers)+1, h.discovered, "unexpected discovered count")
365-
require.Equalf(t, len(poolServers)+1, h.deactivated, "unexpected deactivated count")
363+
364+
discovered = atomic.LoadUint32(&h.discovered)
365+
deactivated = atomic.LoadUint32(&h.deactivated)
366+
require.Equalf(t, uint32(len(poolServers)+1), discovered,
367+
"unexpected discovered count")
368+
require.Equalf(t, uint32(len(poolServers)+1), deactivated,
369+
"unexpected deactivated count")
366370
}
367371

368372
type testAddErrorHandler struct {

0 commit comments

Comments
 (0)