From 6144dec3b5d2c767efe36c9e84f36fc13c93e959 Mon Sep 17 00:00:00 2001 From: Vasiliy Mikhailov Date: Sat, 27 Jun 2026 04:09:42 +0000 Subject: [PATCH] Initialize checkStamp in LatencyFaultToleranceImpl.FaultItem FaultItem never set checkStamp, so it defaulted to 0 and detectByOneRound treated every fault item as ready to detect on every round, ignoring detectInterval. Initialize checkStamp to now plus detectInterval in the constructor. --- .../latency/LatencyFaultToleranceImpl.java | 1 + .../LatencyFaultToleranceImplTest.java | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/client/src/main/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImpl.java b/client/src/main/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImpl.java index db8bbd66ef2..e4f3e50e7c2 100644 --- a/client/src/main/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImpl.java +++ b/client/src/main/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImpl.java @@ -202,6 +202,7 @@ public class FaultItem implements Comparable { public FaultItem(final String name) { this.name = name; + this.checkStamp = System.currentTimeMillis() + LatencyFaultToleranceImpl.this.detectInterval; } public void updateNotAvailableDuration(long notAvailableDuration) { diff --git a/client/src/test/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImplTest.java b/client/src/test/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImplTest.java index 42ccdae5a48..e3ea29065cf 100644 --- a/client/src/test/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImplTest.java +++ b/client/src/test/java/org/apache/rocketmq/client/latency/LatencyFaultToleranceImplTest.java @@ -19,11 +19,17 @@ import org.awaitility.core.ThrowingRunnable; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class LatencyFaultToleranceImplTest { private LatencyFaultTolerance latencyFaultTolerance; @@ -80,4 +86,19 @@ public void testIsReachable() throws Exception { latencyFaultTolerance.updateFaultItem(anotherBrokerName, 1001, 3000, false); assertThat(latencyFaultTolerance.isReachable(anotherBrokerName)).isEqualTo(false); } -} \ No newline at end of file + + @Test + public void testDetectByOneRoundRespectsDetectInterval() throws Exception { + Resolver resolver = mock(Resolver.class); + ServiceDetector serviceDetector = mock(ServiceDetector.class); + when(resolver.resolve(brokerName)).thenReturn("127.0.0.1:10911"); + when(serviceDetector.detect(anyString(), anyLong())).thenReturn(true); + + LatencyFaultToleranceImpl impl = new LatencyFaultToleranceImpl(resolver, serviceDetector); + impl.setDetectInterval(3600000); // 1 hour + impl.updateFaultItem(brokerName, 1000, 0, true); + // fresh FaultItem must wait detectInterval before its first detect + impl.detectByOneRound(); + verify(serviceDetector, Mockito.never()).detect(anyString(), anyLong()); + } +}