Apache9 commented on code in PR #8357:
URL: https://github.com/apache/hbase/pull/8357#discussion_r3499870322


##########
hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRollbackSCP.java:
##########
@@ -75,12 +85,45 @@ public class TestRollbackSCP {
 
   private static final AtomicBoolean INJECTED = new AtomicBoolean(false);
 
+  // HBASE-29555: guards the in-place procedure-executor reload against region 
servers concurrently
+  // reporting region state transitions. See 
restartMasterProcedureExecutorLikeFailover(). Fair so
+  // that, while the reload is waiting for / holding the write lock, new 
reports are rejected rather
+  // than barging in. A region state report takes the read lock; the reload 
takes the write lock.
+  private static final ReentrantReadWriteLock RELOAD_LOCK = new 
ReentrantReadWriteLock(true);

Review Comment:
   Actually I do not get the point why here we need fair lock?



##########
hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRollbackSCP.java:
##########
@@ -160,6 +203,67 @@ public void describeTo(Description description) {
     };
   }
 
+  /**
+   * Wait for the (already shutdown) asyncTaskExecutor of the given executor 
to fully terminate.
+   * HBASE-29555 (Gap #1): callbacks that wake a procedure after an async 
operation (e.g.
+   * AssignmentManager#persistToMeta run on the executor's asyncTaskExecutor, 
not on a
+   * PEWorker. In production a master restart is a fresh process, so no such 
callback can survive
+   * into the reloaded executor. Here we reuse the same executor in-place, so 
a pending callback can
+   * call scheduler.addFront during the reload. ProcedureExecutor shuts the
+   * asyncTaskExecutor down; waiting for it to terminate guarantees any 
pending callback has run
+   * before we clear the scheduler, reproducing the "no async work survives 
the restart" guarantee.
+   */
+  private static void awaitAsyncTaskExecutorTermination(ProcedureExecutor<?> 
procExec) {
+    ExecutorService asyncTaskExecutor = procExec.getAsyncTaskExecutor();
+    if (asyncTaskExecutor == null) {
+      return;
+    }
+    long deadline = System.currentTimeMillis() + 60000;
+    try {
+      while (!asyncTaskExecutor.awaitTermination(1, TimeUnit.SECONDS)) {

Review Comment:
   Why not just wait for 1 minute?



##########
hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRollbackSCP.java:
##########
@@ -75,12 +85,45 @@ public class TestRollbackSCP {
 
   private static final AtomicBoolean INJECTED = new AtomicBoolean(false);
 
+  // HBASE-29555: guards the in-place procedure-executor reload against region 
servers concurrently
+  // reporting region state transitions. See 
restartMasterProcedureExecutorLikeFailover(). Fair so
+  // that, while the reload is waiting for / holding the write lock, new 
reports are rejected rather
+  // than barging in. A region state report takes the read lock; the reload 
takes the write lock.
+  private static final ReentrantReadWriteLock RELOAD_LOCK = new 
ReentrantReadWriteLock(true);
+
   private static final class AssignmentManagerForTest extends 
AssignmentManager {
 
     public AssignmentManagerForTest(MasterServices master, MasterRegion 
masterRegion) {
       super(master, masterRegion);
     }
 
+    @Override
+    public ReportRegionStateTransitionResponse reportRegionStateTransition(
+      ReportRegionStateTransitionRequest req) throws PleaseHoldException {
+      // HBASE-29555 (Gap #2): in production a starting/recovering master 
rejects region state
+      // reports (via HMaster.checkServiceStarted) until it has finished 
initializing, which happens
+      // only after the procedure executor has loaded. The test instead 
reloads the executor in place
+      // under a live master, so a report can wake a procedure and re-populate 
the scheduler in the
+      // window between clearing it and ProcedureExecutor.load() asserting it 
is empty. Mirror
+      // production: while the reload holds the write lock, reject reports 
with PleaseHoldException
+      // (the region server retries). tryLock (non-blocking) is used so a 
report never blocks the
+      // reload; acquiring the write lock in the reload still waits for any 
already in-flight report.
+      boolean locked = false;
+      try {
+        locked = RELOAD_LOCK.readLock().tryLock(0, TimeUnit.SECONDS);

Review Comment:
   What does timeout 0 means here? No timeout or same with tryLock without any 
parameters?



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

Reply via email to