absurdfarce commented on code in PR #1743:
URL:
https://github.com/apache/cassandra-java-driver/pull/1743#discussion_r1638440588
##########
core/src/main/java/com/datastax/oss/driver/internal/core/loadbalancing/DefaultLoadBalancingPolicy.java:
##########
@@ -96,14 +100,39 @@ public class DefaultLoadBalancingPolicy extends
BasicLoadBalancingPolicy impleme
private static final int MAX_IN_FLIGHT_THRESHOLD = 10;
private static final long RESPONSE_COUNT_RESET_INTERVAL_NANOS =
MILLISECONDS.toNanos(200);
- protected final Map<Node, AtomicLongArray> responseTimes = new
ConcurrentHashMap<>();
+ protected final LoadingCache<Node, NodeResponseRateSample> responseTimes;
protected final Map<Node, Long> upTimes = new ConcurrentHashMap<>();
private final boolean avoidSlowReplicas;
public DefaultLoadBalancingPolicy(@NonNull DriverContext context, @NonNull
String profileName) {
super(context, profileName);
this.avoidSlowReplicas =
profile.getBoolean(DefaultDriverOption.LOAD_BALANCING_POLICY_SLOW_AVOIDANCE,
true);
+ CacheLoader<Node, NodeResponseRateSample> cacheLoader =
+ new CacheLoader<Node, NodeResponseRateSample>() {
+ @Override
+ public NodeResponseRateSample load(Node key) {
+ NodeResponseRateSample sample = responseTimes.getIfPresent(key);
+ if (sample == null) {
+ sample = new NodeResponseRateSample();
+ } else {
+ sample.update();
+ }
+ return sample;
+ }
+ };
Review Comment:
To make this more concrete: I got the relevant test case
(DefaultLoadBalancingPolicyRequestTrackerTest) with the following changes:
```java
protected final ConcurrentMap<Node, NodeResponseRateSample> responseTimes;
protected final Map<Node, Long> upTimes = new ConcurrentHashMap<>();
private final boolean avoidSlowReplicas;
public DefaultLoadBalancingPolicy(@NonNull DriverContext context, @NonNull
String profileName) {
super(context, profileName);
this.avoidSlowReplicas =
profile.getBoolean(DefaultDriverOption.LOAD_BALANCING_POLICY_SLOW_AVOIDANCE,
true);
this.responseTimes =
new MapMaker().weakKeys().makeMap();
}
...
protected void updateResponseTimes(@NonNull Node node) {
this.responseTimes.compute(node, (k,v) -> v == null ? new
NodeResponseRateSample() : v.next());
}
...
// Exposed as protected for unit tests
protected class NodeResponseRateSample {
@VisibleForTesting
protected final long oldest;
@VisibleForTesting
protected final OptionalLong newest;
private NodeResponseRateSample() {
long now = nanoTime();
this.oldest = now;
this.newest = OptionalLong.empty();
}
private NodeResponseRateSample(long oldestSample) {
this(oldestSample, nanoTime());
}
private NodeResponseRateSample(long oldestSample, long newestSample) {
this.oldest = oldestSample;
this.newest = OptionalLong.of(newestSample);
}
@VisibleForTesting
protected NodeResponseRateSample(AtomicLongArray times) {
assert times.length() >= 1;
this.oldest = times.get(0);
this.newest = (times.length() > 1) ? OptionalLong.of(times.get(1)) :
OptionalLong.empty();
}
// Our newest sample becomes the oldest in the next generation
private NodeResponseRateSample next() {
return new NodeResponseRateSample(this.getNewestValidSample(),
nanoTime());
}
// If we have a pair of values return the newest, otherwise we have just
one value... so just return it
private long getNewestValidSample() { return
this.newest.orElse(this.oldest); }
// response rate is considered insufficient when less than 2 responses
were obtained in
// the past interval delimited by RESPONSE_COUNT_RESET_INTERVAL_NANOS.
private boolean hasSufficientResponses(long now) {
// If we only have one sample it's an automatic failure
if (!this.newest.isPresent())
return false;
long threshold = now - RESPONSE_COUNT_RESET_INTERVAL_NANOS;
return this.oldest - threshold >= 0;
}
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]