[FIXED] Explicit gateway not using discovered URLs

If cluster A configures a gateway to cluster B, the server on A
tries to connect to that server URL. If there is no server on B
at that address, but a server on B with different address connects
to server on cluster A, that server should be able to create its
outbound connection in response.
That was not the case because the configured URLs were snapshot
before the loop of trying to connect. When accepting an inbound
connection and updating the array, this new URL was not being used.

The issue is only if the server on A had no outbound connection
at that time.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
This commit is contained in:
Ivan Kozlovic
2019-10-24 16:40:38 -06:00
parent d304c9b1e8
commit 75ec78c232
2 changed files with 33 additions and 2 deletions

View File

@@ -580,7 +580,6 @@ func (s *Server) solicitGateway(cfg *gatewayCfg, firstConnect bool) {
var (
opts = s.getOpts()
isImplicit = cfg.isImplicit()
urls = cfg.getURLs()
attempts int
typeStr string
)
@@ -593,7 +592,11 @@ func (s *Server) solicitGateway(cfg *gatewayCfg, firstConnect bool) {
const connFmt = "Connecting to %s gateway %q (%s) at %s (attempt %v)"
const connErrFmt = "Error connecting to %s gateway %q (%s) at %s (attempt %v): %v"
for s.isRunning() && len(urls) > 0 {
for s.isRunning() {
urls := cfg.getURLs()
if len(urls) == 0 {
break
}
attempts++
report := s.shouldReportConnectErr(firstConnect, attempts)
// Iteration is random

View File

@@ -1098,6 +1098,34 @@ func TestGatewayURLsFromClusterSentInINFO(t *testing.T) {
}
}
func TestGatewayUseUpdatedURLs(t *testing.T) {
// For this test, we have cluster B with an explicit gateway to cluster A
// on a given URL. Then we create cluster A with a gateway to B with server B's
// GW url, and we expect server B to ultimately create an outbound GW connection
// to server A (with the URL it will get from server A connecting to it).
ob := testGatewayOptionsFromToWithURLs(t, "B", "A", []string{"nats://127.0.0.1:1234"})
sb := runGatewayServer(ob)
defer sb.Shutdown()
// Add a delay before starting server A to make sure that server B start
// initiating the connection to A on inexistant server at :1234.
time.Sleep(100 * time.Millisecond)
oa := testGatewayOptionsFromToWithServers(t, "A", "B", sb)
sa := runGatewayServer(oa)
defer sa.Shutdown()
// sa should have no problem creating outbound connection to sb
waitForOutboundGateways(t, sa, 1, time.Second)
// Make sure that since sb learns about sa's GW URL, it can successfully
// connect to it.
waitForOutboundGateways(t, sb, 1, 3*time.Second)
waitForInboundGateways(t, sb, 1, time.Second)
waitForInboundGateways(t, sa, 1, time.Second)
}
func TestGatewayAutoDiscovery(t *testing.T) {
o4 := testDefaultOptionsForGateway("D")
s4 := runGatewayServer(o4)