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

jxue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git


The following commit(s) were added to refs/heads/master by this push:
     new aba2b54bb Fix racecondition in PerKeyBlockingExecutor
aba2b54bb is described below

commit aba2b54bb9c6c6ba7e45f4e35f6027b953c5bd40
Author: Junkai Xue <[email protected]>
AuthorDate: Sat Mar 7 20:24:53 2026 -0800

    Fix racecondition in PerKeyBlockingExecutor
    
      The original code had a race condition:
      1. offerEvent checks _runningEvents.contains(key) to decide whether to 
queue or execute
      2. But the key was only added to _runningEvents inside runEvent() which 
runs in a separate executor thread
      3. This created a window where the second event could be executed 
directly instead of being queued, because _runningEvents didn't have the key 
yet when the check happened
      Fix: Move _runningEvents.add(key) to execute BEFORE the executor submits 
the task (inside the lock), ensuring the key is marked as running before any 
subsequent offerEvent calls for the same key can
      check the set.
---
 .../java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java     | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git 
a/helix-gateway/src/main/java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java
 
b/helix-gateway/src/main/java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java
index c5463d214..b8a342b2d 100644
--- 
a/helix-gateway/src/main/java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java
+++ 
b/helix-gateway/src/main/java/org/apache/helix/gateway/util/PerKeyBlockingExecutor.java
@@ -55,6 +55,8 @@ public class PerKeyBlockingExecutor {
     _queueLock.lock();
     try {
       if (!_runningEvents.contains(key)) {
+        // Add to running events BEFORE executing to avoid race condition
+        _runningEvents.add(key);
         _executor.execute(() -> runEvent(key, event));
       } else {
         _pendingBlockedEvents.computeIfAbsent(key, k -> new 
ConcurrentLinkedQueue<>());
@@ -67,7 +69,6 @@ public class PerKeyBlockingExecutor {
 
   private void runEvent(String key, Runnable event) {
     try {
-      _runningEvents.add(key);
       event.run();
     } finally {
       _queueLock.lock();

Reply via email to