mirror of https://github.com/grpc/grpc-java.git
util: OutlierDetection should use Ticker, not TimeProvider (#12110)
TimeProvider provides wall time. That can move forward and backward as time is adjusted. OutlierDetection is measuring durations, so it should use a monotonic clock. Fixes #11622
This commit is contained in:
parent
d5b4fb51c2
commit
1c43098990
|
@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkState;
|
|||
import static java.util.concurrent.TimeUnit.NANOSECONDS;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Ticker;
|
||||
import com.google.common.collect.ForwardingMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -39,7 +40,6 @@ import io.grpc.Metadata;
|
|||
import io.grpc.Status;
|
||||
import io.grpc.SynchronizationContext;
|
||||
import io.grpc.SynchronizationContext.ScheduledHandle;
|
||||
import io.grpc.internal.TimeProvider;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -82,7 +82,7 @@ public final class OutlierDetectionLoadBalancer extends LoadBalancer {
|
|||
private final SynchronizationContext syncContext;
|
||||
private final Helper childHelper;
|
||||
private final GracefulSwitchLoadBalancer switchLb;
|
||||
private TimeProvider timeProvider;
|
||||
private Ticker ticker;
|
||||
private final ScheduledExecutorService timeService;
|
||||
private ScheduledHandle detectionTimerHandle;
|
||||
private Long detectionTimerStartNanos;
|
||||
|
@ -95,14 +95,14 @@ public final class OutlierDetectionLoadBalancer extends LoadBalancer {
|
|||
/**
|
||||
* Creates a new instance of {@link OutlierDetectionLoadBalancer}.
|
||||
*/
|
||||
public OutlierDetectionLoadBalancer(Helper helper, TimeProvider timeProvider) {
|
||||
public OutlierDetectionLoadBalancer(Helper helper, Ticker ticker) {
|
||||
logger = helper.getChannelLogger();
|
||||
childHelper = new ChildHelper(checkNotNull(helper, "helper"));
|
||||
switchLb = new GracefulSwitchLoadBalancer(childHelper);
|
||||
endpointTrackerMap = new EndpointTrackerMap();
|
||||
this.syncContext = checkNotNull(helper.getSynchronizationContext(), "syncContext");
|
||||
this.timeService = checkNotNull(helper.getScheduledExecutorService(), "timeService");
|
||||
this.timeProvider = timeProvider;
|
||||
this.ticker = ticker;
|
||||
logger.log(ChannelLogLevel.DEBUG, "OutlierDetection lb created.");
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ public final class OutlierDetectionLoadBalancer extends LoadBalancer {
|
|||
// If a timer has started earlier we cancel it and use the difference between the start
|
||||
// time and now as the interval.
|
||||
initialDelayNanos = Math.max(0L,
|
||||
config.intervalNanos - (timeProvider.currentTimeNanos() - detectionTimerStartNanos));
|
||||
config.intervalNanos - (ticker.read() - detectionTimerStartNanos));
|
||||
}
|
||||
|
||||
// If a timer has been previously created we need to cancel it and reset all the call counters
|
||||
|
@ -201,7 +201,7 @@ public final class OutlierDetectionLoadBalancer extends LoadBalancer {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
detectionTimerStartNanos = timeProvider.currentTimeNanos();
|
||||
detectionTimerStartNanos = ticker.read();
|
||||
|
||||
endpointTrackerMap.swapCounters();
|
||||
|
||||
|
@ -638,7 +638,7 @@ public final class OutlierDetectionLoadBalancer extends LoadBalancer {
|
|||
config.baseEjectionTimeNanos * ejectionTimeMultiplier,
|
||||
maxEjectionDurationSecs);
|
||||
|
||||
return currentTimeNanos > maxEjectionTimeNanos;
|
||||
return currentTimeNanos - maxEjectionTimeNanos > 0;
|
||||
}
|
||||
|
||||
/** Tracks both successful and failed call counts. */
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package io.grpc.util;
|
||||
|
||||
import com.google.common.base.Ticker;
|
||||
import io.grpc.Internal;
|
||||
import io.grpc.LoadBalancer;
|
||||
import io.grpc.LoadBalancer.Helper;
|
||||
|
@ -23,7 +24,6 @@ import io.grpc.LoadBalancerProvider;
|
|||
import io.grpc.NameResolver.ConfigOrError;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.internal.JsonUtil;
|
||||
import io.grpc.internal.TimeProvider;
|
||||
import io.grpc.util.OutlierDetectionLoadBalancer.OutlierDetectionLoadBalancerConfig;
|
||||
import io.grpc.util.OutlierDetectionLoadBalancer.OutlierDetectionLoadBalancerConfig.FailurePercentageEjection;
|
||||
import io.grpc.util.OutlierDetectionLoadBalancer.OutlierDetectionLoadBalancerConfig.SuccessRateEjection;
|
||||
|
@ -34,7 +34,7 @@ public final class OutlierDetectionLoadBalancerProvider extends LoadBalancerProv
|
|||
|
||||
@Override
|
||||
public LoadBalancer newLoadBalancer(Helper helper) {
|
||||
return new OutlierDetectionLoadBalancer(helper, TimeProvider.SYSTEM_TIME_PROVIDER);
|
||||
return new OutlierDetectionLoadBalancer(helper, Ticker.systemTicker());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -227,7 +227,7 @@ public class OutlierDetectionLoadBalancerTest {
|
|||
when(mockStreamTracerFactory.newClientStreamTracer(any(),
|
||||
any())).thenReturn(mockStreamTracer);
|
||||
|
||||
loadBalancer = new OutlierDetectionLoadBalancer(mockHelper, fakeClock.getTimeProvider());
|
||||
loadBalancer = new OutlierDetectionLoadBalancer(mockHelper, fakeClock.getTicker());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue