Skip to content

Commit b142ce7

Browse files
authored
Merge pull request #257 from ydb-platform/remove-multi-balancer
balanced code has been simplified
2 parents d9310fe + 35788f1 commit b142ce7

30 files changed

+825
-1280
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* Simplified the balancing logic
2+
13
## v3.25.3
24
* Changed primary license to `Apache2.0` for auto-detect license
35
* Refactored `types.Struct` value creation

balancers/balancers.go

Lines changed: 32 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,40 @@ import (
44
"strings"
55

66
"github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer"
7-
"github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/multi"
8-
"github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/rr"
9-
"github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/single"
107
"github.com/ydb-platform/ydb-go-sdk/v3/internal/conn"
118
)
129

10+
// Deprecated: RoundRobin is RandomChoice now
1311
func RoundRobin() balancer.Balancer {
14-
return rr.RoundRobin(nil)
12+
return &balancer.Config{}
1513
}
1614

1715
func RandomChoice() balancer.Balancer {
18-
return rr.RandomChoice(nil)
16+
return &balancer.Config{}
1917
}
2018

2119
func SingleConn() balancer.Balancer {
22-
return single.Balancer(nil)
20+
return &balancer.Config{
21+
SingleConn: true,
22+
}
2323
}
2424

2525
// PreferLocalDC creates balancer which use endpoints only in location such as initial endpoint location
2626
// Balancer "balancer" defines balancing algorithm between endpoints selected with filter by location
2727
func PreferLocalDC(balancer balancer.Balancer) balancer.Balancer {
28-
return Prefer(
29-
balancer,
30-
func(endpoint Endpoint) bool {
31-
return endpoint.LocalDC()
32-
},
33-
)
28+
balancer.IsPreferConn = func(c conn.Conn) bool {
29+
return c.Endpoint().LocalDC()
30+
}
31+
return balancer
3432
}
3533

3634
// PreferLocalDCWithFallBack creates balancer which use endpoints only in location such as initial endpoint location
3735
// Balancer "balancer" defines balancing algorithm between endpoints selected with filter by location
3836
// If filter returned zero endpoints from all discovery endpoints list - used all endpoint instead
3937
func PreferLocalDCWithFallBack(balancer balancer.Balancer) balancer.Balancer {
40-
return PreferWithFallback(
41-
balancer,
42-
func(endpoint Endpoint) bool {
43-
return endpoint.LocalDC()
44-
},
45-
)
38+
balancer = PreferLocalDC(balancer)
39+
balancer.AllowFalback = true
40+
return balancer
4641
}
4742

4843
// PreferLocations creates balancer which use endpoints only in selected locations (such as "ABC", "DEF", etc.)
@@ -54,42 +49,25 @@ func PreferLocations(balancer balancer.Balancer, locations ...string) balancer.B
5449
for i := range locations {
5550
locations[i] = strings.ToUpper(locations[i])
5651
}
57-
return Prefer(
58-
balancer,
59-
func(endpoint Endpoint) bool {
60-
location := strings.ToUpper(endpoint.Location())
61-
for _, l := range locations {
62-
if location == l {
63-
return true
64-
}
52+
balancer.IsPreferConn = func(c conn.Conn) bool {
53+
location := strings.ToUpper(c.Endpoint().Location())
54+
for _, l := range locations {
55+
if location == l {
56+
return true
6557
}
66-
return false
67-
},
68-
)
58+
}
59+
return false
60+
}
61+
return balancer
6962
}
7063

7164
// PreferLocationsWithFallback creates balancer which use endpoints only in selected locations
7265
// Balancer "balancer" defines balancing algorithm between endpoints selected with filter by location
7366
// If filter returned zero endpoints from all discovery endpoints list - used all endpoint instead
7467
func PreferLocationsWithFallback(balancer balancer.Balancer, locations ...string) balancer.Balancer {
75-
if len(locations) == 0 {
76-
panic("empty list of locations")
77-
}
78-
for i := range locations {
79-
locations[i] = strings.ToUpper(locations[i])
80-
}
81-
return PreferWithFallback(
82-
balancer,
83-
func(endpoint Endpoint) bool {
84-
location := strings.ToUpper(endpoint.Location())
85-
for _, l := range locations {
86-
if location == l {
87-
return true
88-
}
89-
}
90-
return false
91-
},
92-
)
68+
balancer = PreferLocations(balancer, locations...)
69+
balancer.AllowFalback = true
70+
return balancer
9371
}
9472

