@@ -729,57 +729,132 @@ func TestRoutesToEachOther(t *testing.T) {
729
729
}
730
730
}
731
731
732
- func TestConnectULRsWithRoutesToEachOther (t * testing.T ) {
733
- optsA := DefaultOptions ()
734
- optsA .Host = "127.0.0.1"
735
- optsA .Cluster .Port = 7246
736
- optsA .Routes = RoutesFromStr ("nats://127.0.0.1:7247" )
737
-
738
- optsB := DefaultOptions ()
739
- optsB .Host = "127.0.0.1"
740
- optsB .Cluster .Port = 7247
741
- optsB .Routes = RoutesFromStr ("nats://127.0.0.1:7246" )
742
-
743
- // Start servers with go routines to increase change of
744
- // each server connecting to each other at the same time.
745
- srvA := New (optsA )
746
- defer srvA .Shutdown ()
747
-
748
- srvB := New (optsB )
749
- defer srvB .Shutdown ()
750
-
751
- go srvA .Start ()
752
- go srvB .Start ()
753
-
754
- // Wait for cluster to be formed
755
- checkClusterFormed (t , srvA , srvB )
756
-
757
- // Connect to serverB
758
- url := fmt .Sprintf ("nats://%s" , srvB .Addr ().String ())
759
- nc , err := nats .Connect (url )
760
- if err != nil {
761
- t .Fatalf ("Error on connect: %v" , err )
762
- }
763
- defer nc .Close ()
764
- ds := nc .Servers ()
765
- if len (ds ) != 2 {
766
- t .Fatalf ("Expected 2 servers, got %v" , ds )
732
+ func wait (ch chan bool ) error {
733
+ select {
734
+ case <- ch :
735
+ return nil
736
+ case <- time .After (5 * time .Second ):
767
737
}
738
+ return fmt .Errorf ("timeout" )
739
+ }
768
740
769
- // Shutdown server A and make sure that we are notfied
770
- // that server A is no longer running.
771
- srvA .Shutdown ()
772
- timeout := time .Now ().Add (5 * time .Second )
773
- ok := false
774
- for time .Now ().Before (timeout ) {
775
- ds = nc .Servers ()
776
- if len (ds ) == 1 {
777
- ok = true
778
- break
741
+ func TestServerPoolUpdatedWhenRouteGoesAway (t * testing.T ) {
742
+ s1Opts := DefaultOptions ()
743
+ s1Opts .Host = "127.0.0.1"
744
+ s1Opts .Port = 4222
745
+ s1Opts .Cluster .Host = "127.0.0.1"
746
+ s1Opts .Cluster .Port = 6222
747
+ s1Opts .Routes = RoutesFromStr ("nats://127.0.0.1:6223,nats://127.0.0.1:6224" )
748
+ s1 := RunServer (s1Opts )
749
+ defer s1 .Shutdown ()
750
+
751
+ s1Url := "nats://127.0.0.1:4222"
752
+ s2Url := "nats://127.0.0.1:4223"
753
+ s3Url := "nats://127.0.0.1:4224"
754
+
755
+ ch := make (chan bool , 1 )
756
+ chch := make (chan bool , 1 )
757
+ connHandler := func (_ * nats.Conn ) {
758
+ chch <- true
759
+ }
760
+ nc , err := nats .Connect (s1Url ,
761
+ nats .ReconnectHandler (connHandler ),
762
+ nats .DiscoveredServersHandler (func (_ * nats.Conn ) {
763
+ ch <- true
764
+ }))
765
+ if err != nil {
766
+ t .Fatalf ("Error on connect" )
767
+ }
768
+
769
+ s2Opts := DefaultOptions ()
770
+ s2Opts .Host = "127.0.0.1"
771
+ s2Opts .Port = s1Opts .Port + 1
772
+ s2Opts .Cluster .Host = "127.0.0.1"
773
+ s2Opts .Cluster .Port = 6223
774
+ s2Opts .Routes = RoutesFromStr ("nats://127.0.0.1:6222,nats://127.0.0.1:6224" )
775
+ s2 := RunServer (s2Opts )
776
+ defer s2 .Shutdown ()
777
+
778
+ // Wait to be notified
779
+ if err := wait (ch ); err != nil {
780
+ t .Fatal ("New server callback was not invoked" )
781
+ }
782
+
783
+ checkPool := func (expected []string ) {
784
+ // Don't use discovered here, but Servers to have the full list.
785
+ // Also, there may be cases where the mesh is not formed yet,
786
+ // so try again on failure.
787
+ var (
788
+ ds []string
789
+ timeout = time .Now ().Add (5 * time .Second )
790
+ )
791
+ for time .Now ().Before (timeout ) {
792
+ ds = nc .Servers ()
793
+ if len (ds ) == len (expected ) {
794
+ m := make (map [string ]struct {}, len (ds ))
795
+ for _ , url := range ds {
796
+ m [url ] = struct {}{}
797
+ }
798
+ ok := true
799
+ for _ , url := range expected {
800
+ if _ , present := m [url ]; ! present {
801
+ ok = false
802
+ break
803
+ }
804
+ }
805
+ if ok {
806
+ return
807
+ }
808
+ }
809
+ time .Sleep (50 * time .Millisecond )
779
810
}
780
- time .Sleep (50 * time .Millisecond )
811
+ stackFatalf (t , "Expected %v, got %v" , expected , ds )
812
+ }
813
+ // Verify that we now know about s2
814
+ checkPool ([]string {s1Url , s2Url })
815
+
816
+ s3Opts := DefaultOptions ()
817
+ s3Opts .Host = "127.0.0.1"
818
+ s3Opts .Port = s2Opts .Port + 1
819
+ s3Opts .Cluster .Host = "127.0.0.1"
820
+ s3Opts .Cluster .Port = 6224
821
+ s3Opts .Routes = RoutesFromStr ("nats://127.0.0.1:6222,nats://127.0.0.1:6223" )
822
+ s3 := RunServer (s3Opts )
823
+ defer s3 .Shutdown ()
824
+
825
+ // Wait to be notified
826
+ if err := wait (ch ); err != nil {
827
+ t .Fatal ("New server callback was not invoked" )
828
+ }
829
+ // Verify that we now know about s3
830
+ checkPool ([]string {s1Url , s2Url , s3Url })
831
+
832
+ // Stop s1. Since this was passed to the Connect() call, this one should
833
+ // still be present.
834
+ s1 .Shutdown ()
835
+ // Wait for reconnect
836
+ if err := wait (chch ); err != nil {
837
+ t .Fatal ("Reconnect handler not invoked" )
838
+ }
839
+ checkPool ([]string {s1Url , s2Url , s3Url })
840
+
841
+ // Check the server we reconnected to.
842
+ reConnectedTo := nc .ConnectedUrl ()
843
+ expected := []string {s1Url }
844
+ if reConnectedTo == s2Url {
845
+ s2 .Shutdown ()
846
+ expected = append (expected , s3Url )
847
+ } else if reConnectedTo == s3Url {
848
+ s3 .Shutdown ()
849
+ expected = append (expected , s2Url )
850
+ } else {
851
+ t .Fatalf ("Unexpected server client has reconnected to: %v" , reConnectedTo )
781
852
}
782
- if ! ok {
783
- t .Fatalf ("List of servers should be only 1, got %v" , ds )
853
+ // Wait for reconnect
854
+ if err := wait (chch ); err != nil {
855
+ t .Fatal ("Reconnect handler not invoked" )
784
856
}
857
+ // The implicit server that we just shutdown should have been removed from the pool
858
+ checkPool (expected )
859
+ nc .Close ()
785
860
}
0 commit comments