@Override
  public void remoteCallFailed(MasterProcedureEnv env, ServerName remote, IOException exception) {
    RegionStateNode regionNode = getRegionNode(env);
    regionNode.lock();
    try {
      if (!env.getMasterServices().getServerManager().isServerOnline(remote)) {
        // the SCP will interrupt us, give up
        LOG.debug("{} for region {}, targetServer {} is dead, SCP will interrupt us, give up", this,
          regionNode, remote);
        return;
      }
      if (state != RegionRemoteProcedureBaseState.REGION_REMOTE_PROCEDURE_DISPATCH) {
        // not sure how can this happen but anyway let's add a check here to avoid waking the wrong
        // procedure...
        LOG.warn("{} for region {}, targetServer={} has already been woken up, ignore", this,
          regionNode, remote);
        return;
      }
      LOG.warn("The remote operation {} for region {} to server {} failed", this, regionNode,
        remote, exception);
      // It is OK to not persist the state here, as we do not need to change the region state if the
      // remote call is failed. If the master crashed before we actually execute the procedure and
      // persist the new state, it is fine to retry on the same target server again.
      state = RegionRemoteProcedureBaseState.REGION_REMOTE_PROCEDURE_DISPATCH_FAIL;
      regionNode.getProcedureEvent().wake(env.getProcedureScheduler());
    } finally {
      regionNode.unlock();
    }
  }
The base class for the remote procedures used to open/close a region.
<p/>
Notice that here we do not care about the result of the remote call, if the remote call is
finished, either succeeded or not, we will always finish the procedure. The parent procedure
should take care of the result and try to reschedule if the result is not good.
hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionRemoteProcedureBase.java