Skip to content

Commit

Permalink
fix: solve the problem of serviceInfo incomparable, to fit the upgrad…
Browse files Browse the repository at this point in the history
…e of grpc-go. (#309)

Co-authored-by: 廖顶超 <feihua@douyu.tv>
Co-authored-by: 大可 <hnlq.sysu@gmail.com>
  • Loading branch information
3 people authored Apr 19, 2022
1 parent d08827e commit 77f6f92
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 12 deletions.
12 changes: 8 additions & 4 deletions example/grpc/etcd/etcd-client/config.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
[jupiter.registry.wh]
connectTimeout = "1s"
endpoints=["127.0.0.1:2379"]
secure = false
[jupiter.client.etcdserver]
address = "etcd:///main"
balancerName = "round_robin" # 默认值
block = false # 默认值
dialTimeout = "0s" # 默认值

[jupiter.registry.wh]
configKey="jupiter.etcdv3.default"
timeout = "10s"

[jupiter.etcdv3.default]
connectTimeout = "10s"
endpoints=["localhost:2379"]
secure = false
2 changes: 2 additions & 0 deletions example/grpc/etcd/etcd-client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/douyu/jupiter"
"github.com/douyu/jupiter/pkg/client/grpc"
"github.com/douyu/jupiter/pkg/client/grpc/balancer"
"github.com/douyu/jupiter/pkg/client/grpc/balancer/p2c"
"github.com/douyu/jupiter/pkg/client/grpc/resolver"
"github.com/douyu/jupiter/pkg/registry/etcdv3"
"github.com/douyu/jupiter/pkg/xlog"
Expand Down Expand Up @@ -59,6 +60,7 @@ func (eng *Engine) initResolver() error {
func (eng *Engine) consumer() error {
config := grpc.StdConfig("etcdserver")
config.BalancerName = balancer.NameSmoothWeightRoundRobin
config.BalancerName = p2c.Name

client := helloworld.NewGreeterClient(config.Build())
go func() {
Expand Down
11 changes: 8 additions & 3 deletions example/grpc/etcd/etcd-server/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
[jupiter.server.grpc]
port = 9091

[jupiter.registry.wh]
connectTimeout = "1s"
endpoints=["127.0.0.1:2379"]
secure = false
configKey = "jupiter.etcdv3.default"
timeout = "1s"

[jupiter.etcdv3.default]
connectTimeout = "10s"
endpoints = ["localhost:2379"]
secure = false
13 changes: 9 additions & 4 deletions example/grpc/etcd/etcd-server/config2.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
[jupiter.server.grpc]
port = 9093
port = 9092

[jupiter.registry.wh]
connectTimeout = "1s"
endpoints=["127.0.0.1:2379"]
secure = false
configKey = "jupiter.etcdv3.default"
timeout = "1s"

[jupiter.etcdv3.default]
connectTimeout = "10s"
endpoints = ["localhost:2379"]
secure = false
14 changes: 13 additions & 1 deletion pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

type Option func(c *ServiceInfo)

// ServiceConfigurator represents service configurator
// ConfigInfo ServiceConfigurator represents service configurator
type ConfigInfo struct {
Routes []Route
}
Expand Down Expand Up @@ -63,6 +63,18 @@ func (si ServiceInfo) Label() string {
return fmt.Sprintf("%s://%s", si.Scheme, si.Address)
}

// Equal allows the values to be compared by Attributes.Equal, this change is in order
// to fit the change in grpc-go:
// attributes: add Equal method; resolver: add AddressMap and State.BalancerAttributes (#4855)
func (si ServiceInfo) Equal(o interface{}) bool {
oa, ok := o.(ServiceInfo)
return ok &&
oa.Name == si.Name &&
oa.Address == si.Address &&
oa.Kind == si.Kind &&
oa.Group == si.Group
}

// Server ...
type Server interface {
Serve() error
Expand Down
142 changes: 142 additions & 0 deletions pkg/server/server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright 2020 Douyu
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package server

import (
"testing"

"github.com/douyu/jupiter/pkg/constant"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc/attributes"
"google.golang.org/grpc/resolver"
)

func Test_ServiceInfo(t *testing.T) {

info1 := ServiceInfo{
Name: "main",
Address: "127.0.0.1:1234",
Weight: 100,
Kind: constant.ServiceProvider,
Group: "g1",
}

info2 := ServiceInfo{
Name: "main",
Address: "127.0.0.1:1234",
Weight: 100,
Kind: constant.ServiceProvider,
Group: "g1",
}

info3 := ServiceInfo{
Name: "main",
Address: "127.0.0.1:1235",
Weight: 100,
Kind: constant.ServiceProvider,
Group: "g1",
}

var (
address1, address2, address3 resolver.Address
)

address1.Addr = info1.Address
address1.Attributes = attributes.New(constant.KeyServiceInfo, info1)

address2.Addr = info2.Address
address2.Attributes = attributes.New(constant.KeyServiceInfo, info2)

address3.Addr = info3.Address
address3.Attributes = attributes.New(constant.KeyServiceInfo, info3)

// the Equal method will check the info which added to attributes,
// two attributes with the same content are Equal.
if !address1.Equal(address2) {
t.Fatalf("%+v.Equals(%+v) = false; want true", address1, address2)
}
if !address2.Equal(address1) {
t.Fatalf("%+v.Equals(%+v) = false; want true", address2, address1)
}

if address1.Equal(address3) {
t.Fatalf("%+v.Equals(%+v) = true; want false", address1, address3)
}

if address3.Equal(address1) {
t.Fatalf("%+v.Equals(%+v) = true; want false", address3, address1)
}

}

// Reproduce the pannic problem of issue #293
// The structure #ServiceInfo# inside the test case
// does not implement the equal method, so the
// comparison at runtime results in panic
func TestNotImplementEqual(t *testing.T) {

// The previous structure: Equal method is not implemented
type ServiceInfo struct {
Name string `json:"name"`
AppID string `json:"appId"`
Scheme string `json:"scheme"`
Address string `json:"address"`
Weight float64 `json:"weight"`
Enable bool `json:"enable"`
Healthy bool `json:"healthy"`
Metadata map[string]string `json:"metadata"`
Region string `json:"region"`
Zone string `json:"zone"`
Kind constant.ServiceKind `json:"kind"`
// Deployment 部署组: 不同组的流量隔离
// 比如某些服务给内部调用和第三方调用,可以配置不同的deployment,进行流量隔离
Deployment string `json:"deployment"`
// Group 流量组: 流量在Group之间进行负载均衡
Group string `json:"group"`
Services map[string]*Service `json:"services" toml:"services"`
}

info1 := ServiceInfo{
Name: "main",
Address: "127.0.0.1:1234",
Weight: 100,
Kind: constant.ServiceProvider,
Group: "g1",
}

info2 := ServiceInfo{
Name: "main",
Address: "127.0.0.1:1234",
Weight: 100,
Kind: constant.ServiceProvider,
Group: "g1",
}

var (
address1, address2 resolver.Address
)

// Attributes as above
address1.Addr = info1.Address
address1.Attributes = attributes.New(constant.KeyServiceInfo, info1)

address2.Addr = info2.Address
address2.Attributes = attributes.New(constant.KeyServiceInfo, info2)

assert.Panics(t, func() {
// This will cause panic
address1.Equal(address2)
})
}

0 comments on commit 77f6f92

Please sign in to comment.