github-actions[bot] commented on code in PR #66269:
URL: https://github.com/apache/doris/pull/66269#discussion_r3714720001


##########
fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHiveAccessController.java:
##########
@@ -64,7 +74,41 @@ public RangerHiveAccessController(Map<String, String> 
properties,
         hivePlugin = new RangerHivePlugin(serviceName, 
rangerAuthContextListener);
         auditHandler = new RangerHiveAuditHandler(hivePlugin.getConfig());
         // start a timed log flusher
-        logFlushTimer.scheduleAtFixedRate(new 
RangerHiveAuditLogFlusher(auditHandler), 10, 20L, TimeUnit.SECONDS);
+        logFlushFuture = LOG_FLUSH_TIMER.scheduleAtFixedRate(
+                new RangerHiveAuditLogFlusher(auditHandler), 10, 20L, 
TimeUnit.SECONDS);
+    }
+
+    @Override
+    public void close() {
+        lifecycleLock.writeLock().lock();
+        try {
+            if (closed) {
+                return;
+            }
+            closed = true;
+            if (logFlushFuture != null) {
+                logFlushFuture.cancel(false);
+                logFlushFuture = null;
+            }
+            // flushAudit atomically drains the handler. This preserves events 
produced before close without
+            // racing the periodic flusher or re-emitting events it has 
already sent.
+            try {
+                auditHandler.flushAudit();

Review Comment:
   **[P1] Keep a consumer alive when the final audit flush fails**
   
   This cancels and clears the only scheduled consumer before attempting the 
final `flushAudit()`. The handler now retains a failed head in 
`pendingAuditEvents`, but if the configured provider throws once here, this 
catch only logs before plugin cleanup; the manager then drops the controller 
and every later `close()` returns because `closed` is already set. An event 
authorized just before ALTER/DROP is therefore permanently lost even if the 
provider would succeed on retry. Please transfer a failed final batch to a 
consumer that outlives the controller (or otherwise retry before releasing 
ownership), and add a close test with a throw-once provider.



##########
fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHiveAccessController.java:
##########
@@ -42,17 +44,25 @@
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.stream.Collectors;
 
 public class RangerHiveAccessController extends RangerAccessController {
     private static final Logger LOG = 
LogManager.getLogger(RangerHiveAccessController.class);
-    private static ScheduledThreadPoolExecutor logFlushTimer = 
ThreadPoolManager.newDaemonScheduledThreadPool(1,
+    private static final ScheduledThreadPoolExecutor LOG_FLUSH_TIMER = 
ThreadPoolManager.newDaemonScheduledThreadPool(1,

Review Comment:
   **[P2] Isolate audit progress across Ranger catalogs**
   
   The new one-shot flusher removes the previous forever loop and the 
producer-lock fix lets other callbacks enqueue, but every controller still 
performs synchronous provider delivery on this static one-thread scheduler. If 
catalog A's provider stalls, the sole worker cannot start catalog B's 
already-due task, so B's audit latency and buffer growth are unbounded. 
`ThreadPoolManager.newDaemonScheduledThreadPool()` explicitly reserves this 
helper for short fixed-rate tasks. Please keep the timer callback short and 
provide independent, bounded delivery progress with per-handler serialization, 
plus a two-controller latch test where B flushes while A's provider is blocked.



##########
fe/fe-core/src/main/java/org/apache/doris/datasource/plugin/PluginDrivenExternalCatalog.java:
##########
@@ -1513,21 +1513,29 @@ private void 
closeConnectorContextQuietly(DefaultConnectorContext context) {
         }
         try {
             context.close();
-        } catch (IOException e) {
+        } catch (Throwable e) {
             LOG.warn("Failed to close connector context filesystem for catalog 
{}", name, e);
         }
     }
 
     @Override
-    public void onClose() {
-        super.onClose();
-        if (connector != null) {
+    protected void closeResources() {
+        try {
+            super.closeResources();
+        } catch (Throwable e) {
+            LOG.warn("Failed to close common resources for plugin-driven 
catalog {}", name, e);
+        }
+
+        // Detach every stage before invoking external code. A throwing 
connector must not remain reachable
+        // for another close attempt or prevent the connector-context stage 
from running.
+        Connector connectorToClose = connector;
+        connector = null;
+        if (connectorToClose != null) {
             try {
-                connector.close();
-            } catch (IOException e) {
+                connectorToClose.close();

Review Comment:
   **[P2] Pin the connector loader before detaching cleanup**
   
   This still invokes a directory-loaded connector under the FE caller's TCCL. 
A child-first plugin whose `close()` uses `ServiceLoader`, reflective by-name 
loading, or starts cleanup workers can therefore fail with an unchecked 
classloading error. The new order makes that materially worse on ALTER: 
`connector` is nulled first and every `Throwable` is swallowed, so the DDL can 
succeed after permanently abandoning the plugin's resources. Please invoke 
connector lifecycle callbacks under the connector's defining classloader with 
restoration in `finally`, reuse the helper for the first-initialization 
replacement close, and add a directory-loaded fake whose `close()` verifies 
TCCL and restoration.



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