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

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


The following commit(s) were added to refs/heads/master by this push:
     new 094858a5151 fix: Track persist and merge time in nanoseconds to fix 
flaky StreamAppenderatorTest (#20626)
094858a5151 is described below

commit 094858a5151fbe959cdafa97628e71060e275aca
Author: Nimish Rao <[email protected]>
AuthorDate: Sun Oct 25 13:18:57 2026 +0530

    fix: Track persist and merge time in nanoseconds to fix flaky 
StreamAppenderatorTest (#20626)
    
    * Fix flaky StreamAppenderatorTest assertions on Windows #20602
    
    * Track persist and merge time in nanoseconds
    
    * Remove unrelated formatting changes from StreamAppenderatorTest
    
    * Fix batch persist and merge time units and remove unrelated formatting 
changes
    
    * Derive monitor deltas from cumulative millis, inline merge time 
conversion, update BatchAppenderatorTest
    
    * Inline merge time conversion at log statements
---
 .../apache/druid/java/util/common/Stopwatch.java   |  9 +++++++
 .../segment/realtime/SegmentGenerationMetrics.java | 31 +++++++++++++++-------
 .../realtime/appenderator/BatchAppenderator.java   | 15 ++++++-----
 .../realtime/appenderator/StreamAppenderator.java  | 12 ++++-----
 .../appenderator/BatchAppenderatorTest.java        | 12 +++++++--
 .../appenderator/StreamAppenderatorTest.java       | 12 +++++++--
 6 files changed, 64 insertions(+), 27 deletions(-)

diff --git 
a/processing/src/main/java/org/apache/druid/java/util/common/Stopwatch.java 
b/processing/src/main/java/org/apache/druid/java/util/common/Stopwatch.java
index ab48fd7f9b0..d81b7e98631 100644
--- a/processing/src/main/java/org/apache/druid/java/util/common/Stopwatch.java
+++ b/processing/src/main/java/org/apache/druid/java/util/common/Stopwatch.java
@@ -88,6 +88,15 @@ public class Stopwatch
     return delegate.elapsed(TimeUnit.MILLISECONDS);
   }
 
+  /**
+   * Returns the nanoseconds elapsed on the stopwatch.
+   */
+
+  public long nanosElapsed()
+  {
+    return delegate.elapsed(TimeUnit.NANOSECONDS);
+  }
+
   /**
    * Checks if the given duration has already elapsed on the stopwatch.
    */
diff --git 
a/server/src/main/java/org/apache/druid/segment/realtime/SegmentGenerationMetrics.java
 
b/server/src/main/java/org/apache/druid/segment/realtime/SegmentGenerationMetrics.java
index 97d347b0e3a..4c3cd407cd1 100644
--- 
a/server/src/main/java/org/apache/druid/segment/realtime/SegmentGenerationMetrics.java
+++ 
b/server/src/main/java/org/apache/druid/segment/realtime/SegmentGenerationMetrics.java
@@ -21,6 +21,7 @@ package org.apache.druid.segment.realtime;
 
 import com.google.common.annotations.VisibleForTesting;
 
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -36,7 +37,7 @@ public class SegmentGenerationMetrics
   private final AtomicLong dedupCount = new AtomicLong(0);
   private final AtomicLong rowOutputCount = new AtomicLong(0);
   private final AtomicLong numPersists = new AtomicLong(0);
-  private final AtomicLong persistTimeMillis = new AtomicLong(0);
+  private final AtomicLong persistTimeNanos = new AtomicLong(0);
   private final AtomicLong persistBackPressureMillis = new AtomicLong(0);
   private final AtomicLong failedPersists = new AtomicLong(0);
   private final AtomicLong failedHandoffs = new AtomicLong(0);
@@ -44,7 +45,7 @@ public class SegmentGenerationMetrics
   private final AtomicLong mergedRows = new AtomicLong(0);
   // Measures the number of rows that have been pushed to deep storage.
   private final AtomicLong pushedRows = new AtomicLong(0);
-  private final AtomicLong mergeTimeMillis = new AtomicLong(0);
+  private final AtomicLong mergeTimeNanos = new AtomicLong(0);
   private final AtomicLong mergeCpuTime = new AtomicLong(0);
   private final AtomicLong persistCpuTime = new AtomicLong(0);
   private final AtomicLong handOffCount = new AtomicLong(0);
@@ -127,9 +128,9 @@ public class SegmentGenerationMetrics
     numPersists.incrementAndGet();
   }
 
-  public void incrementPersistTimeMillis(long millis)
+  public void incrementPersistTimeNanos(long nanos)
   {
-    persistTimeMillis.addAndGet(millis);
+    persistTimeNanos.addAndGet(nanos);
   }
 
   public void incrementPersistBackPressureMillis(long millis)
@@ -186,9 +187,9 @@ public class SegmentGenerationMetrics
     }
   }
 
-  public void setMergeTime(long elapsedMergeTimeMillis)
+  public void setMergeTime(long elapsedMergeTimeNanos)
   {
-    mergeTimeMillis.set(elapsedMergeTimeMillis);
+    mergeTimeNanos.set(elapsedMergeTimeNanos);
   }
 
   public void setMergeCpuTime(long elapsedCpuTimeNanos)
