feat: add etcd resolver scheme, fix discov minor issue (#1281)
This commit is contained in:
@@ -37,25 +37,35 @@ func GetRegistry() *Registry {
|
|||||||
|
|
||||||
// GetConn returns an etcd client connection associated with given endpoints.
|
// GetConn returns an etcd client connection associated with given endpoints.
|
||||||
func (r *Registry) GetConn(endpoints []string) (EtcdClient, error) {
|
func (r *Registry) GetConn(endpoints []string) (EtcdClient, error) {
|
||||||
return r.getCluster(endpoints).getClient()
|
c, _ := r.getCluster(endpoints)
|
||||||
|
return c.getClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Monitor monitors the key on given etcd endpoints, notify with the given UpdateListener.
|
// Monitor monitors the key on given etcd endpoints, notify with the given UpdateListener.
|
||||||
func (r *Registry) Monitor(endpoints []string, key string, l UpdateListener) error {
|
func (r *Registry) Monitor(endpoints []string, key string, l UpdateListener) error {
|
||||||
return r.getCluster(endpoints).monitor(key, l)
|
c, exists := r.getCluster(endpoints)
|
||||||
|
// if exists, the existing values should be updated to the listener.
|
||||||
|
if exists {
|
||||||
|
kvs := c.getCurrent(key)
|
||||||
|
for _, kv := range kvs {
|
||||||
|
l.OnAdd(kv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.monitor(key, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Registry) getCluster(endpoints []string) *cluster {
|
func (r *Registry) getCluster(endpoints []string) (c *cluster, exists bool) {
|
||||||
clusterKey := getClusterKey(endpoints)
|
clusterKey := getClusterKey(endpoints)
|
||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
defer r.lock.Unlock()
|
||||||
c, ok := r.clusters[clusterKey]
|
c, exists = r.clusters[clusterKey]
|
||||||
if !ok {
|
if !exists {
|
||||||
c = newCluster(endpoints)
|
c = newCluster(endpoints)
|
||||||
r.clusters[clusterKey] = c
|
r.clusters[clusterKey] = c
|
||||||
}
|
}
|
||||||
|
|
||||||
return c
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type cluster struct {
|
type cluster struct {
|
||||||
@@ -94,6 +104,21 @@ func (c *cluster) getClient() (EtcdClient, error) {
|
|||||||
return val.(EtcdClient), nil
|
return val.(EtcdClient), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *cluster) getCurrent(key string) []KV {
|
||||||
|
c.lock.Lock()
|
||||||
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
|
var kvs []KV
|
||||||
|
for k, v := range c.values[key] {
|
||||||
|
kvs = append(kvs, KV{
|
||||||
|
Key: k,
|
||||||
|
Val: v,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return kvs
|
||||||
|
}
|
||||||
|
|
||||||
func (c *cluster) handleChanges(key string, kvs []KV) {
|
func (c *cluster) handleChanges(key string, kvs []KV) {
|
||||||
var add []KV
|
var add []KV
|
||||||
var remove []KV
|
var remove []KV
|
||||||
@@ -197,14 +222,12 @@ func (c *cluster) load(cli EtcdClient, key string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var kvs []KV
|
var kvs []KV
|
||||||
c.lock.Lock()
|
|
||||||
for _, ev := range resp.Kvs {
|
for _, ev := range resp.Kvs {
|
||||||
kvs = append(kvs, KV{
|
kvs = append(kvs, KV{
|
||||||
Key: string(ev.Key),
|
Key: string(ev.Key),
|
||||||
Val: string(ev.Value),
|
Val: string(ev.Value),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
c.lock.Unlock()
|
|
||||||
|
|
||||||
c.handleChanges(key, kvs)
|
c.handleChanges(key, kvs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ func setMockClient(cli EtcdClient) func() {
|
|||||||
|
|
||||||
func TestGetCluster(t *testing.T) {
|
func TestGetCluster(t *testing.T) {
|
||||||
AddAccount([]string{"first"}, "foo", "bar")
|
AddAccount([]string{"first"}, "foo", "bar")
|
||||||
c1 := GetRegistry().getCluster([]string{"first"})
|
c1, _ := GetRegistry().getCluster([]string{"first"})
|
||||||
c2 := GetRegistry().getCluster([]string{"second"})
|
c2, _ := GetRegistry().getCluster([]string{"second"})
|
||||||
c3 := GetRegistry().getCluster([]string{"first"})
|
c3, _ := GetRegistry().getCluster([]string{"first"})
|
||||||
assert.Equal(t, c1, c3)
|
assert.Equal(t, c1, c3)
|
||||||
assert.NotEqual(t, c1, c2)
|
assert.NotEqual(t, c1, c2)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
type discovBuilder struct{}
|
type discovBuilder struct{}
|
||||||
|
|
||||||
func (b *discovBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (
|
func (b *discovBuilder) Build(target resolver.Target, cc resolver.ClientConn, _ resolver.BuildOptions) (
|
||||||
resolver.Resolver, error) {
|
resolver.Resolver, error) {
|
||||||
hosts := strings.FieldsFunc(target.Authority, func(r rune) bool {
|
hosts := strings.FieldsFunc(target.Authority, func(r rune) bool {
|
||||||
return r == EndpointSepChar
|
return r == EndpointSepChar
|
||||||
|
|||||||
9
zrpc/internal/resolver/etcdbuilder.go
Normal file
9
zrpc/internal/resolver/etcdbuilder.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package resolver
|
||||||
|
|
||||||
|
type etcdBuilder struct {
|
||||||
|
discovBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *etcdBuilder) Scheme() string {
|
||||||
|
return EtcdScheme
|
||||||
|
}
|
||||||
@@ -11,6 +11,8 @@ const (
|
|||||||
DirectScheme = "direct"
|
DirectScheme = "direct"
|
||||||
// DiscovScheme stands for discov scheme.
|
// DiscovScheme stands for discov scheme.
|
||||||
DiscovScheme = "discov"
|
DiscovScheme = "discov"
|
||||||
|
// EtcdScheme stands for etcd scheme.
|
||||||
|
EtcdScheme = "etcd"
|
||||||
// KubernetesScheme stands for k8s scheme.
|
// KubernetesScheme stands for k8s scheme.
|
||||||
KubernetesScheme = "k8s"
|
KubernetesScheme = "k8s"
|
||||||
// EndpointSepChar is the separator cha in endpoints.
|
// EndpointSepChar is the separator cha in endpoints.
|
||||||
@@ -23,16 +25,18 @@ var (
|
|||||||
// EndpointSep is the separator string in endpoints.
|
// EndpointSep is the separator string in endpoints.
|
||||||
EndpointSep = fmt.Sprintf("%c", EndpointSepChar)
|
EndpointSep = fmt.Sprintf("%c", EndpointSepChar)
|
||||||
|
|
||||||
dirBuilder directBuilder
|
directResolverBuilder directBuilder
|
||||||
disBuilder discovBuilder
|
discovResolverBuilder discovBuilder
|
||||||
k8sBuilder kubeBuilder
|
etcdResolverBuilder etcdBuilder
|
||||||
|
k8sResolverBuilder kubeBuilder
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterResolver registers the direct and discov schemes to the resolver.
|
// RegisterResolver registers the direct and discov schemes to the resolver.
|
||||||
func RegisterResolver() {
|
func RegisterResolver() {
|
||||||
resolver.Register(&dirBuilder)
|
resolver.Register(&directResolverBuilder)
|
||||||
resolver.Register(&disBuilder)
|
resolver.Register(&discovResolverBuilder)
|
||||||
resolver.Register(&k8sBuilder)
|
resolver.Register(&etcdResolverBuilder)
|
||||||
|
resolver.Register(&k8sResolverBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
type nopResolver struct {
|
type nopResolver struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user