FrankChen021 commented on code in PR #19603:
URL: https://github.com/apache/druid/pull/19603#discussion_r3499360854


##########
server/src/main/java/org/apache/druid/metadata/SqlSegmentsMetadataManager.java:
##########
@@ -556,22 +556,22 @@ boolean useLatestSnapshotIfWithinDelay()
   @VisibleForTesting
   void forceOrWaitOngoingDatabasePoll()
   {
-    long checkStartTime = System.currentTimeMillis();
+    long checkStartTimeNanos = System.nanoTime();
     ReentrantReadWriteLock.WriteLock lock = startStopPollLock.writeLock();
     lock.lock();
     try {
       DatabasePoll latestDatabasePoll = this.latestDatabasePoll;
       try {
         //Verify if there was a periodic poll completed while we were waiting 
for the lock
         if (latestDatabasePoll instanceof PeriodicDatabasePoll
-            && ((PeriodicDatabasePoll) 
latestDatabasePoll).lastPollStartTimestampInMs > checkStartTime) {
+            && ((PeriodicDatabasePoll) 
latestDatabasePoll).lastPollStartTimestampInNanos > checkStartTimeNanos) {
           return;
         }
-        // Verify if there was a on-demand poll completed while we were 
waiting for the lock
+        // Verify if there was an on-demand poll completed while we were 
waiting for the lock
         if (latestDatabasePoll instanceof OnDemandDatabasePoll) {
-          long checkStartTimeNanos = 
TimeUnit.MILLISECONDS.toNanos(checkStartTime);
           OnDemandDatabasePoll latestOnDemandPoll = (OnDemandDatabasePoll) 
latestDatabasePoll;
           if (latestOnDemandPoll.initiationTimeNanos > checkStartTimeNanos) {

Review Comment:
   [P2] Contended force calls still miss the poll they waited for
   
   This still compares the existing on-demand poll's initiation time with the 
caller's check start. In the common contended path, thread A creates the 
OnDemandDatabasePoll and holds the write lock while polling; thread B enters 
forceOrWaitOngoingDatabasePoll after that initiation, waits for the same write 
lock until A's poll completes, then sees initiationTimeNanos <= 
checkStartTimeNanos and starts another database poll. That means the PR still 
serializes duplicate forced polls for callers that arrived during the actual 
poll, even though the previous poll completed after their call. Track and 
compare completion time, or otherwise record that the caller waited behind the 
in-progress on-demand poll, before returning/forcing a new poll.



##########
server/src/main/java/org/apache/druid/metadata/SqlSegmentsMetadataManager.java:
##########
@@ -90,7 +90,7 @@ static class PeriodicDatabasePoll implements DatabasePoll
      * leadership changes.
      */
     final CompletableFuture<Void> firstPollCompletionFuture = new 
CompletableFuture<>();
-    long lastPollStartTimestampInMs = -1;
+    long lastPollStartTimestampInNanos = -1;

Review Comment:
   [P2] Do not use -1 as a nanoTime sentinel
   
   This timestamp is now compared directly with System.nanoTime() readings, but 
System.nanoTime() has an arbitrary origin and is allowed to return negative 
values. If the manager has installed a new PeriodicDatabasePoll but its first 
task has not set this field yet, lastPollStartTimestampInNanos remains -1; on a 
JVM where the caller's checkStartTimeNanos is less than -1, 
forceOrWaitOngoingDatabasePoll will treat that unstarted poll as newer and 
return without polling or waiting. Use Long.MIN_VALUE, an explicit initialized 
flag, or a nullable/completion timestamp instead.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to