@@ -229,7 +230,12 @@ public class SegmentGenerationMetrics
 
   public long persistTimeMillis()
   {
-    return persistTimeMillis.get();
+    return TimeUnit.NANOSECONDS.toMillis(persistTimeNanos.get());
+  }
+
+  public long persistTimeNanos()
+  {
+    return persistTimeNanos.get();
   }
 
   public long persistBackPressureMillis()
@@ -259,7 +265,12 @@ public class SegmentGenerationMetrics
 
   public long mergeTimeMillis()
   {
-    return mergeTimeMillis.get();
+    return TimeUnit.NANOSECONDS.toMillis(mergeTimeNanos.get());
+  }
+
+  public long mergeTimeNanos()
+  {
+    return mergeTimeNanos.get();
   }
 
   public long mergeCpuTime()
@@ -306,11 +317,11 @@ public class SegmentGenerationMetrics
     retVal.dedupCount.set(dedupCount.get());
     retVal.rowOutputCount.set(rowOutputCount.get());
     retVal.numPersists.set(numPersists.get());
-    retVal.persistTimeMillis.set(persistTimeMillis.get());
+    retVal.persistTimeNanos.set(persistTimeNanos.get());
     retVal.persistBackPressureMillis.set(persistBackPressureMillis.get());
     retVal.failedPersists.set(failedPersists.get());
     retVal.failedHandoffs.set(failedHandoffs.get());
-    retVal.mergeTimeMillis.set(mergeTimeMillis.get());
+    retVal.mergeTimeNanos.set(mergeTimeNanos.get());
     retVal.mergeCpuTime.set(mergeCpuTime.get());
     retVal.persistCpuTime.set(persistCpuTime.get());
     retVal.handOffCount.set(handOffCount.get());
diff --git 
a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderator.java
 
b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderator.java
index ec1ac78f209..f15ca0067c2 100644
--- 
a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderator.java
+++ 
b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderator.java
@@ -622,8 +622,9 @@ public class BatchAppenderator implements Appenderator
           }
           finally {
             metrics.setPersistCpuTime(JvmUtils.safeGetThreadCpuTime() - 
startPersistCpuNanos);
-            final long persistMillis = persistStopwatch.millisElapsed();
-            metrics.incrementPersistTimeMillis(persistMillis);
+            final long persistNanos = persistStopwatch.nanosElapsed();
+            final long persistMillis = 
TimeUnit.NANOSECONDS.toMillis(persistNanos);
+            metrics.incrementPersistTimeNanos(persistNanos);
             metrics.incrementNumPersists();
             persistStopwatch.stop();
             // make sure no push can start while persisting:
@@ -803,7 +804,7 @@ public class BatchAppenderator implements Appenderator
       final File mergedFile;
       final DataSegment mergedSegment;
       final Stopwatch mergeStopwatch = Stopwatch.createStarted();
-      final long mergeTimeMillis;
+      final long mergeTimeNanos;
       final long startMergeCpuNanos = JvmUtils.safeGetThreadCpuTime();
       List<QueryableIndex> indexes = new ArrayList<>();
       long rowsinMergedSegment = 0L;
@@ -836,10 +837,10 @@ public class BatchAppenderator implements Appenderator
         metrics.incrementMergedRows(rowsinMergedSegment);
 
         metrics.setMergeCpuTime(JvmUtils.safeGetThreadCpuTime() - 
startMergeCpuNanos);
-        mergeTimeMillis = mergeStopwatch.millisElapsed();
-        metrics.setMergeTime(mergeTimeMillis);
+        mergeTimeNanos = mergeStopwatch.nanosElapsed();
+        metrics.setMergeTime(mergeTimeNanos);
 
-        log.debug("Segment[%s] built in %,dms.", identifier, mergeTimeMillis);
+        log.debug("Segment[%s] built in %,dms.", identifier, 
TimeUnit.NANOSECONDS.toMillis(mergeTimeNanos));
         QueryableIndex index = indexIO.loadIndex(mergedFile);
         closer.register(index);
         // Clustered segments have no top-level columns 
(getAvailableDimensions() is empty); their logical
@@ -896,7 +897,7 @@ public class BatchAppenderator implements Appenderator
           segment.getSize(),
           segment.getTotalRows(),
           indexes.size(),
-          mergeTimeMillis,
+          TimeUnit.NANOSECONDS.toMillis(mergeTimeNanos),
           pushTimeMillis,
           objectMapper.writeValueAsString(segment.getLoadSpec())
       );
diff --git 
a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderator.java
 
b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderator.java
index d8290aaa9b0..7a7108c5db8 100644
--- 
a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderator.java
+++ 
b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderator.java
@@ -753,7 +753,7 @@ public class StreamAppenderator implements Appenderator
             }
             finally {
               metrics.setPersistCpuTime(JvmUtils.safeGetThreadCpuTime() - 
startPersistCpuNanos);
-              
metrics.incrementPersistTimeMillis(persistStopwatch.millisElapsed());
+              
metrics.incrementPersistTimeNanos(persistStopwatch.nanosElapsed());
               metrics.incrementNumPersists();
               persistStopwatch.stop();
             }
