Skip to content

Commit 2779422

Browse files
committed
bugfix: logic of add/delete in round robin strategy
* Duplicates could be added to a list of connections, which then cannot be deleted. * The delete function uses an address from a connection instead of argument value. It may lead to unexpected errors. Part of #208
1 parent dcb9491 commit 2779422

File tree

2 files changed

+66
-5
lines changed

2 files changed

+66
-5
lines changed

connection_pool/round_robin.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ func (r *RoundRobinStrategy) DeleteConnByAddr(addr string) *tarantool.Connection
4646
r.conns = append(r.conns[:index], r.conns[index+1:]...)
4747
r.size -= 1
4848

49-
for index, conn := range r.conns {
50-
r.indexByAddr[conn.Addr()] = index
49+
for k, v := range r.indexByAddr {
50+
if v > index {
51+
r.indexByAddr[k] = v - 1
52+
}
5153
}
5254

5355
return conn
@@ -94,9 +96,13 @@ func (r *RoundRobinStrategy) AddConn(addr string, conn *tarantool.Connection) {
9496
r.mutex.Lock()
9597
defer r.mutex.Unlock()
9698

97-
r.conns = append(r.conns, conn)
98-
r.indexByAddr[addr] = r.size
99-
r.size += 1
99+
if idx, ok := r.indexByAddr[addr]; ok {
100+
r.conns[idx] = conn
101+
} else {
102+
r.conns = append(r.conns, conn)
103+
r.indexByAddr[addr] = r.size
104+
r.size += 1
105+
}
100106
}
101107

102108
func (r *RoundRobinStrategy) nextIndex() int {

connection_pool/round_robin_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package connection_pool_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/tarantool/go-tarantool"
7+
. "github.com/tarantool/go-tarantool/connection_pool"
8+
)
9+
10+
const (
11+
validAddr1 = "x"
12+
validAddr2 = "y"
13+
)
14+
15+
func TestRoundRobinAddDelete(t *testing.T) {
16+
rr := NewEmptyRoundRobin(10)
17+
18+
addrs := []string{validAddr1, validAddr2}
19+
conns := []*tarantool.Connection{&tarantool.Connection{}, &tarantool.Connection{}}
20+
21+
for i, addr := range addrs {
22+
rr.AddConn(addr, conns[i])
23+
}
24+
25+
for i, addr := range addrs {
26+
if conn := rr.DeleteConnByAddr(addr); conn != conns[i] {
27+
t.Errorf("Unexpected connection on address %s", addr)
28+
}
29+
}
30+
if !rr.IsEmpty() {
31+
t.Errorf("RoundRobin does not empty")
32+
}
33+
}
34+
35+
func TestRoundRobinAddDuplicateDelete(t *testing.T) {
36+
rr := NewEmptyRoundRobin(10)
37+
38+
conn1 := &tarantool.Connection{}
39+
conn2 := &tarantool.Connection{}
40+
41+
rr.AddConn(validAddr1, conn1)
42+
rr.AddConn(validAddr1, conn2)
43+
44+
if rr.DeleteConnByAddr("x") != conn2 {
45+
t.Errorf("Unexpected deleted connection")
46+
}
47+
if !rr.IsEmpty() {
48+
t.Errorf("RoundRobin does not empty")
49+
}
50+
if rr.DeleteConnByAddr("x") != nil {
51+
t.Errorf("Unexpected valued after second delition")
52+
}
53+
}
54+
55+

0 commit comments

Comments
 (0)