From fcd728ac71960a19c273769133c10a07c43fa68d Mon Sep 17 00:00:00 2001 From: syermakov Date: Thu, 12 May 2022 19:50:14 +0300 Subject: [PATCH] Fix broken order in seed node selection logic in case of network timeouts --- .../internal/gossip/GossipSeedNodesSate.java | 8 ++++-- .../gossip/GossipSeedNodesSateTest.java | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/hekate-core/src/main/java/io/hekate/cluster/internal/gossip/GossipSeedNodesSate.java b/hekate-core/src/main/java/io/hekate/cluster/internal/gossip/GossipSeedNodesSate.java index 56f57f7c..f988d651 100644 --- a/hekate-core/src/main/java/io/hekate/cluster/internal/gossip/GossipSeedNodesSate.java +++ b/hekate-core/src/main/java/io/hekate/cluster/internal/gossip/GossipSeedNodesSate.java @@ -34,6 +34,8 @@ private enum Status { RETRY, + TIMEOUT, + FAILED, BAN @@ -211,7 +213,7 @@ public void onFailure(InetSocketAddress seed, Throwable cause) { log.warn("Seed node timeout ...will retry [address={}, cause={}]", s.address(), String.valueOf(cause)); } - s.updateStatus(Status.RETRY); + s.updateStatus(Status.TIMEOUT); } else { if (log.isWarnEnabled()) { log.warn("Couldn't contact seed node [address={}, cause={}]", s.address(), String.valueOf(cause)); @@ -235,7 +237,9 @@ public void onBan(InetSocketAddress seed) { } private boolean triedAllNodes() { - return seeds.stream().allMatch(s -> s.address().equals(localAddress) || s.status() != Status.NEW); + return seeds.stream().allMatch(s -> + s.address().equals(localAddress) || (s.status() != Status.NEW && s.status() != Status.TIMEOUT) + ); } private boolean isNetworkTimeout(Throwable cause) { diff --git a/hekate-core/src/test/java/io/hekate/cluster/internal/gossip/GossipSeedNodesSateTest.java b/hekate-core/src/test/java/io/hekate/cluster/internal/gossip/GossipSeedNodesSateTest.java index 468d085a..ddb6c7e9 100644 --- a/hekate-core/src/test/java/io/hekate/cluster/internal/gossip/GossipSeedNodesSateTest.java +++ b/hekate-core/src/test/java/io/hekate/cluster/internal/gossip/GossipSeedNodesSateTest.java @@ -17,6 +17,7 @@ package io.hekate.cluster.internal.gossip; import io.hekate.HekateTestBase; +import io.hekate.network.NetworkConnectTimeoutException; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.HashSet; @@ -58,6 +59,30 @@ public void testNextSeed() throws Exception { }); } + @Test + public void testOrderOnNetworkTimeout() throws Exception { + List seeds = new ArrayList<>(); + + seeds.add(newSocketAddress(100)); + seeds.add(newSocketAddress(200)); + seeds.add(newSocketAddress(300)); + + for (int localPort = 0; localPort <= 303; localPort += 101) { + say("Local port: " + localPort); + + GossipSeedNodesSate s = new GossipSeedNodesSate(newSocketAddress(localPort), seeds, false); + + repeat(3, i -> + seeds.forEach(seed -> { + assertFalse(s.isSelfJoin()); + assertEquals(seed, s.nextSeed(false)); + + s.onFailure(seed, new NetworkConnectTimeoutException(TEST_ERROR.getMessage())); + }) + ); + } + } + @Test public void testNextSeedBusy() throws Exception { List seeds = new ArrayList<>();