Skip to content

Commit

Permalink
loadbalancer: move health check related constants to the HealthCheck …
Browse files Browse the repository at this point in the history
…class (#2764)

Motivation:

We're going to want to use these constants in a few places but they're
currently a private field of the RoundRobinLoadBalancerFactory.

Modifications:

- move the constants to the HealthCheckConfig class
- turn the durations into longs in the HealtCheckConfig instances

Result:

More sharable constants.
  • Loading branch information
bryce-anderson authored Nov 27, 2023
1 parent 0879b30 commit 623c32a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,18 @@

import java.time.Duration;

import static io.servicetalk.utils.internal.DurationUtils.ensureNonNegative;
import static io.servicetalk.utils.internal.DurationUtils.ensurePositive;
import static io.servicetalk.utils.internal.DurationUtils.isPositive;
import static java.time.Duration.ofSeconds;

final class HealthCheckConfig {

static final Duration DEFAULT_HEALTH_CHECK_INTERVAL = ofSeconds(5);
static final Duration DEFAULT_HEALTH_CHECK_JITTER = ofSeconds(3);
static final Duration DEFAULT_HEALTH_CHECK_RESUBSCRIBE_INTERVAL = ofSeconds(10);
static final int DEFAULT_HEALTH_CHECK_FAILED_CONNECTIONS_THRESHOLD = 5; // higher than default for AutoRetryStrategy

final Executor executor;
final Duration healthCheckInterval;
final Duration jitter;
Expand All @@ -28,13 +39,30 @@ final class HealthCheckConfig {
final long healthCheckResubscribeUpperBound;

HealthCheckConfig(final Executor executor, final Duration healthCheckInterval, final Duration healthCheckJitter,
final int failedThreshold, final long healthCheckResubscribeLowerBound,
final long healthCheckResubscribeUpperBound) {
final int failedThreshold, final Duration resubscribeInterval,
final Duration healthCheckResubscribeJitter) {
this.executor = executor;
this.healthCheckInterval = healthCheckInterval;
this.failedThreshold = failedThreshold;
this.jitter = healthCheckJitter;
this.healthCheckResubscribeLowerBound = healthCheckResubscribeLowerBound;
this.healthCheckResubscribeUpperBound = healthCheckResubscribeUpperBound;

validateHealthCheckIntervals(resubscribeInterval, healthCheckResubscribeJitter);
this.healthCheckResubscribeLowerBound = resubscribeInterval.minus(healthCheckResubscribeJitter).toNanos();
this.healthCheckResubscribeUpperBound = resubscribeInterval.plus(healthCheckResubscribeJitter).toNanos();
}

static void validateHealthCheckIntervals(Duration interval, Duration jitter) {
ensurePositive(interval, "interval");
ensureNonNegative(jitter, "jitter");
final Duration lowerBound = interval.minus(jitter);
if (!isPositive(lowerBound)) {
throw new IllegalArgumentException("interval (" + interval + ") minus jitter (" + jitter +
") must be greater than 0, current=" + lowerBound);
}
final Duration upperBound = interval.plus(jitter);
if (!isPositive(upperBound)) {
throw new IllegalArgumentException("interval (" + interval + ") plus jitter (" + jitter +
") must not overflow, current=" + upperBound);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
import java.util.concurrent.ThreadPoolExecutor;
import javax.annotation.Nullable;

import static io.servicetalk.utils.internal.DurationUtils.ensureNonNegative;
import static io.servicetalk.utils.internal.DurationUtils.ensurePositive;
import static io.servicetalk.utils.internal.DurationUtils.isPositive;
import static java.time.Duration.ofSeconds;
import static io.servicetalk.loadbalancer.HealthCheckConfig.DEFAULT_HEALTH_CHECK_FAILED_CONNECTIONS_THRESHOLD;
import static io.servicetalk.loadbalancer.HealthCheckConfig.DEFAULT_HEALTH_CHECK_INTERVAL;
import static io.servicetalk.loadbalancer.HealthCheckConfig.DEFAULT_HEALTH_CHECK_JITTER;
import static io.servicetalk.loadbalancer.HealthCheckConfig.DEFAULT_HEALTH_CHECK_RESUBSCRIBE_INTERVAL;
import static io.servicetalk.loadbalancer.HealthCheckConfig.validateHealthCheckIntervals;
import static java.util.concurrent.TimeUnit.SECONDS;

/**
Expand All @@ -53,11 +54,6 @@
public final class RoundRobinLoadBalancerFactory<ResolvedAddress, C extends LoadBalancedConnection>
implements LoadBalancerFactory<ResolvedAddress, C> {

private static final Duration DEFAULT_HEALTH_CHECK_INTERVAL = ofSeconds(5);
private static final Duration DEFAULT_HEALTH_CHECK_JITTER = ofSeconds(3);
static final Duration DEFAULT_HEALTH_CHECK_RESUBSCRIBE_INTERVAL = ofSeconds(10);
static final int DEFAULT_HEALTH_CHECK_FAILED_CONNECTIONS_THRESHOLD = 5; // higher than default for AutoRetryStrategy

private final String id;
private final int linearSearchSpace;
private final boolean useNewRoundRobin;
Expand Down Expand Up @@ -123,10 +119,8 @@ public static final class Builder<ResolvedAddress, C extends LoadBalancedConnect
private Duration healthCheckInterval = DEFAULT_HEALTH_CHECK_INTERVAL;
private Duration healthCheckJitter = DEFAULT_HEALTH_CHECK_JITTER;
private int healthCheckFailedConnectionsThreshold = DEFAULT_HEALTH_CHECK_FAILED_CONNECTIONS_THRESHOLD;
private long healthCheckResubscribeLowerBound =
DEFAULT_HEALTH_CHECK_RESUBSCRIBE_INTERVAL.minus(DEFAULT_HEALTH_CHECK_JITTER).toNanos();
private long healthCheckResubscribeUpperBound =
DEFAULT_HEALTH_CHECK_RESUBSCRIBE_INTERVAL.plus(DEFAULT_HEALTH_CHECK_JITTER).toNanos();;
private Duration healthCheckResubscribeInterval = DEFAULT_HEALTH_CHECK_RESUBSCRIBE_INTERVAL;
private Duration healthCheckResubscribeJitter = DEFAULT_HEALTH_CHECK_JITTER;

/**
* Creates a new instance with default settings.
Expand Down Expand Up @@ -190,7 +184,7 @@ public RoundRobinLoadBalancerFactory.Builder<ResolvedAddress, C> healthCheckInte
@Override
public RoundRobinLoadBalancerFactory.Builder<ResolvedAddress, C> healthCheckInterval(Duration interval,
Duration jitter) {
validate(interval, jitter);
validateHealthCheckIntervals(interval, jitter);
this.healthCheckInterval = interval;
this.healthCheckJitter = jitter;
return this;
Expand All @@ -199,27 +193,12 @@ public RoundRobinLoadBalancerFactory.Builder<ResolvedAddress, C> healthCheckInte
@Override
public RoundRobinLoadBalancerFactory.Builder<ResolvedAddress, C> healthCheckResubscribeInterval(
Duration interval, Duration jitter) {
validate(interval, jitter);
this.healthCheckResubscribeLowerBound = interval.minus(jitter).toNanos();
this.healthCheckResubscribeUpperBound = interval.plus(jitter).toNanos();
validateHealthCheckIntervals(interval, jitter);
this.healthCheckResubscribeInterval = interval;
this.healthCheckResubscribeJitter = jitter;
return this;
}

private static void validate(Duration interval, Duration jitter) {
ensurePositive(interval, "interval");
ensureNonNegative(jitter, "jitter");
final Duration lowerBound = interval.minus(jitter);
if (!isPositive(lowerBound)) {
throw new IllegalArgumentException("interval (" + interval + ") minus jitter (" + jitter +
") must be greater than 0, current=" + lowerBound);
}
final Duration upperBound = interval.plus(jitter);
if (!isPositive(upperBound)) {
throw new IllegalArgumentException("interval (" + interval + ") plus jitter (" + jitter +
") must not overflow, current=" + upperBound);
}
}

@Override
public RoundRobinLoadBalancerFactory.Builder<ResolvedAddress, C> healthCheckFailedConnectionsThreshold(
int threshold) {
Expand All @@ -239,7 +218,7 @@ public RoundRobinLoadBalancerFactory<ResolvedAddress, C> build() {
HealthCheckConfig healthCheckConfig = new HealthCheckConfig(
this.backgroundExecutor == null ? SharedExecutor.getInstance() : this.backgroundExecutor,
healthCheckInterval, healthCheckJitter, healthCheckFailedConnectionsThreshold,
healthCheckResubscribeLowerBound, healthCheckResubscribeUpperBound);
healthCheckResubscribeInterval, healthCheckResubscribeJitter);
return new RoundRobinLoadBalancerFactory<>(id, linearSearchSpace, useNewRoundRobin, healthCheckConfig);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@
import static io.servicetalk.concurrent.api.SourceAdapters.toSource;
import static io.servicetalk.concurrent.internal.DeliberateException.DELIBERATE_EXCEPTION;
import static io.servicetalk.concurrent.internal.TestTimeoutConstants.DEFAULT_TIMEOUT_SECONDS;
import static io.servicetalk.loadbalancer.RoundRobinLoadBalancerFactory.DEFAULT_HEALTH_CHECK_FAILED_CONNECTIONS_THRESHOLD;
import static io.servicetalk.loadbalancer.RoundRobinLoadBalancerFactory.DEFAULT_HEALTH_CHECK_RESUBSCRIBE_INTERVAL;
import static io.servicetalk.loadbalancer.HealthCheckConfig.DEFAULT_HEALTH_CHECK_FAILED_CONNECTIONS_THRESHOLD;
import static io.servicetalk.loadbalancer.HealthCheckConfig.DEFAULT_HEALTH_CHECK_RESUBSCRIBE_INTERVAL;
import static io.servicetalk.loadbalancer.RoundRobinLoadBalancerTest.UnhealthyHostConnectionFactory.UNHEALTHY_HOST_EXCEPTION;
import static java.lang.Long.MAX_VALUE;
import static java.time.Duration.ZERO;
Expand Down

0 comments on commit 623c32a

Please sign in to comment.