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


##########
multi-stage-query/src/main/java/org/apache/druid/msq/querykit/BaseLeafStageProcessor.java:
##########
@@ -264,6 +267,30 @@ private ProcessorManager<Object, Long> 
createBaseLeafProcessorManagerWithHandoff
           );
         }
     );
+
+    // segment map function is shared by the regular and handoff managers 
above, so neither of them can own its
+    // lifecycle, close it here, once, when this manager is closed by the 
frame processor executor, that happens
+    // after all processors have finished and released their mapped segments
+    return new ProcessorManager<>()
+    {
+      @Override
+      public ListenableFuture<Optional<ProcessorAndCallback<Object>>> next()
+      {
+        return delegate.next();
+      }
+
+      @Override
+      public Long result()
+      {
+        return delegate.result();
+      }
+
+      @Override
+      public void close()
+      {
+        CloseableUtils.closeAndWrapExceptions(() -> 
CloseableUtils.closeAll(delegate, segmentMapFunction));

Review Comment:
   [P1] Undefined segment map variable prevents compilation
   
   **Finding:** The new ProcessorManager.close implementation references 
segmentMapFunction, but no such variable exists in this class or repository; 
only segmentMapFns, a list of BaseInputSegmentMapFunction, is in scope. The 
multi-stage-query module therefore fails compilation with an unresolved-symbol 
error.
   
   **Suggestion:** Close the delegate and every segmentMapFn() from the 
correctly scoped segmentMapFns list, then add a compile check.



##########
processing/src/main/java/org/apache/druid/segment/SegmentMapFunction.java:
##########
@@ -27,21 +29,51 @@
  * possible.
  * <p>
  * The {@link Segment} returned by this method, if present, must always be 
closed by the caller.
+ * <p>
+ * A {@link SegmentMapFunction} may hold resources acquired when it was 
created, such as lookup snapshots pinned for
+ * the duration of a join (see {@link 
org.apache.druid.query.lookup.RetainedLookupExtractor}). The owner of a
+ * {@link SegmentMapFunction} obtained from {@link 
org.apache.druid.query.DataSource#createSegmentMapFunction} must
+ * {@link #close()} it after all mapped segments have been closed. 
Implementations created from lambdas hold no
+ * resources and inherit the no-op default. Implementations that hold 
resources must make {@link #close()} idempotent.
  */
 @FunctionalInterface
-public interface SegmentMapFunction extends Function<Optional<Segment>, 
Optional<Segment>>
+public interface SegmentMapFunction extends Function<Optional<Segment>, 
Optional<Segment>>, Closeable

Review Comment:
   [P2] UNION map wrappers drop close propagation
   
   **Finding:** After SegmentMapFunction became closeable, 
ExecutionVertex.splitUnionSegmentMapFunctions still returns plain lambdas that 
capture aboveUnionFn and each armFn and inherit the no-op close. MSQ consumes 
these functions through BaseInputSegmentMapFunction, so joins or lookups above 
a UNION can retain snapshots until cleaner or timeout.
   
   **Suggestion:** Return close-aware UNION wrappers or one composite owner 
that closes every arm and the shared above-UNION function exactly once.



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