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:37 UTC

(camel) branch essobedo/CAMEL-21614/prevent-cache-change-miss-on-swap created (now 6d27d74d65b)

This is an automated email from the ASF dual-hosted git repository.

nfilotto pushed a change to branch essobedo/CAMEL-21614/prevent-cache-change-miss-on-swap
in repository https://gitbox.apache.org/repos/asf/camel.git


      at 6d27d74d65b CAMEL-21614: camel-core - Prevent cache change miss on queue swap

This branch includes the following new commits:

     new 6d27d74d65b CAMEL-21614: camel-core - Prevent cache change miss on queue swap

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(camel) 01/01: CAMEL-21614: camel-core - Prevent cache change miss on queue swap

Posted by nf...@apache.org.
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) {