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

junkaixue 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 0a0d081a6 Fix NPE in HelixTaskExecutor.reset() (#3167)
0a0d081a6 is described below

commit 0a0d081a6eb0defeefcf0ba32fdedc5679ff5873
Author: Xiaotian (Jackie) Jiang <[email protected]>
AuthorDate: Sat Aug 15 12:47:12 2026 -0700

    Fix NPE in HelixTaskExecutor.reset() (#3167)
    
    The final logging loop in reset() iterated _taskMap.keySet() and then
    called get(taskId) on the ConcurrentHashMap. A message task completing
    concurrently removes itself from the map between the two calls, so get
    returns null and reading info._task throws, failing the participant
    disconnect. Iterating entrySet() reads each entry atomically, so a
    concurrently-completing task is either logged or skipped, never null.
---
 .../org/apache/helix/messaging/handling/HelixTaskExecutor.java   | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git 
a/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
 
b/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
index c22322a2c..861266d55 100644
--- 
a/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
+++ 
b/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
@@ -738,10 +738,11 @@ public class HelixTaskExecutor implements 
MessageListener, TaskExecutor {
     // this is a potential area to improve. 
https://github.com/apache/helix/issues/1245
 
     StringBuilder sb = new StringBuilder();
-    // Log all tasks that fail to terminate
-    for (String taskId : _taskMap.keySet()) {
-      MessageTaskInfo info = _taskMap.get(taskId);
-      sb.append("Task: " + taskId + " fails to terminate. Message: " + 
info._task.getMessage() + "\n");
+    // Log all tasks that fail to terminate. Iterate entrySet() because each 
entry is read atomically: a task
+    // completing concurrently removes itself from the map, so keySet() + 
get() could observe a null value and NPE.
+    for (Map.Entry<String, MessageTaskInfo> entry : _taskMap.entrySet()) {
+      sb.append(
+          "Task: " + entry.getKey() + " fails to terminate. Message: " + 
entry.getValue()._task.getMessage() + "\n");
     }
 
     LOG.info(sb.toString());

Reply via email to