You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2025/01/14 18:29:38 UTC
(camel) 01/01: CAMEL-21614: camel-core - Prevent cache change miss on queue swap
This is an automated email from the ASF dual-hosted git repository.
nfilotto pushed a commit to branch essobedo/CAMEL-21614/prevent-cache-change-miss-on-swap
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 6d27d74d65bac6bb3b7685a77dcc544680288cfd
Author: Nicolas Filotto <ni...@qlik.com>
AuthorDate: Tue Jan 14 19:29:17 2025 +0100
CAMEL-21614: camel-core - Prevent cache change miss on queue swap
---
.../apache/camel/support/cache/SimpleLRUCache.java | 33 ++++++++++++++++++++--
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/cache/SimpleLRUCache.java b/core/camel-support/src/main/java/org/apache/camel/support/cache/SimpleLRUCache.java
index b6996a3f215..5ddd57b9c43 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/cache/SimpleLRUCache.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/cache/SimpleLRUCache.java
@@ -25,6 +25,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -49,6 +50,14 @@ public class SimpleLRUCache<K, V> extends ConcurrentHashMap<K, V> {
* The flag indicating that an eviction process is in progress.
*/
private final AtomicBoolean eviction = new AtomicBoolean();
+ /**
+ * The flag indicating that a swap process is in progress.
+ */
+ private final AtomicBoolean swap = new AtomicBoolean();
+ /**
+ * The number of cache change additions in progress.
+ */
+ private final AtomicInteger additions = new AtomicInteger();
/**
* The maximum cache size.
*/
@@ -84,7 +93,15 @@ public class SimpleLRUCache<K, V> extends ConcurrentHashMap<K, V> {
if (value == null) {
return null;
}
- lastChanges.get().add(Map.entry(key, value));
+ while (swap.get()) {
+ Thread.yield();
+ }
+ additions.incrementAndGet();
+ try {
+ lastChanges.get().add(Map.entry(key, value));
+ } finally {
+ additions.decrementAndGet();
+ }
return value;
}
@@ -268,8 +285,18 @@ public class SimpleLRUCache<K, V> extends ConcurrentHashMap<K, V> {
* Removes duplicates from the queue of changes.
*/
private void compressChanges() {
- Deque<Entry<K, V>> newChanges = new ConcurrentLinkedDeque<>();
- Deque<Entry<K, V>> currentChanges = lastChanges.getAndSet(newChanges);
+ Deque<Entry<K, V>> newChanges;
+ Deque<Entry<K, V>> currentChanges;
+ try {
+ swap.set(true);
+ while (additions.get() > 0) {
+ Thread.yield();
+ }
+ newChanges = new ConcurrentLinkedDeque<>();
+ currentChanges = lastChanges.getAndSet(newChanges);
+ } finally {
+ swap.set(false);
+ }
Set<K> keys = new HashSet<>();
Entry<K, V> entry;
while ((entry = currentChanges.pollLast()) != null) {