Skip to content

Commit bacbd5a

Browse files
Fix ConfigNode client failover with stale candidates (#18847)
Refresh candidates before fallback selection and resume after the current endpoint. Preserve candidates and cursor on empty refreshes. Add routing and connection tests and re-enable node status failover IT.
1 parent c6f86b5 commit bacbd5a

4 files changed

Lines changed: 672 additions & 13 deletions

File tree

‎integration-test/src/test/java/org/apache/iotdb/confignode/it/cluster/IoTDBNodeStatusFailoverIT.java‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
import com.sun.tools.attach.VirtualMachine;
3838
import org.apache.tsfile.utils.Pair;
3939
import org.junit.After;
40-
import org.junit.Ignore;
4140
import org.junit.Rule;
41+
import org.junit.Test;
4242
import org.junit.experimental.categories.Category;
4343
import org.junit.rules.ErrorCollector;
4444
import org.junit.rules.TemporaryFolder;
@@ -77,7 +77,6 @@
7777
/** Process-level status persistence checks with three actual ConfigRegion voters. */
7878
@RunWith(IoTDBTestRunner.class)
7979
@Category(ClusterIT.class)
80-
@Ignore("Temporarily skip IoTDBNodeStatusFailoverIT")
8180
public class IoTDBNodeStatusFailoverIT {
8281
@Rule public TemporaryFolder temporary = new TemporaryFolder();
8382
@Rule public ErrorCollector failures = new ErrorCollector();
@@ -89,7 +88,7 @@ public void tearDown() {
8988
EnvFactory.getEnv().cleanClusterEnvironment();
9089
}
9190

92-
// @Test
91+
@Test
9392
public void testGracefulLeaderShutdownPreservesStoppedAndRemoving() throws Exception {
9493
init(3);
9594
int stopped = stoppedFixture(0);
@@ -114,7 +113,7 @@ public void testGracefulLeaderShutdownPreservesStoppedAndRemoving() throws Excep
114113
assertStatus(1, removing, NodeStatus.Removing);
115114
}
116115

117-
// @Test
116+
@Test
118117
public void testGracefulSeedShutdownReportsStopped() throws Exception {
119118
init(1);
120119
transfer(1);
@@ -137,7 +136,7 @@ public void testGracefulSeedShutdownReportsStopped() throws Exception {
137136
awaitPersisted(2, seedId, null);
138137
}
139138

140-
// @Test
139+
@Test
141140
public void testForcedLeaderShutdownWithTwoDataNodes() throws Exception {
142141
init(2);
143142
int stopped = stoppedFixture(0);
@@ -157,7 +156,7 @@ public void testForcedLeaderShutdownWithTwoDataNodes() throws Exception {
157156
assertStatus(0, stopped, NodeStatus.Stopped);
158157
}
159158

160-
// @Test
159+
@Test
161160
public void testNewLeaderChangesSurviveReturnToOriginalLeader() throws Exception {
162161
init(3);
163162
int stopped = stoppedFixture(0);
@@ -181,7 +180,7 @@ public void testNewLeaderChangesSurviveReturnToOriginalLeader() throws Exception
181180
assertStatus(1, removing, NodeStatus.Unknown);
182181
}
183182

184-
// @Test
183+
@Test
185184
public void testReadOnlyReasonPersistsAcrossLeaderTransferAndClearsAfterRestart()
186185
throws Exception {
187186
init(2);
@@ -230,7 +229,7 @@ public void testReadOnlyReasonPersistsAcrossLeaderTransferAndClearsAfterRestart(
230229
}
231230
}
232231

233-
// @Test
232+
@Test
234233
public void testLiveOldLeaderPartitionAndQuorumRecovery() throws Exception {
235234
init(3);
236235
int stopped = stoppedFixture(0);
@@ -299,7 +298,7 @@ private void init(int dataNodes) throws Exception {
299298
}
300299
}
301300

302-
// @Test
301+
@Test
303302
public void testNoQuorumTransitionMatrix() throws Exception {
304303
init(2);
305304
int nodeId = stoppedFixture(0);
@@ -362,7 +361,7 @@ public void testNoQuorumTransitionMatrix() throws Exception {
362361
}
363362
}
364363

365-
// @Test
364+
@Test
366365
public void testSnapshotAndFollowingClearLogRecoverTogether() throws Exception {
367366
init(3);
368367
int stopped = stoppedFixture(0);
@@ -458,7 +457,7 @@ private void awaitConfigNodeRunning(int index) {
458457
Collections.singletonList(NodeStatus.Running));
459458
}
460459

461-
// @Test
460+
@Test
462461
public void testRealRemovalPersistsIntentAndDeletesRegistration() throws Exception {
463462
EnvFactory.getEnv()
464463
.getConfig()

‎iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/client/AbstractConfigNodeClient.java‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,11 @@ private void tryToConnect(int timeoutMs) throws TException {
322322
}
323323
}
324324

325+
// Refresh stale candidates before retrying after an RPC or connection failure.
326+
syncLatestConfigNodeList();
327+
if (configNode != null) {
328+
cursor = configNodes.indexOf(configNode);
329+
}
325330
for (int tryHostNum = 0; tryHostNum < configNodes.size(); tryHostNum++) {
326331
cursor = (cursor + 1) % configNodes.size();
327332
TEndPoint tryEndpoint = configNodes.get(cursor);
@@ -345,8 +350,11 @@ private void tryToConnect(int timeoutMs) throws TException {
345350
}
346351

347352
public void syncLatestConfigNodeList() {
348-
configNodes = getConfigNodeInfo().getLatestConfigNodes();
349-
cursor = 0;
353+
final List<TEndPoint> latestConfigNodes = getConfigNodeInfo().getLatestConfigNodes();
354+
if (!latestConfigNodes.isEmpty()) {
355+
configNodes = latestConfigNodes;
356+
cursor = 0;
357+
}
350358
}
351359

352360
@Override

0 commit comments

Comments
 (0)