9573
type Endpoint interface {
@@ -102,34 +80,19 @@ type Endpoint interface {
10280
// Prefer creates balancer which use endpoints by filter
10381
// Balancer "balancer" defines balancing algorithm between endpoints selected with filter
10482
func Prefer(balancer balancer.Balancer, filter func(endpoint Endpoint) bool) balancer.Balancer {
105-
return multi.Balancer(
106-
multi.WithBalancer(
107-
balancer,
108-
func(cc conn.Conn) bool {
109-
return filter(cc.Endpoint())
110-
},
111-
),
112-
)
83+
balancer.IsPreferConn = func(c conn.Conn) bool {
84+
return filter(c.Endpoint())
85+
}
86+
return balancer
11387
}
11488

11589
// PreferWithFallback creates balancer which use endpoints by filter
11690
// Balancer "balancer" defines balancing algorithm between endpoints selected with filter
11791
// If filter returned zero endpoints from all discovery endpoints list - used all endpoint instead
11892
func PreferWithFallback(balancer balancer.Balancer, filter func(endpoint Endpoint) bool) balancer.Balancer {
119-
return multi.Balancer(
120-
multi.WithBalancer(
121-
balancer,
122-
func(cc conn.Conn) bool {
123-
return filter(cc.Endpoint())
124-
},
125-
),
126-
multi.WithBalancer(
127-
balancer,
128-
func(cc conn.Conn) bool {
129-
return !filter(cc.Endpoint())
130-
},
131-
),
132-
)
93+
balancer = Prefer(balancer, filter)
94+
balancer.AllowFalback = true
95+
return balancer
13396
}
13497

13598
// Default balancer used by default

balancers/balancers_test.go

Lines changed: 27 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,71 @@
11
package balancers
22

33
import (
4-
"context"
54
"testing"
65

76
"github.com/stretchr/testify/require"
87

8+
"github.com/ydb-platform/ydb-go-sdk/v3/internal/mock"
9+
910
"github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer"
10-
"github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/mock"
1111
"github.com/ydb-platform/ydb-go-sdk/v3/internal/conn"
1212
)
1313

1414
func TestPreferLocalDC(t *testing.T) {
15-
ctx := context.Background()
16-
1715
conns := []conn.Conn{
1816
&mock.Conn{AddrField: "1", LocalDCField: false},
1917
&mock.Conn{AddrField: "2", State: conn.Online, LocalDCField: true},
2018
&mock.Conn{AddrField: "3", State: conn.Online, LocalDCField: true},
2119
}
22-
rr := PreferLocalDC(RoundRobin()).Create(conns)
23-
require.Contains(t, []conn.Conn{conns[1], conns[2]}, rr.Next(ctx))
24-
require.Contains(t, []conn.Conn{conns[1], conns[2]}, rr.Next(ctx))
25-
require.Contains(t, []conn.Conn{conns[1], conns[2]}, rr.Next(ctx))
26-
27-
// ban local connections
28-
conns[1].SetState(conn.Banned)
29-
conns[2].SetState(conn.Banned)
30-
require.Contains(t, []conn.Conn{conns[1], conns[2]}, rr.Next(ctx, balancer.WithAcceptBanned(true)))
31-
require.Nil(t, rr.Next(ctx))
20+
rr := PreferLocalDC(RoundRobin())
21+
require.False(t, rr.AllowFalback)
22+
require.Equal(t, []conn.Conn{conns[1], conns[2]}, applyPreferFilter(rr, conns))
3223
}
3324

3425
func TestPreferLocalDCWithFallBack(t *testing.T) {
35-
ctx := context.Background()
36-
3726
conns := []conn.Conn{
38-
&mock.Conn{AddrField: "1", LocalDCField: false, State: conn.Online},
27+
&mock.Conn{AddrField: "1", LocalDCField: false},
3928
&mock.Conn{AddrField: "2", State: conn.Online, LocalDCField: true},
4029
&mock.Conn{AddrField: "3", State: conn.Online, LocalDCField: true},
4130
}
42-
rr := PreferLocalDCWithFallBack(RoundRobin()).Create(conns)
43-
require.Contains(t, []conn.Conn{conns[1], conns[2]}, rr.Next(ctx))
44-
require.Contains(t, []conn.Conn{conns[1], conns[2]}, rr.Next(ctx))
45-
require.Contains(t, []conn.Conn{conns[1], conns[2]}, rr.Next(ctx))
46-
47-
// ban connections
48-
conns[1].SetState(conn.Banned)
49-
conns[2].SetState(conn.Banned)
50-
require.Contains(t, []conn.Conn{conns[1], conns[2]}, rr.Next(ctx, balancer.WithAcceptBanned(true)))
51-
require.Equal(t, conns[0], rr.Next(ctx))
31+
rr := PreferLocalDCWithFallBack(RoundRobin())
32+
require.True(t, rr.AllowFalback)
33+
require.Equal(t, []conn.Conn{conns[1], conns[2]}, applyPreferFilter(rr, conns))
5234
}
5335

5436
func TestPreferLocations(t *testing.T) {
55-
ctx := context.Background()
56-
5737
conns := []conn.Conn{
5838
&mock.Conn{AddrField: "1", LocationField: "zero", State: conn.Online},
5939
&mock.Conn{AddrField: "2", State: conn.Online, LocationField: "one"},
6040
&mock.Conn{AddrField: "3", State: conn.Online, LocationField: "two"},
6141
}
6242

63-
rr := PreferLocations(RoundRobin(), "zero", "two").Create(conns)
64-
require.Contains(t, []conn.Conn{conns[0], conns[2]}, rr.Next(ctx))
65-
require.Contains(t, []conn.Conn{conns[0], conns[2]}, rr.Next(ctx))
66-
require.Contains(t, []conn.Conn{conns[0], conns[2]}, rr.Next(ctx))
67-
68-
// ban zero, two
69-
conns[0].SetState(conn.Banned)
70-
conns[2].SetState(conn.Banned)
71-
require.Contains(t, []conn.Conn{conns[0], conns[2]}, rr.Next(ctx, balancer.WithAcceptBanned(true)))
72-
require.Nil(t, rr.Next(ctx))
43+
rr := PreferLocations(RoundRobin(), "zero", "two")
44+
require.False(t, rr.AllowFalback)
45+
require.Equal(t, []conn.Conn{conns[0], conns[2]}, applyPreferFilter(rr, conns))
7346
}
7447

7548
func TestPreferLocationsWithFallback(t *testing.T) {
76-
ctx := context.Background()
77-
7849
conns := []conn.Conn{
7950
&mock.Conn{AddrField: "1", LocationField: "zero", State: conn.Online},
8051
&mock.Conn{AddrField: "2", State: conn.Online, LocationField: "one"},
8152
&mock.Conn{AddrField: "3", State: conn.Online, LocationField: "two"},
8253
}
8354

84-
rr := PreferLocationsWithFallback(RoundRobin(), "zero", "two").Create(conns)
85-
require.Contains(t, []conn.Conn{conns[0], conns[2]}, rr.Next(ctx))
86-
require.Contains(t, []conn.Conn{conns[0], conns[2]}, rr.Next(ctx))
87-
require.Contains(t, []conn.Conn{conns[0], conns[2]}, rr.Next(ctx))
55+
rr := PreferLocationsWithFallback(RoundRobin(), "zero", "two")
56+
require.True(t, rr.AllowFalback)
57+
require.Equal(t, []conn.Conn{conns[0], conns[2]}, applyPreferFilter(rr, conns))
58+
}
8859

89-
// ban zero, two
90-
conns[0].SetState(conn.Banned)
91-
conns[2].SetState(conn.Banned)
92-
require.Contains(t, []conn.Conn{conns[0], conns[2]}, rr.Next(ctx, balancer.WithAcceptBanned(true)))
93-
require.Equal(t, conns[1], rr.Next(ctx))
60+
func applyPreferFilter(b balancer.Balancer, conns []conn.Conn) []conn.Conn {
61+
if b.IsPreferConn == nil {
62+
b.IsPreferConn = func(c conn.Conn) bool { return true }
63+
}
64+
res := make([]conn.Conn, 0, len(conns))
65+
for _, c := range conns {
66+
if b.IsPreferConn(c) {
67+
res = append(res, c)
68+
}
69+
}
70+
return res
9471
}

0 commit comments

Comments
 (0)