rename rpcx to zrpc
This commit is contained in:
32
zrpc/internal/resolver/directbuilder.go
Normal file
32
zrpc/internal/resolver/directbuilder.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"google.golang.org/grpc/resolver"
|
||||
)
|
||||
|
||||
type directBuilder struct{}
|
||||
|
||||
func (d *directBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (
|
||||
resolver.Resolver, error) {
|
||||
var addrs []resolver.Address
|
||||
endpoints := strings.FieldsFunc(target.Endpoint, func(r rune) bool {
|
||||
return r == EndpointSepChar
|
||||
})
|
||||
|
||||
for _, val := range subset(endpoints, subsetSize) {
|
||||
addrs = append(addrs, resolver.Address{
|
||||
Addr: val,
|
||||
})
|
||||
}
|
||||
cc.UpdateState(resolver.State{
|
||||
Addresses: addrs,
|
||||
})
|
||||
|
||||
return &nopResolver{cc: cc}, nil
|
||||
}
|
||||
|
||||
func (d *directBuilder) Scheme() string {
|
||||
return DirectScheme
|
||||
}
|
||||
52
zrpc/internal/resolver/directbuilder_test.go
Normal file
52
zrpc/internal/resolver/directbuilder_test.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/core/lang"
|
||||
"github.com/tal-tech/go-zero/core/mathx"
|
||||
"google.golang.org/grpc/resolver"
|
||||
)
|
||||
|
||||
func TestDirectBuilder_Build(t *testing.T) {
|
||||
tests := []int{
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
subsetSize / 2,
|
||||
subsetSize,
|
||||
subsetSize * 2,
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(strconv.Itoa(test), func(t *testing.T) {
|
||||
var servers []string
|
||||
for i := 0; i < test; i++ {
|
||||
servers = append(servers, fmt.Sprintf("localhost:%d", i))
|
||||
}
|
||||
var b directBuilder
|
||||
cc := new(mockedClientConn)
|
||||
_, err := b.Build(resolver.Target{
|
||||
Scheme: DirectScheme,
|
||||
Endpoint: strings.Join(servers, ","),
|
||||
}, cc, resolver.BuildOptions{})
|
||||
assert.Nil(t, err)
|
||||
size := mathx.MinInt(test, subsetSize)
|
||||
assert.Equal(t, size, len(cc.state.Addresses))
|
||||
m := make(map[string]lang.PlaceholderType)
|
||||
for _, each := range cc.state.Addresses {
|
||||
m[each.Addr] = lang.Placeholder
|
||||
}
|
||||
assert.Equal(t, size, len(m))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDirectBuilder_Scheme(t *testing.T) {
|
||||
var b directBuilder
|
||||
assert.Equal(t, DirectScheme, b.Scheme())
|
||||
}
|
||||
41
zrpc/internal/resolver/discovbuilder.go
Normal file
41
zrpc/internal/resolver/discovbuilder.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/tal-tech/go-zero/core/discov"
|
||||
"google.golang.org/grpc/resolver"
|
||||
)
|
||||
|
||||
type discovBuilder struct{}
|
||||
|
||||
func (d *discovBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (
|
||||
resolver.Resolver, error) {
|
||||
hosts := strings.FieldsFunc(target.Authority, func(r rune) bool {
|
||||
return r == EndpointSepChar
|
||||
})
|
||||
sub, err := discov.NewSubscriber(hosts, target.Endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
update := func() {
|
||||
var addrs []resolver.Address
|
||||
for _, val := range subset(sub.Values(), subsetSize) {
|
||||
addrs = append(addrs, resolver.Address{
|
||||
Addr: val,
|
||||
})
|
||||
}
|
||||
cc.UpdateState(resolver.State{
|
||||
Addresses: addrs,
|
||||
})
|
||||
}
|
||||
sub.AddListener(update)
|
||||
update()
|
||||
|
||||
return &nopResolver{cc: cc}, nil
|
||||
}
|
||||
|
||||
func (d *discovBuilder) Scheme() string {
|
||||
return DiscovScheme
|
||||
}
|
||||
35
zrpc/internal/resolver/resolver.go
Normal file
35
zrpc/internal/resolver/resolver.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/grpc/resolver"
|
||||
)
|
||||
|
||||
const (
|
||||
DirectScheme = "direct"
|
||||
DiscovScheme = "discov"
|
||||
EndpointSepChar = ','
|
||||
subsetSize = 32
|
||||
)
|
||||
|
||||
var (
|
||||
EndpointSep = fmt.Sprintf("%c", EndpointSepChar)
|
||||
dirBuilder directBuilder
|
||||
disBuilder discovBuilder
|
||||
)
|
||||
|
||||
func RegisterResolver() {
|
||||
resolver.Register(&dirBuilder)
|
||||
resolver.Register(&disBuilder)
|
||||
}
|
||||
|
||||
type nopResolver struct {
|
||||
cc resolver.ClientConn
|
||||
}
|
||||
|
||||
func (r *nopResolver) Close() {
|
||||
}
|
||||
|
||||
func (r *nopResolver) ResolveNow(options resolver.ResolveNowOptions) {
|
||||
}
|
||||
36
zrpc/internal/resolver/resolver_test.go
Normal file
36
zrpc/internal/resolver/resolver_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"google.golang.org/grpc/resolver"
|
||||
"google.golang.org/grpc/serviceconfig"
|
||||
)
|
||||
|
||||
func TestNopResolver(t *testing.T) {
|
||||
// make sure ResolveNow & Close don't panic
|
||||
var r nopResolver
|
||||
r.ResolveNow(resolver.ResolveNowOptions{})
|
||||
r.Close()
|
||||
}
|
||||
|
||||
type mockedClientConn struct {
|
||||
state resolver.State
|
||||
}
|
||||
|
||||
func (m *mockedClientConn) UpdateState(state resolver.State) {
|
||||
m.state = state
|
||||
}
|
||||
|
||||
func (m *mockedClientConn) ReportError(err error) {
|
||||
}
|
||||
|
||||
func (m *mockedClientConn) NewAddress(addresses []resolver.Address) {
|
||||
}
|
||||
|
||||
func (m *mockedClientConn) NewServiceConfig(serviceConfig string) {
|
||||
}
|
||||
|
||||
func (m *mockedClientConn) ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult {
|
||||
return nil
|
||||
}
|
||||
14
zrpc/internal/resolver/subset.go
Normal file
14
zrpc/internal/resolver/subset.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package resolver
|
||||
|
||||
import "math/rand"
|
||||
|
||||
func subset(set []string, sub int) []string {
|
||||
rand.Shuffle(len(set), func(i, j int) {
|
||||
set[i], set[j] = set[j], set[i]
|
||||
})
|
||||
if len(set) <= sub {
|
||||
return set
|
||||
} else {
|
||||
return set[:sub]
|
||||
}
|
||||
}
|
||||
53
zrpc/internal/resolver/subset_test.go
Normal file
53
zrpc/internal/resolver/subset_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tal-tech/go-zero/core/mathx"
|
||||
)
|
||||
|
||||
func TestSubset(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
set int
|
||||
sub int
|
||||
}{
|
||||
{
|
||||
name: "more vals to subset",
|
||||
set: 100,
|
||||
sub: 36,
|
||||
},
|
||||
{
|
||||
name: "less vals to subset",
|
||||
set: 100,
|
||||
sub: 200,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
var vals []string
|
||||
for i := 0; i < test.set; i++ {
|
||||
vals = append(vals, strconv.Itoa(i))
|
||||
}
|
||||
|
||||
m := make(map[interface{}]int)
|
||||
for i := 0; i < 1000; i++ {
|
||||
set := subset(append([]string(nil), vals...), test.sub)
|
||||
if test.sub < test.set {
|
||||
assert.Equal(t, test.sub, len(set))
|
||||
} else {
|
||||
assert.Equal(t, test.set, len(set))
|
||||
}
|
||||
|
||||
for _, val := range set {
|
||||
m[val]++
|
||||
}
|
||||
}
|
||||
|
||||
assert.True(t, mathx.CalcEntropy(m) > 0.95)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user