@@ -943,7 +943,7 @@ public class StreamAppenderator implements Appenderator
       final File mergedFile;
       final DataSegment mergedSegment;
       final Stopwatch mergeStopwatch = Stopwatch.createStarted();
-      final long mergeTimeMillis;
+      final long mergeTimeNanos;
       final long startMergeCpuNanos = JvmUtils.safeGetThreadCpuTime();
       List<QueryableIndex> indexes = new ArrayList<>();
       Closer closer = Closer.create();
@@ -970,10 +970,10 @@ public class StreamAppenderator implements Appenderator
         );
 
         metrics.setMergeCpuTime(JvmUtils.safeGetThreadCpuTime() - 
startMergeCpuNanos);
-        mergeTimeMillis = mergeStopwatch.millisElapsed();
-        metrics.setMergeTime(mergeTimeMillis);
+        mergeTimeNanos = mergeStopwatch.nanosElapsed();
+        metrics.setMergeTime(mergeTimeNanos);
 
-        log.debug("Segment[%s] built in %,dms.", identifier, mergeTimeMillis);
+        log.debug("Segment[%s] built in %,dms.", identifier, 
TimeUnit.NANOSECONDS.toMillis(mergeTimeNanos));
         QueryableIndex index = indexIO.loadIndex(mergedFile);
         closer.register(index);
         // Clustered segments have no top-level columns 
(getAvailableDimensions() is empty); their logical
@@ -1014,7 +1014,7 @@ public class StreamAppenderator implements Appenderator
           segment.getSize(),
           segment.getTotalRows(),
           indexes.size(),
-          mergeTimeMillis,
+          TimeUnit.NANOSECONDS.toMillis(mergeTimeNanos),
           pushTimeMillis,
           objectMapper.writeValueAsString(segment.getLoadSpec())
       );
diff --git 
a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorTest.java
 
b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorTest.java
index d66a5dfc18c..0937e97f0e3 100644
--- 
a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorTest.java
+++ 
b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorTest.java
@@ -159,10 +159,18 @@ public class BatchAppenderatorTest extends 
InitializedNullHandlingTest
       SegmentGenerationMetrics segmentGenerationMetrics = tester.getMetrics();
       Assertions.assertEquals(2, segmentGenerationMetrics.numPersists());
       Assertions.assertEquals(4, segmentGenerationMetrics.rowOutput());
-      Assertions.assertTrue(segmentGenerationMetrics.persistTimeMillis() > 0);
+      Assertions.assertTrue(segmentGenerationMetrics.persistTimeNanos() > 0);
+      Assertions.assertEquals(
+          segmentGenerationMetrics.persistTimeNanos() / 1_000_000,
+          segmentGenerationMetrics.persistTimeMillis()
+      );
       Assertions.assertTrue(segmentGenerationMetrics.persistCpuTime() > 0);
 
-      Assertions.assertTrue(segmentGenerationMetrics.mergeTimeMillis() > 0);
+      Assertions.assertTrue(segmentGenerationMetrics.mergeTimeNanos() > 0);
+      Assertions.assertEquals(
+          segmentGenerationMetrics.mergeTimeNanos() / 1_000_000,
+          segmentGenerationMetrics.mergeTimeMillis()
+      );
       Assertions.assertTrue(segmentGenerationMetrics.mergeCpuTime() > 0);
 
       appenderator.close();
diff --git 
a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorTest.java
 
b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorTest.java
index 6868515d0c0..43accdf5ac7 100644
--- 
a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorTest.java
+++ 
b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorTest.java
@@ -189,10 +189,18 @@ public class StreamAppenderatorTest extends 
InitializedNullHandlingTest
       SegmentGenerationMetrics segmentGenerationMetrics = tester.getMetrics();
       Assertions.assertEquals(2, segmentGenerationMetrics.numPersists());
       Assertions.assertEquals(3, segmentGenerationMetrics.rowOutput());
-      Assertions.assertTrue(segmentGenerationMetrics.persistTimeMillis() > 0);
+      Assertions.assertTrue(segmentGenerationMetrics.persistTimeNanos() > 0);
+      Assertions.assertEquals(
+          segmentGenerationMetrics.persistTimeNanos() / 1_000_000,
+          segmentGenerationMetrics.persistTimeMillis()
+      );
       Assertions.assertTrue(segmentGenerationMetrics.persistCpuTime() > 0);
 
-      Assertions.assertTrue(segmentGenerationMetrics.mergeTimeMillis() > 0);
+      Assertions.assertTrue(segmentGenerationMetrics.mergeTimeNanos() > 0);
+      Assertions.assertEquals(
+          segmentGenerationMetrics.mergeTimeNanos() / 1_000_000,
+          segmentGenerationMetrics.mergeTimeMillis()
+      );
       Assertions.assertTrue(segmentGenerationMetrics.mergeCpuTime() > 0);
 
       // clear


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

Reply via email to