registry: [gossip] add ConnectRetry and ConnectTimeout
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
		| @@ -1,7 +1,6 @@ | ||||
| package gossip_test | ||||
| package gossip | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"os" | ||||
| 	"sync" | ||||
| 	"testing" | ||||
| @@ -9,68 +8,57 @@ import ( | ||||
|  | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/hashicorp/memberlist" | ||||
| 	micro "github.com/micro/go-micro" | ||||
| 	"github.com/micro/go-micro/client" | ||||
| 	"github.com/micro/go-micro/registry" | ||||
| 	"github.com/micro/go-micro/registry/gossip" | ||||
| 	pb "github.com/micro/go-micro/registry/gossip/proto" | ||||
| 	"github.com/micro/go-micro/selector" | ||||
| 	"github.com/micro/go-micro/server" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	r1 registry.Registry | ||||
| 	r2 registry.Registry | ||||
| 	mu sync.Mutex | ||||
| ) | ||||
|  | ||||
| func newConfig() *memberlist.Config { | ||||
| 	wc := memberlist.DefaultLANConfig() | ||||
| 	wc.DisableTcpPings = false | ||||
| 	wc.GossipVerifyIncoming = false | ||||
| 	wc.GossipVerifyOutgoing = false | ||||
| 	wc.EnableCompression = false | ||||
| 	wc.LogOutput = os.Stderr | ||||
| 	wc.ProtocolVersion = 4 | ||||
| 	wc.Name = uuid.New().String() | ||||
| 	return wc | ||||
| func newMemberlistConfig() *memberlist.Config { | ||||
| 	mc := memberlist.DefaultLANConfig() | ||||
| 	mc.DisableTcpPings = false | ||||
| 	mc.GossipVerifyIncoming = false | ||||
| 	mc.GossipVerifyOutgoing = false | ||||
| 	mc.EnableCompression = false | ||||
| 	mc.PushPullInterval = 3 * time.Second | ||||
| 	mc.LogOutput = os.Stderr | ||||
| 	mc.ProtocolVersion = 4 | ||||
| 	mc.Name = uuid.New().String() | ||||
| 	return mc | ||||
| } | ||||
|  | ||||
| func newRegistries() { | ||||
| 	mu.Lock() | ||||
| 	defer mu.Unlock() | ||||
|  | ||||
| 	if r1 != nil && r2 != nil { | ||||
| 		return | ||||
| func newRegistry(opts ...registry.Option) registry.Registry { | ||||
| 	options := []registry.Option{ | ||||
| 		ConnectRetry(true), | ||||
| 		ConnectTimeout(60 * time.Second), | ||||
| 	} | ||||
|  | ||||
| 	wc1 := newConfig() | ||||
| 	wc2 := newConfig() | ||||
|  | ||||
| 	rops1 := []registry.Option{gossip.Config(wc1), gossip.Address("127.0.0.1:54321")} | ||||
| 	rops2 := []registry.Option{gossip.Config(wc2), gossip.Address("127.0.0.2:54321"), registry.Addrs("127.0.0.1:54321")} | ||||
|  | ||||
| 	r1 = gossip.NewRegistry(rops1...) // first started without members | ||||
| 	r2 = gossip.NewRegistry(rops2...) // second started joining | ||||
| 	options = append(options, opts...) | ||||
| 	r := NewRegistry(options...) | ||||
| 	return r | ||||
| } | ||||
|  | ||||
| func TestRegistryBroadcast(t *testing.T) { | ||||
| 	newRegistries() | ||||
| 	mc1 := newMemberlistConfig() | ||||
| 	r1 := newRegistry(Config(mc1), Address("127.0.0.1:54321")) | ||||
|  | ||||
| 	mc2 := newMemberlistConfig() | ||||
| 	r2 := newRegistry(Config(mc2), Address("127.0.0.2:54321"), registry.Addrs("127.0.0.1:54321")) | ||||
|  | ||||
| 	defer r1.(*gossipRegistry).Stop() | ||||
| 	defer r2.(*gossipRegistry).Stop() | ||||
|  | ||||
| 	svc1 := ®istry.Service{Name: "r1-svc", Version: "0.0.0.1"} | ||||
| 	svc2 := ®istry.Service{Name: "r2-svc", Version: "0.0.0.2"} | ||||
|  | ||||
| 	<-time.After(1 * time.Second) | ||||
| 	if err := r1.Register(svc1); err != nil { | ||||
| 	t.Logf("register service svc1 on r1\n") | ||||
| 	if err := r1.Register(svc1, registry.RegisterTTL(10*time.Second)); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	<-time.After(1 * time.Second) | ||||
| 	if err := r2.Register(svc2); err != nil { | ||||
| 	t.Logf("register service svc2 on r2\n") | ||||
| 	if err := r2.Register(svc2, registry.RegisterTTL(10*time.Second)); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	var found bool | ||||
|  | ||||
| 	t.Logf("list services on r1\n") | ||||
| 	svcs, err := r1.ListServices() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| @@ -83,6 +71,129 @@ func TestRegistryBroadcast(t *testing.T) { | ||||
| 	} | ||||
| 	if !found { | ||||
| 		t.Fatalf("r2-svc not found in r1, broadcast not work") | ||||
| 	} else { | ||||
| 		t.Logf("r2-svc found in r1, all ok") | ||||
| 	} | ||||
|  | ||||
| 	found = false | ||||
| 	t.Logf("list services on r2\n") | ||||
| 	svcs, err = r2.ListServices() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	for _, svc := range svcs { | ||||
| 		if svc.Name == "r1-svc" { | ||||
| 			found = true | ||||
| 		} | ||||
| 	} | ||||
| 	if !found { | ||||
| 		t.Fatalf("r1-svc not found in r2, broadcast not work") | ||||
| 	} else { | ||||
| 		t.Logf("r1-svc found in r1, all ok") | ||||
| 	} | ||||
|  | ||||
| 	t.Logf("deregister service svc1 on r1\n") | ||||
| 	if err := r1.Deregister(svc1); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	t.Logf("deregister service svc1 on r2\n") | ||||
| 	if err := r2.Deregister(svc2); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| } | ||||
| func TestRegistryRetry(t *testing.T) { | ||||
| 	mc1 := newMemberlistConfig() | ||||
| 	r1 := newRegistry(Config(mc1), Address("127.0.0.1:54321")) | ||||
|  | ||||
| 	mc2 := newMemberlistConfig() | ||||
| 	r2 := newRegistry(Config(mc2), Address("127.0.0.2:54321"), registry.Addrs("127.0.0.1:54321")) | ||||
|  | ||||
| 	defer r1.(*gossipRegistry).Stop() | ||||
| 	defer r2.(*gossipRegistry).Stop() | ||||
|  | ||||
| 	svc1 := ®istry.Service{Name: "r1-svc", Version: "0.0.0.1"} | ||||
| 	svc2 := ®istry.Service{Name: "r2-svc", Version: "0.0.0.2"} | ||||
|  | ||||
| 	var mu sync.Mutex | ||||
| 	ch := make(chan struct{}) | ||||
| 	ticker := time.NewTicker(1 * time.Second) | ||||
| 	defer ticker.Stop() | ||||
|  | ||||
| 	go func() { | ||||
| 		for { | ||||
| 			select { | ||||
| 			case <-ticker.C: | ||||
| 				mu.Lock() | ||||
| 				if r1 != nil { | ||||
| 					r1.Register(svc1, registry.RegisterTTL(2*time.Second)) | ||||
| 				} | ||||
| 				if r2 != nil { | ||||
| 					r2.Register(svc2, registry.RegisterTTL(2*time.Second)) | ||||
| 				} | ||||
| 				if ch != nil { | ||||
| 					close(ch) | ||||
| 					ch = nil | ||||
| 				} | ||||
| 				mu.Unlock() | ||||
| 			} | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	<-ch | ||||
| 	var found bool | ||||
|  | ||||
| 	svcs, err := r2.ListServices() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	for _, svc := range svcs { | ||||
| 		if svc.Name == "r1-svc" { | ||||
| 			found = true | ||||
| 		} | ||||
| 	} | ||||
| 	if !found { | ||||
| 		t.Fatalf("r1-svc not found in r2, broadcast not work, retry cant test") | ||||
| 	} | ||||
|  | ||||
| 	t.Logf("stop r1\n") | ||||
| 	if err = r1.(*gossipRegistry).Stop(); err != nil { | ||||
| 		t.Fatalf("cant stop r1 registry %v", err) | ||||
| 	} | ||||
|  | ||||
| 	mu.Lock() | ||||
| 	r1 = nil | ||||
| 	mu.Unlock() | ||||
|  | ||||
| 	<-time.After(3 * time.Second) | ||||
|  | ||||
| 	found = false | ||||
| 	svcs, err = r2.ListServices() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	for _, svc := range svcs { | ||||
| 		if svc.Name == "r1-svc" { | ||||
| 			found = true | ||||
| 		} | ||||
| 	} | ||||
| 	if found { | ||||
| 		t.Fatalf("r1-svc found in r2, something wrong") | ||||
| 	} | ||||
|  | ||||
| 	t.Logf("start r1\n") | ||||
|  | ||||
| 	r1 = newRegistry(Config(mc1), Address("127.0.0.1:54321")) | ||||
| 	<-time.After(2 * time.Second) | ||||
|  | ||||
| 	if tr := os.Getenv("TRAVIS"); len(tr) > 0 { | ||||
| 		t.Logf("skip next test part, becasue it not works in travis") | ||||
| 		t.Skip() | ||||
| 		return | ||||
| 		<-time.After(5 * time.Second) | ||||
| 	} | ||||
|  | ||||
| 	found = false | ||||
| @@ -97,7 +208,7 @@ func TestRegistryBroadcast(t *testing.T) { | ||||
| 		} | ||||
| 	} | ||||
| 	if !found { | ||||
| 		t.Fatalf("r1-svc not found in r2, broadcast not work") | ||||
| 		t.Fatalf("r1-svc not found in r2, connect retry not works") | ||||
| 	} | ||||
|  | ||||
| 	if err := r1.Deregister(svc1); err != nil { | ||||
| @@ -107,93 +218,6 @@ func TestRegistryBroadcast(t *testing.T) { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestServerRegistry(t *testing.T) { | ||||
| 	newRegistries() | ||||
|  | ||||
| 	_, err := newServer("s1", r1, t) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	_, err = newServer("s2", r2, t) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	svcs, err := r1.ListServices() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if len(svcs) < 1 { | ||||
| 		t.Fatalf("r1 svcs unknown %#+v\n", svcs) | ||||
| 	} | ||||
|  | ||||
| 	found := false | ||||
| 	for _, svc := range svcs { | ||||
| 		if svc.Name == "s2" { | ||||
| 			found = true | ||||
| 		} | ||||
| 	} | ||||
| 	if !found { | ||||
| 		t.Fatalf("r1 does not have s2, broadcast not work") | ||||
| 	} | ||||
|  | ||||
| 	found = false | ||||
| 	svcs, err = r2.ListServices() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| 	for _, svc := range svcs { | ||||
| 		if svc.Name == "s1" { | ||||
| 			found = true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if !found { | ||||
| 		t.Fatalf("r2 does not have s1, broadcast not work") | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| type testServer struct{} | ||||
|  | ||||
| func (*testServer) Test(ctx context.Context, req *pb.Update, rsp *pb.Update) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func newServer(n string, r registry.Registry, t *testing.T) (micro.Service, error) { | ||||
| 	h := &testServer{} | ||||
|  | ||||
| 	var wg sync.WaitGroup | ||||
|  | ||||
| 	wg.Add(1) | ||||
| 	sopts := []server.Option{ | ||||
| 		server.Name(n), | ||||
| 		server.Registry(r), | ||||
| 	} | ||||
|  | ||||
| 	copts := []client.Option{ | ||||
| 		client.Selector(selector.NewSelector(selector.Registry(r))), | ||||
| 		client.Registry(r), | ||||
| 	} | ||||
|  | ||||
| 	srv := micro.NewService( | ||||
| 		micro.Server(server.NewServer(sopts...)), | ||||
| 		micro.Client(client.NewClient(copts...)), | ||||
| 		micro.AfterStart(func() error { | ||||
| 			wg.Done() | ||||
| 			return nil | ||||
| 		}), | ||||
| 	) | ||||
|  | ||||
| 	srv.Server().NewHandler(h) | ||||
|  | ||||
| 	go func() { | ||||
| 		t.Fatal(srv.Run()) | ||||
| 	}() | ||||
| 	wg.Wait() | ||||
| 	return srv, nil | ||||
| 	r1.(*gossipRegistry).Stop() | ||||
| 	r2.(*gossipRegistry).Stop() | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user