HappenLee commented on code in PR #68658:
URL: https://github.com/apache/doris/pull/68658#discussion_r4141516679


##########
fe/fe-core/src/main/java/org/apache/doris/common/profile/Profile.java:
##########
@@ -314,7 +314,7 @@ public synchronized void updateSummary(Map<String, String> 
summaryInfo, boolean
                 long durationThreshold = executionProfiles.isEmpty()
                                     ? autoProfileDurationMs : 
executionProfiles.size() * autoProfileDurationMs;
                 if (this.queryFinishTimestamp != Long.MAX_VALUE && durationMs 
< durationThreshold) {
-                    ProfileManager.getInstance().removeProfile(this.getId());
+                    ProfileManager.getInstance().removeProfile(this);
                     if (LOG.isDebugEnabled()) {

Review Comment:
   Confirmed this retry cleanup gap locally on 
`c588e48817809f120a4296a2a6d5d32615df8729`.
   
   The change correctly cleans up the first short failed attempt, but a 
subsequent attempt can still retain its `ExecutionProfile`:
   
   1. With profiling enabled and a positive auto-profile threshold, a fast 
retryable RPC failure during dispatch reaches `finalizeQuery()`. 
`updateSummary(..., true, ...)` sets `isQueryFinished = true` and removes the 
first execution profile.
   2. `handleQueryWithRetry()` reuses that same `Profile`, changes the query 
ID, and registers another execution profile.
   3. Both summary updates for the retry return immediately at the 
`isQueryFinished` guard, so this removal is never reached again. 
`unregisterQuery()` only marks the execution profile finished.
   
   The fallback collector is size-triggered (`size > 2 * 
max_query_profile_num`, i.e. over 1000 entries by default), so a small number 
of retained entries will not simply disappear after five seconds. This is a 
pre-existing lifecycle gap left uncovered by this fix, rather than a new 
regression introduced by the diff.
   
   Please cover failed dispatch followed by a retry, and ensure cleanup applies 
to the retry execution as well. The lifecycle needs to distinguish completion 
of one attempt from completion of the whole statement.
   
   **Validation:** ran the repository's `run-fe-ut.sh`: `ProfileTest` (15), 
`AutoProfileTest` (1), and `ProfileManagerTest` (28) all passed. The additional 
test below failed on the final assertion: the first execution was removed, but 
the retry execution remained registered. It directly reproduces the Profile 
lifecycle; it does not inject an actual BE RPC failure.
   
   <details>
   <summary>Minimal reproducer: ReviewProfileRetryTest.java</summary>
   
   ```java
   package org.apache.doris.common.profile;
   
   import org.apache.doris.common.util.DebugUtil;
   import org.apache.doris.thrift.TUniqueId;
   
   import org.junit.jupiter.api.Assertions;
   import org.junit.jupiter.api.Test;
   import org.junit.jupiter.api.parallel.ResourceLock;
   
   import java.util.Collections;
   import java.util.HashMap;
   import java.util.Map;
   
   @ResourceLock("global")
   public class ReviewProfileRetryTest {
       @Test
       public void retryExecutionMustBeReleasedAfterFinalization() {
           ProfileManager manager = ProfileManager.getInstance();
           Profile profile = new Profile(true, 1, 60_000);
           
profile.getSummaryProfile().setQueryBeginTime(System.currentTimeMillis());
           TUniqueId firstId = new TUniqueId(68658, 1);
           TUniqueId retryId = new TUniqueId(68658, 2);
           Map<String, String> summary = new HashMap<>();
           summary.put(SummaryProfile.PROFILE_ID, DebugUtil.printId(firstId));
           try {
               // registerQuery, dispatch failure, finalizeQuery: no running 
summary was pushed.
               ExecutionProfile first = new ExecutionProfile(firstId, 
Collections.emptyList());
               profile.addExecutionProfile(first);
               manager.addExecutionProfile(first);
               profile.updateSummary(summary, true, null);
               manager.markExecutionProfileFinished(firstId);
               Assertions.assertNull(manager.getExecutionProfile(firstId));
               Assertions.assertTrue(profile.isQueryFinished);
   
               // handleQueryWithRetry reuses Profile while replacing the query 
ID and Coordinator.
               ExecutionProfile retry = new ExecutionProfile(retryId, 
Collections.emptyList());
               profile.addExecutionProfile(retry);
               manager.addExecutionProfile(retry);
               summary.put(SummaryProfile.PROFILE_ID, 
DebugUtil.printId(retryId));
               profile.updateSummary(summary, false, null);
               profile.updateSummary(summary, true, null);
               manager.markExecutionProfileFinished(retryId);
   
               Assertions.assertNull(manager.getExecutionProfile(retryId),
                       "The retry execution remains registered after 
finalization");
           } finally {
               manager.removeProfile(profile);
           }
       }
   }
   ```
   
   Observed failure:
   
   ```text
   The retry execution remains registered after finalization
   expected: <null> but was: <DetailProfile(10c32-2): ...>
   Tests run: 45, Failures: 1, Errors: 0, Skipped: 0
   ```
   
   </details>
   



-- 
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