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

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


The following commit(s) were added to refs/heads/master by this push:
     new 7e7c4363c9b HDDS-15371. [DiskBalancer] Use monotonic time for delayed 
replica deletion (#10364)
7e7c4363c9b is described below

commit 7e7c4363c9b67ce3054d903f56fbc8065c786224
Author: slfan1989 <[email protected]>
AuthorDate: Wed May 27 13:09:14 2026 +0800

    HDDS-15371. [DiskBalancer] Use monotonic time for delayed replica deletion 
(#10364)
---
 .../container/diskbalancer/DiskBalancerService.java     | 17 +++++++++++++++--
 .../diskbalancer/DiskBalancerServiceTestImpl.java       |  8 ++++++++
 .../container/diskbalancer/TestDiskBalancerTask.java    | 12 ++++++------
 3 files changed, 29 insertions(+), 8 deletions(-)

diff --git 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java
 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java
index 53470ef0410..a33a2d665fb 100644
--- 
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java
+++ 
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerService.java
@@ -31,6 +31,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.time.Clock;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -59,6 +60,7 @@
 import org.apache.hadoop.hdds.utils.BackgroundTaskQueue;
 import org.apache.hadoop.hdds.utils.BackgroundTaskResult;
 import org.apache.hadoop.hdds.utils.FaultInjector;
+import org.apache.hadoop.hdds.utils.SlidingWindow;
 import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.container.common.helpers.ContainerUtils;
 import org.apache.hadoop.ozone.container.common.impl.ContainerData;
@@ -94,6 +96,7 @@ public class DiskBalancerService extends BackgroundService {
 
   private OzoneContainer ozoneContainer;
   private final ConfigurationSource conf;
+  private final Clock clock;
 
   private double threshold;
   private long bandwidthInMB;
@@ -135,10 +138,19 @@ public class DiskBalancerService extends 
BackgroundService {
   public DiskBalancerService(OzoneContainer ozoneContainer,
       long serviceCheckInterval, long serviceCheckTimeout, TimeUnit timeUnit,
       int workerSize, ConfigurationSource conf) throws IOException {
+    this(ozoneContainer, serviceCheckInterval, serviceCheckTimeout, timeUnit,
+        workerSize, conf, new SlidingWindow.MonotonicClock());
+  }
+
+  DiskBalancerService(OzoneContainer ozoneContainer,
+      long serviceCheckInterval, long serviceCheckTimeout, TimeUnit timeUnit,
+      int workerSize, ConfigurationSource conf, Clock clock)
+      throws IOException {
     super("DiskBalancerService", serviceCheckInterval, timeUnit, workerSize,
         serviceCheckTimeout);
     this.ozoneContainer = ozoneContainer;
     this.conf = conf;
+    this.clock = Objects.requireNonNull(clock, "clock");
 
     String diskBalancerInfoPath = getDiskBalancerInfoPath();
     Objects.requireNonNull(diskBalancerInfoPath);
@@ -634,7 +646,8 @@ public BackgroundTaskResult call() {
         }
         if (moveSucceeded && newContainer != null) {
           // Add current old container to pendingDeletionContainers.
-          pendingDeletionContainers.put(System.currentTimeMillis() + 
replicaDeletionDelay, container);
+          pendingDeletionContainers.put(clock.millis() + replicaDeletionDelay,
+              container);
           ContainerLogger.logMoveSuccess(newContainer.getContainerData(), 
sourceVolume,
               destVolume, containerSize, Time.monotonicNow() - startTime);
         }
@@ -691,7 +704,7 @@ private void cleanupPendingDeletionContainers() {
   private boolean tryCleanupOnePendingDeletionContainer() {
     Map.Entry<Long, Container> entry = 
pendingDeletionContainers.pollFirstEntry();
     if (entry != null) {
-      if (entry.getKey() <= System.currentTimeMillis()) {
+      if (entry.getKey() <= clock.millis()) {
         // entry container is expired
         deleteContainer(entry.getValue());
         return true;
diff --git 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerServiceTestImpl.java
 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerServiceTestImpl.java
index ef150321907..3f9bb384002 100644
--- 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerServiceTestImpl.java
+++ 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/DiskBalancerServiceTestImpl.java
@@ -19,6 +19,7 @@
 
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import java.io.IOException;
+import java.time.Clock;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
@@ -46,6 +47,13 @@ public DiskBalancerServiceTestImpl(OzoneContainer container,
         TimeUnit.MILLISECONDS, threadCount, conf);
   }
 
+  public DiskBalancerServiceTestImpl(OzoneContainer container,
+      int serviceInterval, ConfigurationSource conf, int threadCount,
+      Clock clock) throws IOException {
+    super(container, serviceInterval, SERVICE_TIMEOUT_IN_MILLISECONDS,
+        TimeUnit.MILLISECONDS, threadCount, conf, clock);
+  }
+
   public void runBalanceTasks() {
     if (latch.getCount() > 0) {
       this.latch.countDown();
diff --git 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java
 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java
index fc3fdb7b140..7e4b49ccb40 100644
--- 
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java
+++ 
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/diskbalancer/TestDiskBalancerTask.java
@@ -47,7 +47,6 @@
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import org.apache.commons.io.FileUtils;
 import org.apache.hadoop.hdds.HddsConfigKeys;
@@ -83,6 +82,7 @@
 import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer;
 import org.apache.ozone.test.GenericTestUtils;
 import org.apache.ozone.test.GenericTestUtils.LogCapturer;
+import org.apache.ozone.test.TestClock;
 import org.assertj.core.api.Fail;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -113,6 +113,7 @@ public class TestDiskBalancerTask {
   private HddsVolume sourceVolume;
   private HddsVolume destVolume;
   private DiskBalancerServiceTestImpl diskBalancerService;
+  private TestClock clock;
 
   private static final long CONTAINER_ID = 1L;
   private static final long CONTAINER_SIZE = 1024L * 1024L; // 1 MB
@@ -243,8 +244,9 @@ public void setup() throws Exception {
     DiskBalancerConfiguration diskBalancerConfiguration = 
conf.getObject(DiskBalancerConfiguration.class);
     diskBalancerConfiguration.setDiskBalancerShouldRun(true);
     conf.setFromObject(diskBalancerConfiguration);
+    clock = TestClock.newInstance();
     diskBalancerService = new DiskBalancerServiceTestImpl(ozoneContainer,
-        100, conf, 1);
+        100, conf, 1, clock);
     diskBalancerService.setReplicaDeletionDelay(0);
     KeyValueContainer.setInjector(kvFaultInjector);
   }
@@ -599,10 +601,8 @@ public void 
testOldReplicaDelayedDeletion(ContainerTestVersionInfo versionInfo)
     // create another container to trigger the deletion of old replicas
     createContainer(CONTAINER_ID + 1, sourceVolume, State.CLOSED);
     task = getTask();
-    // Wait until the delayed deletion is eligible, then trigger cleanup.
-    long deletionEligibleAt = System.nanoTime() + 
TimeUnit.MILLISECONDS.toNanos(delay);
-    GenericTestUtils.waitFor(
-        () -> System.nanoTime() >= deletionEligibleAt, 50, 12_000);
+    // Advance the injected clock until the delayed deletion is eligible.
+    clock.fastForward(delay);
     task.call();
     // Verify that the old container is deleted
     assertFalse(oldContainerDir.exists());


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to