bug fix: concurrent increase by CounterWindow may cause PriorityQueue broken (#12505)

This commit is contained in:
kael 2024-08-04 20:33:11 +08:00 committed by GitHub
parent 1111f8985d
commit 5c33ee016d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 20 additions and 17 deletions

View File

@ -47,6 +47,7 @@
* BanyanDB: stream sort-by `time` query, use internal time-series rather than `index` to improve the query performance.
* Bump up graphql-java to 21.5.
* Add Unknown Node when receive Kubernetes peer address is not aware in current cluster.
* Fix CounterWindow concurrent increase cause NPE by PriorityQueue
#### UI

View File

@ -48,25 +48,27 @@ public class CounterWindow {
public Tuple2<Long, Double> increase(String name, ImmutableMap<String, String> labels, Double value, long windowSize, long now) {
ID id = new ID(name, labels);
Queue<Tuple2<Long, Double>> window = windows.computeIfAbsent(id, unused -> new PriorityQueue<>());
window.offer(Tuple.of(now, value));
long waterLevel = now - windowSize;
Tuple2<Long, Double> peek = window.peek();
if (peek._1 > waterLevel) {
synchronized (window) {
window.offer(Tuple.of(now, value));
long waterLevel = now - windowSize;
Tuple2<Long, Double> peek = window.peek();
if (peek._1 > waterLevel) {
return peek;
}
Tuple2<Long, Double> result = peek;
while (peek._1 < waterLevel) {
result = window.poll();
peek = window.element();
}
// Choose the closed slot to the expected timestamp
if (waterLevel - result._1 <= peek._1 - waterLevel) {
return result;
}
return peek;
}
Tuple2<Long, Double> result = peek;
while (peek._1 < waterLevel) {
result = window.poll();
peek = window.element();
}
// Choose the closed slot to the expected timestamp
if (waterLevel - result._1 <= peek._1 - waterLevel) {
return result;
}
return peek;
}
public Tuple2<Long, Double> pop(String name, ImmutableMap<String, String> labels, Double value, long now) {