@Override
  protected Flow executeFromState(MasterProcedureEnv env, ReopenTableRegionsState state)
    throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {
    switch (state) {
      case REOPEN_TABLE_REGIONS_GET_REGIONS:
        if (!isTableEnabled(env)) {
          LOG.info("Table {} is disabled, give up reopening its regions", tableName);
          return Flow.NO_MORE_STATE;
        }
        List<HRegionLocation> tableRegions =
          env.getAssignmentManager().getRegionStates().getRegionsOfTableForReopen(tableName);
        regions = getRegionLocationsForReopen(tableRegions);
        setNextState(ReopenTableRegionsState.REOPEN_TABLE_REGIONS_REOPEN_REGIONS);
        return Flow.HAS_MORE_STATE;
      case REOPEN_TABLE_REGIONS_REOPEN_REGIONS:
        // if we didn't finish reopening the last batch yet, let's keep trying until we do.
        // at that point, the batch will be empty and we can generate a new batch
        if (!regions.isEmpty() && currentRegionBatch.isEmpty()) {
          currentRegionBatch = regions.stream().limit(reopenBatchSize).collect(Collectors.toList());
          batchesProcessed++;
        }
        for (HRegionLocation loc : currentRegionBatch) {
          RegionStateNode regionNode =
            env.getAssignmentManager().getRegionStates().getRegionStateNode(loc.getRegion());
          // this possible, maybe the region has already been merged or split, see HBASE-20921
          if (regionNode == null) {
            continue;
          }
          TransitRegionStateProcedure proc;
          regionNode.lock();
          try {
            if (regionNode.getProcedure() != null) {
              continue;
            }
            proc = TransitRegionStateProcedure.reopen(env, regionNode.getRegionInfo());
            regionNode.setProcedure(proc);
          } finally {
            regionNode.unlock();
          }
          addChildProcedure(proc);
          regionsReopened++;
        }
        setNextState(ReopenTableRegionsState.REOPEN_TABLE_REGIONS_CONFIRM_REOPENED);
        return Flow.HAS_MORE_STATE;
      case REOPEN_TABLE_REGIONS_CONFIRM_REOPENED:
        // update region lists based on what's been reopened
        regions = filterReopened(env, regions);
        currentRegionBatch = filterReopened(env, currentRegionBatch);

        // existing batch didn't fully reopen, so try to resolve that first.
        // since this is a retry, don't do the batch backoff
        if (!currentRegionBatch.isEmpty()) {
          return reopenIfSchedulable(env, currentRegionBatch, false);
        }

        if (regions.isEmpty()) {
          return Flow.NO_MORE_STATE;
        }

        // current batch is finished, schedule more regions
        return reopenIfSchedulable(env, regions, true);
      default:
        throw new UnsupportedOperationException("unhandled state=" + state);
    }
  }
Used for reopening the regions for a table.
hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ReopenTableRegionsProcedure.java