|
@@ -1,165 +0,0 @@
|
|
-package main
|
|
|
|
-
|
|
|
|
-import (
|
|
|
|
- "context"
|
|
|
|
- "fmt"
|
|
|
|
- "strings"
|
|
|
|
- "time"
|
|
|
|
-
|
|
|
|
- "github.com/tal-tech/go-zero/core/discov"
|
|
|
|
- "github.com/tal-tech/go-zero/core/logx"
|
|
|
|
- "github.com/tal-tech/go-zero/core/proc"
|
|
|
|
- "github.com/tal-tech/go-zero/core/syncx"
|
|
|
|
- "go.etcd.io/etcd/clientv3"
|
|
|
|
-)
|
|
|
|
-
|
|
|
|
-var (
|
|
|
|
- endpoints []string
|
|
|
|
- keys = []string{
|
|
|
|
- "user.rpc",
|
|
|
|
- "classroom.rpc",
|
|
|
|
- }
|
|
|
|
- vals = make(map[string]map[string]string)
|
|
|
|
- barrier syncx.Barrier
|
|
|
|
-)
|
|
|
|
-
|
|
|
|
-type listener struct {
|
|
|
|
- key string
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func init() {
|
|
|
|
- cluster := proc.Env("ETCD_CLUSTER")
|
|
|
|
- if len(cluster) > 0 {
|
|
|
|
- endpoints = strings.Split(cluster, ",")
|
|
|
|
- } else {
|
|
|
|
- endpoints = []string{"localhost:2379"}
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func (l listener) OnAdd(key, val string) {
|
|
|
|
- fmt.Printf("add, key: %s, val: %s\n", key, val)
|
|
|
|
- barrier.Guard(func() {
|
|
|
|
- if m, ok := vals[l.key]; ok {
|
|
|
|
- m[key] = val
|
|
|
|
- } else {
|
|
|
|
- vals[l.key] = map[string]string{key: val}
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func (l listener) OnDelete(key string) {
|
|
|
|
- fmt.Printf("del, key: %s\n", key)
|
|
|
|
- barrier.Guard(func() {
|
|
|
|
- if m, ok := vals[l.key]; ok {
|
|
|
|
- delete(m, key)
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func load(cli *clientv3.Client, key string) (map[string]string, error) {
|
|
|
|
- ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
- resp, err := cli.Get(ctx, key, clientv3.WithPrefix())
|
|
|
|
- cancel()
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret := make(map[string]string)
|
|
|
|
- for _, ev := range resp.Kvs {
|
|
|
|
- ret[string(ev.Key)] = string(ev.Value)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return ret, nil
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func loadAll(cli *clientv3.Client) (map[string]map[string]string, error) {
|
|
|
|
- ret := make(map[string]map[string]string)
|
|
|
|
- for _, key := range keys {
|
|
|
|
- m, err := load(cli, key)
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ret[key] = m
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return ret, nil
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func compare(a, b map[string]map[string]string) bool {
|
|
|
|
- if len(a) != len(b) {
|
|
|
|
- return false
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for k := range a {
|
|
|
|
- av := a[k]
|
|
|
|
- bv := b[k]
|
|
|
|
- if len(av) != len(bv) {
|
|
|
|
- return false
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for kk := range av {
|
|
|
|
- if av[kk] != bv[kk] {
|
|
|
|
- return false
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func serializeMap(m map[string]map[string]string, prefix string) string {
|
|
|
|
- var builder strings.Builder
|
|
|
|
- for k, v := range m {
|
|
|
|
- fmt.Fprintf(&builder, "%s%s:\n", prefix, k)
|
|
|
|
- for kk, vv := range v {
|
|
|
|
- fmt.Fprintf(&builder, "%s\t%s: %s\n", prefix, kk, vv)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return builder.String()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func main() {
|
|
|
|
- registry := discov.NewFacade(endpoints)
|
|
|
|
- for _, key := range keys {
|
|
|
|
- registry.Monitor(key, listener{key: key})
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ticker := time.NewTicker(time.Minute)
|
|
|
|
- defer ticker.Stop()
|
|
|
|
-
|
|
|
|
- for range ticker.C {
|
|
|
|
- expect, err := loadAll(registry.Client().(*clientv3.Client))
|
|
|
|
- if err != nil {
|
|
|
|
- fmt.Println("[ETCD-test] can't load current keys")
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- check := func() bool {
|
|
|
|
- var match bool
|
|
|
|
- barrier.Guard(func() {
|
|
|
|
- match = compare(expect, vals)
|
|
|
|
- })
|
|
|
|
- if match {
|
|
|
|
- logx.Info("match")
|
|
|
|
- }
|
|
|
|
- return match
|
|
|
|
- }
|
|
|
|
- if check() {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- time.AfterFunc(time.Second*5, func() {
|
|
|
|
- if check() {
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var builder strings.Builder
|
|
|
|
- builder.WriteString(fmt.Sprintf("expect:\n%s\n", serializeMap(expect, "\t")))
|
|
|
|
- barrier.Guard(func() {
|
|
|
|
- builder.WriteString(fmt.Sprintf("actual:\n%s\n", serializeMap(vals, "\t")))
|
|
|
|
- })
|
|
|
|
- fmt.Println(builder.String())
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
-}
|
|
|