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

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


The following commit(s) were added to refs/heads/master by this push:
     new 38793052091 Fix UserLockInfo concurrency (#16559)
38793052091 is described below

commit 38793052091f43e727ac5e76821a07aea685ec5b
Author: Jiang Tian <[email protected]>
AuthorDate: Sat Oct 11 19:02:54 2025 +0800

    Fix UserLockInfo concurrency (#16559)
    
    * Fix the concurrency issue of UserLockInfo
    
    * spotless
---
 .../org/apache/iotdb/db/auth/LoginLockManager.java |  4 +--
 .../apache/iotdb/db/auth/LoginLockManagerTest.java | 33 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/LoginLockManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/LoginLockManager.java
index 66dbc8a7c8a..eaf43d65ca6 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/LoginLockManager.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/auth/LoginLockManager.java
@@ -112,9 +112,7 @@ public class LoginLockManager {
 
     void removeOldFailures(long cutoffTime) {
       // Remove timestamps older than cutoffTime
-      while (!failureTimestamps.isEmpty() && failureTimestamps.peekFirst() < 
cutoffTime) {
-        failureTimestamps.pollFirst();
-      }
+      failureTimestamps.removeIf(timestamp -> timestamp < cutoffTime);
     }
 
     int getFailureCount() {
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/LoginLockManagerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/LoginLockManagerTest.java
index 845e1b4578c..650d88c8690 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/LoginLockManagerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/auth/LoginLockManagerTest.java
@@ -19,13 +19,21 @@
 
 package org.apache.iotdb.db.auth;
 
+import org.apache.iotdb.db.auth.LoginLockManager.UserLockInfo;
+
 import org.junit.Before;
 import org.junit.Test;
 
 import java.lang.reflect.Field;
 import java.net.InetAddress;
+import java.util.ArrayList;
 import java.util.Deque;
+import java.util.List;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.junit.Assert.assertEquals;
@@ -535,4 +543,29 @@ public class LoginLockManagerTest {
     // Final verification: no inconsistencies detected during test
     assertTrue("Lock state should remain valid during concurrent access", 
consistencyFlag.get());
   }
+
+  @Test
+  public void testConcurrentOperateLockInfo() throws InterruptedException, 
ExecutionException {
+    UserLockInfo userLockInfo = new UserLockInfo();
+    int numThreads = 100;
+    final int numAttempts = 100000;
+    ExecutorService executor = Executors.newFixedThreadPool(numThreads);
+    List<Future<Void>> threads = new ArrayList<>(numThreads);
+    for (int i = 0; i < numThreads; i++) {
+      threads.add(
+          executor.submit(
+              () -> {
+                for (int i1 = 0; i1 < numAttempts; i1++) {
+                  userLockInfo.addFailureTime(i1);
+                  if (i1 > 30) {
+                    userLockInfo.removeOldFailures(i1 - 30);
+                  }
+                }
+                return null;
+              }));
+    }
+    for (Future<Void> thread : threads) {
+      thread.get();
+    }
+  }
 }

Reply via email to