HBASE-21144 Addendum fix race when testing whether a procedure is finished

This commit is contained in:
zhangduo 2018-09-07 20:58:22 +08:00
parent 9af7bc6204
commit b04b4b0fd1
1 changed files with 16 additions and 7 deletions

View File

@ -40,6 +40,8 @@ import org.apache.yetus.audience.InterfaceStability;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState;
/** /**
* Helper to synchronously wait on conditions. * Helper to synchronously wait on conditions.
* This will be removed in the future (mainly when the AssignmentManager will be * This will be removed in the future (mainly when the AssignmentManager will be
@ -135,18 +137,25 @@ public final class ProcedureSyncWait {
} }
public static byte[] waitForProcedureToComplete( public static byte[] waitForProcedureToComplete(
final ProcedureExecutor<MasterProcedureEnv> procExec, final ProcedureExecutor<MasterProcedureEnv> procExec, final Procedure<?> proc,
final Procedure<?> proc, final long timeout) final long timeout) throws IOException {
throws IOException {
waitFor(procExec.getEnvironment(), "pid=" + proc.getProcId(), waitFor(procExec.getEnvironment(), "pid=" + proc.getProcId(),
new ProcedureSyncWait.Predicate<Boolean>() { new ProcedureSyncWait.Predicate<Boolean>() {
@Override @Override
public Boolean evaluate() throws IOException { public Boolean evaluate() throws IOException {
return !procExec.isRunning() || procExec.isFinished(proc.getProcId()); if (!procExec.isRunning()) {
return true;
} }
ProcedureState state = proc.getState();
if (state == ProcedureState.INITIALIZING || state == ProcedureState.RUNNABLE) {
// under these states the procedure may have not been added to procExec yet, so do not
// use isFinished to test whether it is finished, as this method will just check if the
// procedure is in the running procedure list
return false;
} }
); return procExec.isFinished(proc.getProcId());
}
});
if (!procExec.isRunning()) { if (!procExec.isRunning()) {
throw new IOException("The Master is Aborting"); throw new IOException("The Master is Aborting");
} }