feat: added configuration center function (#3035)

Co-authored-by: aiden.ma <Aiden.ma@yijinin.com>
This commit is contained in:
MarkJoyMa
2024-08-28 14:47:52 +08:00
committed by GitHub
parent 47d13e5ef8
commit 44cddec5c3
9 changed files with 628 additions and 25 deletions

View File

@@ -10,13 +10,14 @@ import (
"sync"
"time"
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
clientv3 "go.etcd.io/etcd/client/v3"
"github.com/zeromicro/go-zero/core/contextx"
"github.com/zeromicro/go-zero/core/lang"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/syncx"
"github.com/zeromicro/go-zero/core/threading"
"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
clientv3 "go.etcd.io/etcd/client/v3"
)
var (
@@ -45,7 +46,7 @@ func (r *Registry) GetConn(endpoints []string) (EtcdClient, error) {
}
// 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, disablePrefix bool) error {
c, exists := r.getCluster(endpoints)
// if exists, the existing values should be updated to the listener.
if exists {
@@ -55,7 +56,7 @@ func (r *Registry) Monitor(endpoints []string, key string, l UpdateListener) err
}
}
return c.monitor(key, l)
return c.monitor(key, l, disablePrefix)
}
func (r *Registry) getCluster(endpoints []string) (c *cluster, exists bool) {
@@ -79,13 +80,14 @@ func (r *Registry) getCluster(endpoints []string) (c *cluster, exists bool) {
}
type cluster struct {
endpoints []string
key string
values map[string]map[string]string
listeners map[string][]UpdateListener
watchGroup *threading.RoutineGroup
done chan lang.PlaceholderType
lock sync.RWMutex
endpoints []string
key string
values map[string]map[string]string
listeners map[string][]UpdateListener
watchGroup *threading.RoutineGroup
done chan lang.PlaceholderType
lock sync.RWMutex
disablePrefix bool
}
func newCluster(endpoints []string) *cluster {
@@ -224,7 +226,12 @@ func (c *cluster) load(cli EtcdClient, key string) int64 {
for {
var err error
ctx, cancel := context.WithTimeout(c.context(cli), RequestTimeout)
resp, err = cli.Get(ctx, makeKeyPrefix(key), clientv3.WithPrefix())
if c.disablePrefix {
resp, err = cli.Get(ctx, key)
} else {
resp, err = cli.Get(ctx, makeKeyPrefix(key), clientv3.WithPrefix())
}
cancel()
if err == nil {
break
@@ -247,9 +254,10 @@ func (c *cluster) load(cli EtcdClient, key string) int64 {
return resp.Header.Revision
}
func (c *cluster) monitor(key string, l UpdateListener) error {
func (c *cluster) monitor(key string, l UpdateListener, disablePrefix bool) error {
c.lock.Lock()
c.listeners[key] = append(c.listeners[key], l)
c.disablePrefix = disablePrefix
c.lock.Unlock()
cli, err := c.getClient()
@@ -315,14 +323,20 @@ func (c *cluster) watch(cli EtcdClient, key string, rev int64) {
}
func (c *cluster) watchStream(cli EtcdClient, key string, rev int64) error {
var rch clientv3.WatchChan
if rev != 0 {
rch = cli.Watch(clientv3.WithRequireLeader(c.context(cli)), makeKeyPrefix(key),
clientv3.WithPrefix(), clientv3.WithRev(rev+1))
} else {
rch = cli.Watch(clientv3.WithRequireLeader(c.context(cli)), makeKeyPrefix(key),
clientv3.WithPrefix())
var (
rch clientv3.WatchChan
ops []clientv3.OpOption
watchKey = key
)
if !c.disablePrefix {
watchKey = makeKeyPrefix(key)
ops = append(ops, clientv3.WithPrefix())
}
if rev != 0 {
ops = append(ops, clientv3.WithRev(rev+1))
}
rch = cli.Watch(clientv3.WithRequireLeader(c.context(cli)), watchKey, ops...)
for {
select {

View File

@@ -289,7 +289,7 @@ func TestRegistry_Monitor(t *testing.T) {
},
}
GetRegistry().lock.Unlock()
assert.Error(t, GetRegistry().Monitor(endpoints, "foo", new(mockListener)))
assert.Error(t, GetRegistry().Monitor(endpoints, "foo", new(mockListener), false))
}
type mockListener struct {