Skip to content

Commit da619e2

Browse files
committedApr 25, 2024·
rls: Fix time handling in CachingRlsLbClient
`getMinEvictionTime()` was fixed to make sure only deltas were used for comparisons (`a < b` is broken; `a - b < 0` is okay). It had also returned `0` by default, which was meaningless as there is no epoch for `System.nanoTime()`. LinkedHashLruCache now passes the current time into a few more functions since the implementations need it and it was sometimes already available. This made it easier to make some classes static.
1 parent 0561954 commit da619e2

File tree

2 files changed

+15
-22
lines changed

2 files changed

+15
-22
lines changed
 

Diff for: ‎rls/src/main/java/io/grpc/rls/CachingRlsLbClient.java

+9-13
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ public String toString() {
528528
}
529529

530530
/** Common cache entry data for {@link RlsAsyncLruCache}. */
531-
abstract class CacheEntry {
531+
abstract static class CacheEntry {
532532

533533
protected final RouteLookupRequest request;
534534

@@ -538,16 +538,12 @@ abstract class CacheEntry {
538538

539539
abstract int getSizeBytes();
540540

541-
final boolean isExpired() {
542-
return isExpired(ticker.read());
543-
}
544-
545541
abstract boolean isExpired(long now);
546542

547543
abstract void cleanup();
548544

549-
protected long getMinEvictionTime() {
550-
return 0L;
545+
protected boolean isOldEnoughToBeEvicted(long now) {
546+
return true;
551547
}
552548
}
553549

@@ -649,8 +645,8 @@ boolean isStaled(long now) {
649645
}
650646

651647
@Override
652-
protected long getMinEvictionTime() {
653-
return minEvictionTime;
648+
protected boolean isOldEnoughToBeEvicted(long now) {
649+
return minEvictionTime - now <= 0;
654650
}
655651

656652
@Override
@@ -678,7 +674,7 @@ public String toString() {
678674
* Implementation of {@link CacheEntry} contains error. This entry will transition to pending
679675
* status when the backoff time is expired.
680676
*/
681-
private final class BackoffCacheEntry extends CacheEntry {
677+
private static final class BackoffCacheEntry extends CacheEntry {
682678

683679
private final Status status;
684680
private final BackoffPolicy backoffPolicy;
@@ -841,7 +837,7 @@ private static final class RlsAsyncLruCache
841837

842838
@Override
843839
protected boolean isExpired(RouteLookupRequest key, CacheEntry value, long nowNanos) {
844-
return value.isExpired();
840+
return value.isExpired(nowNanos);
845841
}
846842

847843
@Override
@@ -851,8 +847,8 @@ protected int estimateSizeOf(RouteLookupRequest key, CacheEntry value) {
851847

852848
@Override
853849
protected boolean shouldInvalidateEldestEntry(
854-
RouteLookupRequest eldestKey, CacheEntry eldestValue) {
855-
if (eldestValue.getMinEvictionTime() > now()) {
850+
RouteLookupRequest eldestKey, CacheEntry eldestValue, long now) {
851+
if (!eldestValue.isOldEnoughToBeEvicted(now)) {
856852
return false;
857853
}
858854

Diff for: ‎rls/src/main/java/io/grpc/rls/LinkedHashLruCache.java

+6-9
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ protected boolean removeEldestEntry(Map.Entry<K, SizedValue> eldest) {
8585
// first, remove at most 1 expired entry
8686
boolean removed = cleanupExpiredEntries(1, ticker.read());
8787
// handles size based eviction if necessary no expired entry
88-
boolean shouldRemove =
89-
!removed && shouldInvalidateEldestEntry(eldest.getKey(), eldest.getValue().value);
88+
boolean shouldRemove = !removed
89+
&& shouldInvalidateEldestEntry(eldest.getKey(), eldest.getValue().value, ticker.read());
9090
if (shouldRemove) {
9191
// remove entry by us to make sure lruIterator and cache is in sync
9292
LinkedHashLruCache.this.invalidate(eldest.getKey(), EvictionType.SIZE);
@@ -102,7 +102,7 @@ protected boolean removeEldestEntry(Map.Entry<K, SizedValue> eldest) {
102102
* that LruCache is access level and the eldest is determined by access pattern.
103103
*/
104104
@SuppressWarnings("unused")
105-
protected boolean shouldInvalidateEldestEntry(K eldestKey, V eldestValue) {
105+
protected boolean shouldInvalidateEldestEntry(K eldestKey, V eldestValue, long now) {
106106
return true;
107107
}
108108

@@ -236,10 +236,6 @@ public final List<V> values() {
236236
}
237237
}
238238

239-
protected long now() {
240-
return ticker.read();
241-
}
242-
243239
/**
244240
* Cleans up cache if needed to fit into max size bytes by
245241
* removing expired entries and removing oldest entries by LRU order.
@@ -253,13 +249,14 @@ protected final boolean fitToLimit() {
253249
return false;
254250
}
255251
// cleanup expired entries
256-
cleanupExpiredEntries(now());
252+
long now = ticker.read();
253+
cleanupExpiredEntries(now);
257254

258255
// cleanup eldest entry until new size limit
259256
Iterator<Map.Entry<K, SizedValue>> lruIter = delegate.entrySet().iterator();
260257
while (lruIter.hasNext() && estimatedMaxSizeBytes < this.estimatedSizeBytes.get()) {
261258
Map.Entry<K, SizedValue> entry = lruIter.next();
262-
if (!shouldInvalidateEldestEntry(entry.getKey(), entry.getValue().value)) {
259+
if (!shouldInvalidateEldestEntry(entry.getKey(), entry.getValue().value, now)) {
263260
break; // Violates some constraint like minimum age so stop our cleanup
264261
}
265262
lruIter.remove();

0 commit comments

Comments
 (0)
Please sign in to comment.