You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gi...@apache.org on 2026/07/20 23:56:57 UTC

(hbase-site) branch asf-site updated: Published site at 872616e4b45bf2994a63092b272987187bf3e161.

This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hbase-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 3fde55a6901 Published site at 872616e4b45bf2994a63092b272987187bf3e161.
3fde55a6901 is described below

commit 3fde55a6901e1121c84384490004e91c3f32064c
Author: HBase <de...@hbase.apache.org>
AuthorDate: Mon Jul 20 23:53:36 2026 +0000

    Published site at 872616e4b45bf2994a63092b272987187bf3e161.
---
 books/apache-hbase-reference-guide-dark-mode.pdf   | Bin 38943794 -> 38943795 bytes
 books/apache-hbase-reference-guide.pdf             | Bin 38833623 -> 38833623 bytes
 checkstyle-aggregate.html                          |   2 +-
 dependency-convergence.html                        |   2 +-
 dependency-info.html                               |   2 +-
 dependency-management.html                         |   2 +-
 hbase-website/dependency-convergence.html          |   2 +-
 hbase-website/dependency-info.html                 |   2 +-
 hbase-website/dependency-management.html           |   2 +-
 hbase-website/index.html                           |   2 +-
 hbase-website/issue-management.html                |   2 +-
 hbase-website/licenses.html                        |   2 +-
 hbase-website/mailing-lists.html                   |   2 +-
 hbase-website/plugin-management.html               |   2 +-
 hbase-website/plugins.html                         |   2 +-
 hbase-website/project-info.html                    |   2 +-
 hbase-website/scm.html                             |   2 +-
 hbase-website/summary.html                         |   2 +-
 hbase-website/team.html                            |   2 +-
 issue-management.html                              |   2 +-
 licenses.html                                      |   2 +-
 mailing-lists.html                                 |   2 +-
 plugin-management.html                             |   2 +-
 plugins.html                                       |   2 +-
 project-info.html                                  |   2 +-
 project-reports.html                               |   2 +-
 scm.html                                           |   2 +-
 summary.html                                       |   2 +-
 team.html                                          |   2 +-
 testapidocs/index-all.html                         |   2 +
 testapidocs/member-search-index.js                 |   2 +-
 .../apache/hadoop/hbase/util/RSProcDispatcher.html | 242 ++++++++++++-------
 .../hadoop/hbase/util/TestProcDispatcher.html      | 257 +++++++++++----------
 testdevapidocs/constant-values.html                |  11 +
 testdevapidocs/index-all.html                      |  33 ++-
 testdevapidocs/member-search-index.js              |   2 +-
 .../util/RSProcDispatcher.DeadRSRemoteCall.html    |   6 +-
 ...Dispatcher.TestExecuteProceduresRemoteCall.html |  50 +++-
 .../apache/hadoop/hbase/util/RSProcDispatcher.html | 119 ++++++++--
 .../hadoop/hbase/util/TestProcDispatcher.html      |  40 ++--
 .../util/RSProcDispatcher.DeadRSRemoteCall.html    | 242 ++++++++++++-------
 ...Dispatcher.TestExecuteProceduresRemoteCall.html | 242 ++++++++++++-------
 .../apache/hadoop/hbase/util/RSProcDispatcher.html | 242 ++++++++++++-------
 .../hadoop/hbase/util/TestProcDispatcher.html      | 257 +++++++++++----------
 44 files changed, 1133 insertions(+), 668 deletions(-)

diff --git a/books/apache-hbase-reference-guide-dark-mode.pdf b/books/apache-hbase-reference-guide-dark-mode.pdf
index 4418db99d0c..162886d8d28 100644
Binary files a/books/apache-hbase-reference-guide-dark-mode.pdf and b/books/apache-hbase-reference-guide-dark-mode.pdf differ
diff --git a/books/apache-hbase-reference-guide.pdf b/books/apache-hbase-reference-guide.pdf
index 072da602b11..f436519d7a2 100644
Binary files a/books/apache-hbase-reference-guide.pdf and b/books/apache-hbase-reference-guide.pdf differ
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index 7ef7e3727b8..357a34338fc 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:checkstyle-aggregate at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-checkstyle-plugin:3.6.0:checkstyle-aggregate at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/dependency-convergence.html b/dependency-convergence.html
index f7efa987004..c404354e6ed 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-convergence at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-convergence at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/dependency-info.html b/dependency-info.html
index c88a7cc9023..cb587635235 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-info at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-info at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/dependency-management.html b/dependency-management.html
index d397d519ec7..15d4d23d29b 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-management at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-management at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/dependency-convergence.html b/hbase-website/dependency-convergence.html
index 47fbe71a046..058a32f2a77 100644
--- a/hbase-website/dependency-convergence.html
+++ b/hbase-website/dependency-convergence.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-convergence at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-convergence at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/dependency-info.html b/hbase-website/dependency-info.html
index bfe91ac9be5..3733b3cc1e4 100644
--- a/hbase-website/dependency-info.html
+++ b/hbase-website/dependency-info.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-info at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-info at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/dependency-management.html b/hbase-website/dependency-management.html
index 33910217e4f..d0577c5c2d0 100644
--- a/hbase-website/dependency-management.html
+++ b/hbase-website/dependency-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-management at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:dependency-management at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/index.html b/hbase-website/index.html
index 4ebaeed16be..fa304e721ea 100644
--- a/hbase-website/index.html
+++ b/hbase-website/index.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:index at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:index at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/issue-management.html b/hbase-website/issue-management.html
index 5723038fe46..aabed9a9f52 100644
--- a/hbase-website/issue-management.html
+++ b/hbase-website/issue-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:issue-management at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:issue-management at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/licenses.html b/hbase-website/licenses.html
index 4446bd92f23..ac00ed72d27 100644
--- a/hbase-website/licenses.html
+++ b/hbase-website/licenses.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:licenses at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:licenses at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/mailing-lists.html b/hbase-website/mailing-lists.html
index 3d88a1867da..808c896637a 100644
--- a/hbase-website/mailing-lists.html
+++ b/hbase-website/mailing-lists.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:mailing-lists at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:mailing-lists at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/plugin-management.html b/hbase-website/plugin-management.html
index 6eebac8189c..703b6cc6b22 100644
--- a/hbase-website/plugin-management.html
+++ b/hbase-website/plugin-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugin-management at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugin-management at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/plugins.html b/hbase-website/plugins.html
index 015f854a73f..f6576a6dd87 100644
--- a/hbase-website/plugins.html
+++ b/hbase-website/plugins.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugins at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugins at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/project-info.html b/hbase-website/project-info.html
index 872208ca225..9e207665607 100644
--- a/hbase-website/project-info.html
+++ b/hbase-website/project-info.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-info at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-info at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/scm.html b/hbase-website/scm.html
index cfcfe45beda..48f4b96d8e8 100644
--- a/hbase-website/scm.html
+++ b/hbase-website/scm.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:scm at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:scm at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/summary.html b/hbase-website/summary.html
index 20437b5c93b..081998e324b 100644
--- a/hbase-website/summary.html
+++ b/hbase-website/summary.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:summary at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:summary at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/hbase-website/team.html b/hbase-website/team.html
index 3c762eaae3d..98b7d0afc6a 100644
--- a/hbase-website/team.html
+++ b/hbase-website/team.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:team at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:team at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/issue-management.html b/issue-management.html
index 8cf10c24eb4..6b0ec4bdb59 100644
--- a/issue-management.html
+++ b/issue-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:issue-management at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:issue-management at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/licenses.html b/licenses.html
index a76386ad96d..c97a724ce47 100644
--- a/licenses.html
+++ b/licenses.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:licenses at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:licenses at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/mailing-lists.html b/mailing-lists.html
index 1cc8fab2e48..8c2ed1c9054 100644
--- a/mailing-lists.html
+++ b/mailing-lists.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:mailing-lists at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:mailing-lists at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/plugin-management.html b/plugin-management.html
index 671e8c82417..fe320cb83fd 100644
--- a/plugin-management.html
+++ b/plugin-management.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugin-management at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugin-management at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/plugins.html b/plugins.html
index b5e18d9119a..f4aefd06407 100644
--- a/plugins.html
+++ b/plugins.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugins at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:plugins at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/project-info.html b/project-info.html
index ab40aff925c..33dee26cbce 100644
--- a/project-info.html
+++ b/project-info.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-info at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-info at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/project-reports.html b/project-reports.html
index 5cb53341059..e3b447ab831 100644
--- a/project-reports.html
+++ b/project-reports.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-reports at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-site-plugin:3.21.0:project-reports at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/scm.html b/scm.html
index e5ba5b756c5..071d5a927b8 100644
--- a/scm.html
+++ b/scm.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:scm at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:scm at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/summary.html b/summary.html
index 5fcaec77fce..f8b4d9d5842 100644
--- a/summary.html
+++ b/summary.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:summary at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:summary at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/team.html b/team.html
index f18d663275d..0875ca929b4 100644
--- a/team.html
+++ b/team.html
@@ -2,7 +2,7 @@
 
 
 <!--
- | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:team at 2026-07-16
+ | Generated by Apache Maven Doxia Site Renderer 2.0.0 from org.apache.maven.plugins:maven-project-info-reports-plugin:3.9.0:team at 2026-07-20
  | Rendered using Apache Maven Fluido Skin 2.0.0-M9
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
diff --git a/testapidocs/index-all.html b/testapidocs/index-all.html
index e3256861f23..a3df34b88d0 100644
--- a/testapidocs/index-all.html
+++ b/testapidocs/index-all.html
@@ -20672,6 +20672,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="../apidocs/org/apache/hadoop/hbase/util/TestMiniClusterLoadSequential.html#tearDown()" class="member-name-link external-link" title="class or interface in org.apache.hadoop.hbase.util">tearDown()</a> - Method in class org.apache.hadoop.hbase.util.<a href="../apidocs/org/apache/hadoop/hbase/util/TestMiniClusterLoadSequential.html" title="class or interface in org.apache.hadoop.hbase.util" class="external-link">TestMiniClusterLoadSequential</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="../apidocs/org/apache/hadoop/hbase/util/TestProcDispatcher.html#tearDown()" class="member-name-link external-link" title="class or interface in org.apache.hadoop.hbase.util">tearDown()</a> - Method in class org.apache.hadoop.hbase.util.<a href="../apidocs/org/apache/hadoop/hbase/util/TestProcDispatcher.html" title="class or interface in org.apache.hadoop.hbase.util" class="external-link">TestProcDispatcher</a></dt>
+<dd>&nbsp;</dd>
 <dt><a href="../apidocs/org/apache/hadoop/hbase/util/TestRegionMover1.html#tearDown()" class="member-name-link external-link" title="class or interface in org.apache.hadoop.hbase.util">tearDown()</a> - Method in class org.apache.hadoop.hbase.util.<a href="../apidocs/org/apache/hadoop/hbase/util/TestRegionMover1.html" title="class or interface in org.apache.hadoop.hbase.util" class="external-link">TestRegionMover1</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="../apidocs/org/apache/hadoop/hbase/util/TestRegionMover2.html#tearDown()" class="member-name-link external-link" title="class or interface in org.apache.hadoop.hbase.util">tearDown()</a> - Method in class org.apache.hadoop.hbase.util.<a href="../apidocs/org/apache/hadoop/hbase/util/TestRegionMover2.html" title="class or interface in org.apache.hadoop.hbase.util" class="external-link">TestRegionMover2</a></dt>
diff --git a/testapidocs/member-search-index.js b/testapidocs/member-search-index.js
index f1c8c7915a5..f64e6dca3ce 100644
--- a/testapidocs/member-search-index.js
+++ b/testapidocs/member-search-index.js
@@ -1 +1 @@
-memberSearchIndex = [{"p":"org.apache.hadoop.hbase.backup","c":"TestSystemTableSnapshot","l":"_testBackupRestoreSystemTable()"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"TestRegionObserverInterface","l":"A"},{"p":"org.apache.hadoop.hbase.client","c":"TestGetProcedureResult.DummyProcedure","l":"abort(MasterProcedureEnv)","u":"abort(org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv)"},{"p":"org.apache.hadoop.hbase.master","c":"TestMigrateNamespaceTable.SuspendProcedure","l" [...]
\ No newline at end of file
+memberSearchIndex = [{"p":"org.apache.hadoop.hbase.backup","c":"TestSystemTableSnapshot","l":"_testBackupRestoreSystemTable()"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"TestRegionObserverInterface","l":"A"},{"p":"org.apache.hadoop.hbase.client","c":"TestGetProcedureResult.DummyProcedure","l":"abort(MasterProcedureEnv)","u":"abort(org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv)"},{"p":"org.apache.hadoop.hbase.master","c":"TestMigrateNamespaceTable.SuspendProcedure","l" [...]
\ No newline at end of file
diff --git a/testapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html b/testapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html
index b676f94e16b..fcca06ad2ba 100644
--- a/testapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html
+++ b/testapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html
@@ -36,97 +36,165 @@
 <span class="source-line-no">023</span><span id="line-23">import java.util.Arrays;</span>
 <span class="source-line-no">024</span><span id="line-24">import java.util.List;</span>
 <span class="source-line-no">025</span><span id="line-25">import java.util.Set;</span>
-<span class="source-line-no">026</span><span id="line-26">import java.util.concurrent.atomic.AtomicInteger;</span>
-<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.ServerName;</span>
-<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;</span>
-<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;</span>
-<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.master.MasterServices;</span>
-<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;</span>
-<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;</span>
-<span class="source-line-no">033</span><span id="line-33">import org.slf4j.Logger;</span>
-<span class="source-line-no">034</span><span id="line-34">import org.slf4j.LoggerFactory;</span>
-<span class="source-line-no">035</span><span id="line-35"></span>
-<span class="source-line-no">036</span><span id="line-36">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;</span>
-<span class="source-line-no">037</span><span id="line-37"></span>
-<span class="source-line-no">038</span><span id="line-38">/**</span>
-<span class="source-line-no">039</span><span id="line-39"> * Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</span>
-<span class="source-line-no">040</span><span id="line-40"> */</span>
-<span class="source-line-no">041</span><span id="line-41">public class RSProcDispatcher extends RSProcedureDispatcher {</span>
+<span class="source-line-no">026</span><span id="line-26">import java.util.concurrent.atomic.AtomicBoolean;</span>
+<span class="source-line-no">027</span><span id="line-27">import java.util.concurrent.atomic.AtomicInteger;</span>
+<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.ServerName;</span>
+<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.TableName;</span>
+<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;</span>
+<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.client.RegionInfo;</span>
+<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;</span>
+<span class="source-line-no">033</span><span id="line-33">import org.apache.hadoop.hbase.master.MasterServices;</span>
+<span class="source-line-no">034</span><span id="line-34">import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;</span>
+<span class="source-line-no">035</span><span id="line-35">import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;</span>
+<span class="source-line-no">036</span><span id="line-36">import org.slf4j.Logger;</span>
+<span class="source-line-no">037</span><span id="line-37">import org.slf4j.LoggerFactory;</span>
+<span class="source-line-no">038</span><span id="line-38"></span>
+<span class="source-line-no">039</span><span id="line-39">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span>
+<span class="source-line-no">040</span><span id="line-40">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;</span>
+<span class="source-line-no">041</span><span id="line-41">import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;</span>
 <span class="source-line-no">042</span><span id="line-42"></span>
-<span class="source-line-no">043</span><span id="line-43">  private static final Logger LOG = LoggerFactory.getLogger(RSProcDispatcher.class);</span>
-<span class="source-line-no">044</span><span id="line-44"></span>
-<span class="source-line-no">045</span><span id="line-45">  private static final AtomicInteger I = new AtomicInteger();</span>
-<span class="source-line-no">046</span><span id="line-46"></span>
-<span class="source-line-no">047</span><span id="line-47">  private static final List&lt;IOException&gt; ERRORS =</span>
-<span class="source-line-no">048</span><span id="line-48">    Arrays.asList(new ConnectionClosedException("test connection closed error..."),</span>
-<span class="source-line-no">049</span><span id="line-49">      new UnknownHostException("test unknown host error..."),</span>
-<span class="source-line-no">050</span><span id="line-50">      new ConnectException("test connect error..."));</span>
-<span class="source-line-no">051</span><span id="line-51"></span>
-<span class="source-line-no">052</span><span id="line-52">  private static final AtomicInteger ERROR_IDX = new AtomicInteger();</span>
-<span class="source-line-no">053</span><span id="line-53"></span>
-<span class="source-line-no">054</span><span id="line-54">  public RSProcDispatcher(MasterServices master) {</span>
-<span class="source-line-no">055</span><span id="line-55">    super(master);</span>
-<span class="source-line-no">056</span><span id="line-56">  }</span>
+<span class="source-line-no">043</span><span id="line-43">/**</span>
+<span class="source-line-no">044</span><span id="line-44"> * Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</span>
+<span class="source-line-no">045</span><span id="line-45"> */</span>
+<span class="source-line-no">046</span><span id="line-46">public class RSProcDispatcher extends RSProcedureDispatcher {</span>
+<span class="source-line-no">047</span><span id="line-47"></span>
+<span class="source-line-no">048</span><span id="line-48">  private static final Logger LOG = LoggerFactory.getLogger(RSProcDispatcher.class);</span>
+<span class="source-line-no">049</span><span id="line-49"></span>
+<span class="source-line-no">050</span><span id="line-50">  /** Config key for the fail-fast retry limit, shared with the test so the two cannot drift. */</span>
+<span class="source-line-no">051</span><span id="line-51">  static final String FAIL_FAST_LIMIT_KEY = "hbase.master.rs.remote.proc.fail.fast.limit";</span>
+<span class="source-line-no">052</span><span id="line-52"></span>
+<span class="source-line-no">053</span><span id="line-53">  private static final List&lt;IOException&gt; ERRORS =</span>
+<span class="source-line-no">054</span><span id="line-54">    Arrays.asList(new ConnectionClosedException("test connection closed error..."),</span>
+<span class="source-line-no">055</span><span id="line-55">      new UnknownHostException("test unknown host error..."),</span>
+<span class="source-line-no">056</span><span id="line-56">      new ConnectException("test connect error..."));</span>
 <span class="source-line-no">057</span><span id="line-57"></span>
-<span class="source-line-no">058</span><span id="line-58">  @Override</span>
-<span class="source-line-no">059</span><span id="line-59">  protected void remoteDispatch(final ServerName serverName,</span>
-<span class="source-line-no">060</span><span id="line-60">    final Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">061</span><span id="line-61">    if (!master.getServerManager().isServerOnline(serverName)) {</span>
-<span class="source-line-no">062</span><span id="line-62">      // fail fast</span>
-<span class="source-line-no">063</span><span id="line-63">      submitTask(new DeadRSRemoteCall(serverName, remoteProcedures));</span>
-<span class="source-line-no">064</span><span id="line-64">    } else {</span>
-<span class="source-line-no">065</span><span id="line-65">      submitTask(new TestExecuteProceduresRemoteCall(serverName, remoteProcedures));</span>
-<span class="source-line-no">066</span><span id="line-66">    }</span>
-<span class="source-line-no">067</span><span id="line-67">  }</span>
-<span class="source-line-no">068</span><span id="line-68"></span>
-<span class="source-line-no">069</span><span id="line-69">  class TestExecuteProceduresRemoteCall extends ExecuteProceduresRemoteCall {</span>
-<span class="source-line-no">070</span><span id="line-70"></span>
-<span class="source-line-no">071</span><span id="line-71">    public TestExecuteProceduresRemoteCall(ServerName serverName,</span>
-<span class="source-line-no">072</span><span id="line-72">      Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">073</span><span id="line-73">      super(serverName, remoteProcedures);</span>
-<span class="source-line-no">074</span><span id="line-74">    }</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76">    @Override</span>
-<span class="source-line-no">077</span><span id="line-77">    public AdminProtos.ExecuteProceduresResponse sendRequest(final ServerName serverName,</span>
-<span class="source-line-no">078</span><span id="line-78">      final AdminProtos.ExecuteProceduresRequest request) throws IOException {</span>
-<span class="source-line-no">079</span><span id="line-79">      int j = I.addAndGet(1);</span>
-<span class="source-line-no">080</span><span id="line-80">      LOG.info("sendRequest() req: {} , j: {}", request, j);</span>
-<span class="source-line-no">081</span><span id="line-81">      if (j == 12 || j == 22) {</span>
-<span class="source-line-no">082</span><span id="line-82">        // Execute the remote close and open region requests in the last (5th) retry before</span>
-<span class="source-line-no">083</span><span id="line-83">        // throwing ConnectionClosedException. This is to ensure even if the region open/close</span>
-<span class="source-line-no">084</span><span id="line-84">        // is successfully completed by regionserver, master still schedules SCP because</span>
-<span class="source-line-no">085</span><span id="line-85">        // sendRequest() throws error which has retry-limit exhausted.</span>
-<span class="source-line-no">086</span><span id="line-86">        FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
-<span class="source-line-no">087</span><span id="line-87">      }</span>
-<span class="source-line-no">088</span><span id="line-88">      // For one of the close region requests and one of the open region requests,</span>
-<span class="source-line-no">089</span><span id="line-89">      // throw ConnectionClosedException until retry limit is exhausted and master</span>
-<span class="source-line-no">090</span><span id="line-90">      // schedules recoveries for the server.</span>
-<span class="source-line-no">091</span><span id="line-91">      // We will have ABNORMALLY_CLOSED regions, and they are expected to recover on their own.</span>
-<span class="source-line-no">092</span><span id="line-92">      if (j &gt;= 8 &amp;&amp; j &lt;= 13 || j &gt;= 18 &amp;&amp; j &lt;= 23) {</span>
-<span class="source-line-no">093</span><span id="line-93">        throw ERRORS.get(ERROR_IDX.getAndIncrement() % ERRORS.size());</span>
-<span class="source-line-no">094</span><span id="line-94">      }</span>
-<span class="source-line-no">095</span><span id="line-95">      return FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
-<span class="source-line-no">096</span><span id="line-96">    }</span>
-<span class="source-line-no">097</span><span id="line-97"></span>
-<span class="source-line-no">098</span><span id="line-98">    private AsyncRegionServerAdmin getRsAdmin() {</span>
-<span class="source-line-no">099</span><span id="line-99">      return master.getAsyncClusterConnection().getRegionServerAdmin(getServerName());</span>
-<span class="source-line-no">100</span><span id="line-100">    }</span>
-<span class="source-line-no">101</span><span id="line-101">  }</span>
-<span class="source-line-no">102</span><span id="line-102"></span>
-<span class="source-line-no">103</span><span id="line-103">  private class DeadRSRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">058</span><span id="line-58">  private static final AtomicInteger ERROR_IDX = new AtomicInteger();</span>
+<span class="source-line-no">059</span><span id="line-59"></span>
+<span class="source-line-no">060</span><span id="line-60">  // Injection is driven by the test and bound to a target table, not a global call count:</span>
+<span class="source-line-no">061</span><span id="line-61">  // remoteDispatch() fires for every remote procedure in the cluster (startup, table creation,</span>
+<span class="source-line-no">062</span><span id="line-62">  // chores, background assignments), so counting calls drifts and misses the operations under test.</span>
+<span class="source-line-no">063</span><span id="line-63">  private static final AtomicBoolean INJECT = new AtomicBoolean(false);</span>
+<span class="source-line-no">064</span><span id="line-64">  private static final AtomicInteger VICTIMS_REMAINING = new AtomicInteger(0);</span>
+<span class="source-line-no">065</span><span id="line-65">  private static volatile TableName targetTable;</span>
+<span class="source-line-no">066</span><span id="line-66"></span>
+<span class="source-line-no">067</span><span id="line-67">  // Fail-fast retry limit after which the master schedules an SCP; read from conf to match test.</span>
+<span class="source-line-no">068</span><span id="line-68">  private final int failFastLimit;</span>
+<span class="source-line-no">069</span><span id="line-69"></span>
+<span class="source-line-no">070</span><span id="line-70">  /**</span>
+<span class="source-line-no">071</span><span id="line-71">   * Fails the next {@code n} open/close-region requests for {@code table} with connection errors</span>
+<span class="source-line-no">072</span><span id="line-72">   * until the fail-fast retry limit is exhausted, so the master schedules an SCP. Call right before</span>
+<span class="source-line-no">073</span><span id="line-73">   * the operations under test.</span>
+<span class="source-line-no">074</span><span id="line-74">   */</span>
+<span class="source-line-no">075</span><span id="line-75">  static void injectErrorsForNextRequests(TableName table, int n) {</span>
+<span class="source-line-no">076</span><span id="line-76">    ERROR_IDX.set(0);</span>
+<span class="source-line-no">077</span><span id="line-77">    targetTable = table;</span>
+<span class="source-line-no">078</span><span id="line-78">    VICTIMS_REMAINING.set(n);</span>
+<span class="source-line-no">079</span><span id="line-79">    INJECT.set(true);</span>
+<span class="source-line-no">080</span><span id="line-80">  }</span>
+<span class="source-line-no">081</span><span id="line-81"></span>
+<span class="source-line-no">082</span><span id="line-82">  /** Stops error injection. Safe to call unconditionally, e.g. from test teardown. */</span>
+<span class="source-line-no">083</span><span id="line-83">  static void stopInjecting() {</span>
+<span class="source-line-no">084</span><span id="line-84">    INJECT.set(false);</span>
+<span class="source-line-no">085</span><span id="line-85">    VICTIMS_REMAINING.set(0);</span>
+<span class="source-line-no">086</span><span id="line-86">    targetTable = null;</span>
+<span class="source-line-no">087</span><span id="line-87">  }</span>
+<span class="source-line-no">088</span><span id="line-88"></span>
+<span class="source-line-no">089</span><span id="line-89">  public RSProcDispatcher(MasterServices master) {</span>
+<span class="source-line-no">090</span><span id="line-90">    super(master);</span>
+<span class="source-line-no">091</span><span id="line-91">    this.failFastLimit = master.getConfiguration().getInt(FAIL_FAST_LIMIT_KEY, 10);</span>
+<span class="source-line-no">092</span><span id="line-92">  }</span>
+<span class="source-line-no">093</span><span id="line-93"></span>
+<span class="source-line-no">094</span><span id="line-94">  @Override</span>
+<span class="source-line-no">095</span><span id="line-95">  protected void remoteDispatch(final ServerName serverName,</span>
+<span class="source-line-no">096</span><span id="line-96">    final Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">097</span><span id="line-97">    if (!master.getServerManager().isServerOnline(serverName)) {</span>
+<span class="source-line-no">098</span><span id="line-98">      // fail fast</span>
+<span class="source-line-no">099</span><span id="line-99">      submitTask(new DeadRSRemoteCall(serverName, remoteProcedures));</span>
+<span class="source-line-no">100</span><span id="line-100">    } else {</span>
+<span class="source-line-no">101</span><span id="line-101">      submitTask(new TestExecuteProceduresRemoteCall(serverName, remoteProcedures));</span>
+<span class="source-line-no">102</span><span id="line-102">    }</span>
+<span class="source-line-no">103</span><span id="line-103">  }</span>
 <span class="source-line-no">104</span><span id="line-104"></span>
-<span class="source-line-no">105</span><span id="line-105">    public DeadRSRemoteCall(ServerName serverName, Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">106</span><span id="line-106">      super(serverName, remoteProcedures);</span>
-<span class="source-line-no">107</span><span id="line-107">    }</span>
-<span class="source-line-no">108</span><span id="line-108"></span>
-<span class="source-line-no">109</span><span id="line-109">    @Override</span>
-<span class="source-line-no">110</span><span id="line-110">    public void run() {</span>
-<span class="source-line-no">111</span><span id="line-111">      remoteCallFailed(master.getMasterProcedureExecutor().getEnvironment(),</span>
-<span class="source-line-no">112</span><span id="line-112">        new RegionServerStoppedException("Server " + getServerName() + " is not online"));</span>
+<span class="source-line-no">105</span><span id="line-105">  /**</span>
+<span class="source-line-no">106</span><span id="line-106">   * True if the request opens or closes a region of the injection target table. Open requests carry</span>
+<span class="source-line-no">107</span><span id="line-107">   * a full RegionInfo; close requests carry a REGION_NAME specifier the table is parsed from.</span>
+<span class="source-line-no">108</span><span id="line-108">   */</span>
+<span class="source-line-no">109</span><span id="line-109">  private static boolean targetsInjectionTable(AdminProtos.ExecuteProceduresRequest request) {</span>
+<span class="source-line-no">110</span><span id="line-110">    TableName table = targetTable;</span>
+<span class="source-line-no">111</span><span id="line-111">    if (table == null) {</span>
+<span class="source-line-no">112</span><span id="line-112">      return false;</span>
 <span class="source-line-no">113</span><span id="line-113">    }</span>
-<span class="source-line-no">114</span><span id="line-114">  }</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116">}</span>
+<span class="source-line-no">114</span><span id="line-114">    for (AdminProtos.OpenRegionRequest open : request.getOpenRegionList()) {</span>
+<span class="source-line-no">115</span><span id="line-115">      for (AdminProtos.OpenRegionRequest.RegionOpenInfo info : open.getOpenInfoList()) {</span>
+<span class="source-line-no">116</span><span id="line-116">        if (table.equals(ProtobufUtil.toTableName(info.getRegion().getTableName()))) {</span>
+<span class="source-line-no">117</span><span id="line-117">          return true;</span>
+<span class="source-line-no">118</span><span id="line-118">        }</span>
+<span class="source-line-no">119</span><span id="line-119">      }</span>
+<span class="source-line-no">120</span><span id="line-120">    }</span>
+<span class="source-line-no">121</span><span id="line-121">    for (AdminProtos.CloseRegionRequest close : request.getCloseRegionList()) {</span>
+<span class="source-line-no">122</span><span id="line-122">      HBaseProtos.RegionSpecifier region = close.getRegion();</span>
+<span class="source-line-no">123</span><span id="line-123">      if (</span>
+<span class="source-line-no">124</span><span id="line-124">        region.getType() == HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME</span>
+<span class="source-line-no">125</span><span id="line-125">          &amp;&amp; table.equals(RegionInfo.getTable(region.getValue().toByteArray()))</span>
+<span class="source-line-no">126</span><span id="line-126">      ) {</span>
+<span class="source-line-no">127</span><span id="line-127">        return true;</span>
+<span class="source-line-no">128</span><span id="line-128">      }</span>
+<span class="source-line-no">129</span><span id="line-129">    }</span>
+<span class="source-line-no">130</span><span id="line-130">    return false;</span>
+<span class="source-line-no">131</span><span id="line-131">  }</span>
+<span class="source-line-no">132</span><span id="line-132"></span>
+<span class="source-line-no">133</span><span id="line-133">  class TestExecuteProceduresRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">134</span><span id="line-134"></span>
+<span class="source-line-no">135</span><span id="line-135">    // attempts: retries of this single request instance (mirrors the dispatcher's</span>
+<span class="source-line-no">136</span><span id="line-136">    // numberOfAttemptsSoFar). injectErrors: whether this instance is failed with injected errors,</span>
+<span class="source-line-no">137</span><span id="line-137">    // decided once on the first call and kept across its retries.</span>
+<span class="source-line-no">138</span><span id="line-138">    private int attempts = 0;</span>
+<span class="source-line-no">139</span><span id="line-139">    private Boolean injectErrors = null;</span>
+<span class="source-line-no">140</span><span id="line-140"></span>
+<span class="source-line-no">141</span><span id="line-141">    public TestExecuteProceduresRemoteCall(ServerName serverName,</span>
+<span class="source-line-no">142</span><span id="line-142">      Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">143</span><span id="line-143">      super(serverName, remoteProcedures);</span>
+<span class="source-line-no">144</span><span id="line-144">    }</span>
+<span class="source-line-no">145</span><span id="line-145"></span>
+<span class="source-line-no">146</span><span id="line-146">    @Override</span>
+<span class="source-line-no">147</span><span id="line-147">    public AdminProtos.ExecuteProceduresResponse sendRequest(final ServerName serverName,</span>
+<span class="source-line-no">148</span><span id="line-148">      final AdminProtos.ExecuteProceduresRequest request) throws IOException {</span>
+<span class="source-line-no">149</span><span id="line-149">      if (injectErrors == null) {</span>
+<span class="source-line-no">150</span><span id="line-150">        // Claim a slot only for a target-table open/close request, once per instance.</span>
+<span class="source-line-no">151</span><span id="line-151">        injectErrors =</span>
+<span class="source-line-no">152</span><span id="line-152">          INJECT.get() &amp;&amp; targetsInjectionTable(request) &amp;&amp; VICTIMS_REMAINING.getAndDecrement() &gt; 0;</span>
+<span class="source-line-no">153</span><span id="line-153">      }</span>
+<span class="source-line-no">154</span><span id="line-154">      LOG.info("sendRequest() req: {}, attempts: {}, injectErrors: {}", request, attempts,</span>
+<span class="source-line-no">155</span><span id="line-155">        injectErrors);</span>
+<span class="source-line-no">156</span><span id="line-156">      if (!injectErrors) {</span>
+<span class="source-line-no">157</span><span id="line-157">        return FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
+<span class="source-line-no">158</span><span id="line-158">      }</span>
+<span class="source-line-no">159</span><span id="line-159">      // Throw a connection error each attempt until the retry limit is exhausted (-&gt; SCP). On the</span>
+<span class="source-line-no">160</span><span id="line-160">      // last attempt run the real open/close first so the region still recovers.</span>
+<span class="source-line-no">161</span><span id="line-161">      if (attempts++ &gt;= failFastLimit - 1) {</span>
+<span class="source-line-no">162</span><span id="line-162">        FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
+<span class="source-line-no">163</span><span id="line-163">      }</span>
+<span class="source-line-no">164</span><span id="line-164">      throw ERRORS.get(ERROR_IDX.getAndIncrement() % ERRORS.size());</span>
+<span class="source-line-no">165</span><span id="line-165">    }</span>
+<span class="source-line-no">166</span><span id="line-166"></span>
+<span class="source-line-no">167</span><span id="line-167">    private AsyncRegionServerAdmin getRsAdmin() {</span>
+<span class="source-line-no">168</span><span id="line-168">      return master.getAsyncClusterConnection().getRegionServerAdmin(getServerName());</span>
+<span class="source-line-no">169</span><span id="line-169">    }</span>
+<span class="source-line-no">170</span><span id="line-170">  }</span>
+<span class="source-line-no">171</span><span id="line-171"></span>
+<span class="source-line-no">172</span><span id="line-172">  private class DeadRSRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">173</span><span id="line-173"></span>
+<span class="source-line-no">174</span><span id="line-174">    public DeadRSRemoteCall(ServerName serverName, Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">175</span><span id="line-175">      super(serverName, remoteProcedures);</span>
+<span class="source-line-no">176</span><span id="line-176">    }</span>
+<span class="source-line-no">177</span><span id="line-177"></span>
+<span class="source-line-no">178</span><span id="line-178">    @Override</span>
+<span class="source-line-no">179</span><span id="line-179">    public void run() {</span>
+<span class="source-line-no">180</span><span id="line-180">      remoteCallFailed(master.getMasterProcedureExecutor().getEnvironment(),</span>
+<span class="source-line-no">181</span><span id="line-181">        new RegionServerStoppedException("Server " + getServerName() + " is not online"));</span>
+<span class="source-line-no">182</span><span id="line-182">    }</span>
+<span class="source-line-no">183</span><span id="line-183">  }</span>
+<span class="source-line-no">184</span><span id="line-184">}</span>
 
 
 
diff --git a/testapidocs/src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html b/testapidocs/src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html
index 9316d77f071..151ac524f28 100644
--- a/testapidocs/src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html
+++ b/testapidocs/src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html
@@ -55,131 +55,138 @@
 <span class="source-line-no">042</span><span id="line-42">import org.apache.hadoop.hbase.testclassification.LargeTests;</span>
 <span class="source-line-no">043</span><span id="line-43">import org.apache.hadoop.hbase.testclassification.MiscTests;</span>
 <span class="source-line-no">044</span><span id="line-44">import org.junit.jupiter.api.AfterAll;</span>
-<span class="source-line-no">045</span><span id="line-45">import org.junit.jupiter.api.BeforeAll;</span>
-<span class="source-line-no">046</span><span id="line-46">import org.junit.jupiter.api.BeforeEach;</span>
-<span class="source-line-no">047</span><span id="line-47">import org.junit.jupiter.api.Tag;</span>
-<span class="source-line-no">048</span><span id="line-48">import org.junit.jupiter.api.Test;</span>
-<span class="source-line-no">049</span><span id="line-49">import org.junit.jupiter.api.TestInfo;</span>
-<span class="source-line-no">050</span><span id="line-50">import org.slf4j.Logger;</span>
-<span class="source-line-no">051</span><span id="line-51">import org.slf4j.LoggerFactory;</span>
-<span class="source-line-no">052</span><span id="line-52"></span>
-<span class="source-line-no">053</span><span id="line-53">import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;</span>
-<span class="source-line-no">054</span><span id="line-54"></span>
-<span class="source-line-no">055</span><span id="line-55">/**</span>
-<span class="source-line-no">056</span><span id="line-56"> * Testing custom RSProcedureDispatcher to ensure retry limit can be imposed on certain errors.</span>
-<span class="source-line-no">057</span><span id="line-57"> */</span>
-<span class="source-line-no">058</span><span id="line-58">@Tag(MiscTests.TAG)</span>
-<span class="source-line-no">059</span><span id="line-59">@Tag(LargeTests.TAG)</span>
-<span class="source-line-no">060</span><span id="line-60">public class TestProcDispatcher {</span>
-<span class="source-line-no">061</span><span id="line-61"></span>
-<span class="source-line-no">062</span><span id="line-62">  private static final Logger LOG = LoggerFactory.getLogger(TestProcDispatcher.class);</span>
-<span class="source-line-no">063</span><span id="line-63"></span>
-<span class="source-line-no">064</span><span id="line-64">  private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();</span>
-<span class="source-line-no">065</span><span id="line-65">  private static ServerName rs0;</span>
-<span class="source-line-no">066</span><span id="line-66"></span>
-<span class="source-line-no">067</span><span id="line-67">  @BeforeAll</span>
-<span class="source-line-no">068</span><span id="line-68">  public static void setUpBeforeClass() throws Exception {</span>
-<span class="source-line-no">069</span><span id="line-69">    TEST_UTIL.getConfiguration().set(HBASE_MASTER_RSPROC_DISPATCHER_CLASS,</span>
-<span class="source-line-no">070</span><span id="line-70">      RSProcDispatcher.class.getName());</span>
-<span class="source-line-no">071</span><span id="line-71">    TEST_UTIL.getConfiguration().setInt("hbase.master.rs.remote.proc.fail.fast.limit", 5);</span>
-<span class="source-line-no">072</span><span id="line-72">    TEST_UTIL.startMiniCluster(3);</span>
-<span class="source-line-no">073</span><span id="line-73">    SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();</span>
-<span class="source-line-no">074</span><span id="line-74">    rs0 = cluster.getRegionServer(0).getServerName();</span>
-<span class="source-line-no">075</span><span id="line-75">    TEST_UTIL.getAdmin().balancerSwitch(false, true);</span>
-<span class="source-line-no">076</span><span id="line-76">  }</span>
-<span class="source-line-no">077</span><span id="line-77"></span>
-<span class="source-line-no">078</span><span id="line-78">  @AfterAll</span>
-<span class="source-line-no">079</span><span id="line-79">  public static void tearDownAfterClass() throws Exception {</span>
-<span class="source-line-no">080</span><span id="line-80">    TEST_UTIL.shutdownMiniCluster();</span>
-<span class="source-line-no">081</span><span id="line-81">  }</span>
-<span class="source-line-no">082</span><span id="line-82"></span>
-<span class="source-line-no">083</span><span id="line-83">  @BeforeEach</span>
-<span class="source-line-no">084</span><span id="line-84">  public void setUp(TestInfo testInfo) throws Exception {</span>
-<span class="source-line-no">085</span><span id="line-85">    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());</span>
-<span class="source-line-no">086</span><span id="line-86">    TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(tableName)</span>
-<span class="source-line-no">087</span><span id="line-87">      .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();</span>
-<span class="source-line-no">088</span><span id="line-88">    int startKey = 0;</span>
-<span class="source-line-no">089</span><span id="line-89">    int endKey = 80000;</span>
-<span class="source-line-no">090</span><span id="line-90">    TEST_UTIL.getAdmin().createTable(tableDesc, Bytes.toBytes(startKey), Bytes.toBytes(endKey), 9);</span>
-<span class="source-line-no">091</span><span id="line-91">  }</span>
-<span class="source-line-no">092</span><span id="line-92"></span>
-<span class="source-line-no">093</span><span id="line-93">  @Test</span>
-<span class="source-line-no">094</span><span id="line-94">  public void testRetryLimitOnConnClosedErrors(TestInfo testInfo) throws Exception {</span>
-<span class="source-line-no">095</span><span id="line-95">    HbckChore hbckChore = new HbckChore(TEST_UTIL.getHBaseCluster().getMaster());</span>
-<span class="source-line-no">096</span><span id="line-96">    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());</span>
-<span class="source-line-no">097</span><span id="line-97">    SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();</span>
-<span class="source-line-no">098</span><span id="line-98">    Admin admin = TEST_UTIL.getAdmin();</span>
-<span class="source-line-no">099</span><span id="line-99">    Table table = TEST_UTIL.getConnection().getTable(tableName);</span>
-<span class="source-line-no">100</span><span id="line-100">    List&lt;Put&gt; puts = IntStream.range(10, 50000).mapToObj(i -&gt; new Put(Bytes.toBytes(i))</span>
-<span class="source-line-no">101</span><span id="line-101">      .addColumn(Bytes.toBytes("fam1"), Bytes.toBytes("q1"), Bytes.toBytes("val_" + i)))</span>
-<span class="source-line-no">102</span><span id="line-102">      .collect(Collectors.toList());</span>
-<span class="source-line-no">103</span><span id="line-103">    table.put(puts);</span>
-<span class="source-line-no">104</span><span id="line-104">    admin.flush(tableName);</span>
-<span class="source-line-no">105</span><span id="line-105">    admin.compact(tableName);</span>
-<span class="source-line-no">106</span><span id="line-106">    Thread.sleep(3000);</span>
-<span class="source-line-no">107</span><span id="line-107">    HRegionServer hRegionServer0 = cluster.getRegionServer(0);</span>
-<span class="source-line-no">108</span><span id="line-108">    HRegionServer hRegionServer1 = cluster.getRegionServer(1);</span>
-<span class="source-line-no">109</span><span id="line-109">    HRegionServer hRegionServer2 = cluster.getRegionServer(2);</span>
-<span class="source-line-no">110</span><span id="line-110">    int numRegions0 = hRegionServer0.getNumberOfOnlineRegions();</span>
-<span class="source-line-no">111</span><span id="line-111">    int numRegions1 = hRegionServer1.getNumberOfOnlineRegions();</span>
-<span class="source-line-no">112</span><span id="line-112">    int numRegions2 = hRegionServer2.getNumberOfOnlineRegions();</span>
-<span class="source-line-no">113</span><span id="line-113"></span>
-<span class="source-line-no">114</span><span id="line-114">    hbckChore.choreForTesting();</span>
-<span class="source-line-no">115</span><span id="line-115">    HbckReport hbckReport = hbckChore.getLastReport();</span>
-<span class="source-line-no">116</span><span id="line-116">    assertEquals(0, hbckReport.getInconsistentRegions().size());</span>
-<span class="source-line-no">117</span><span id="line-117">    assertEquals(0, hbckReport.getOrphanRegionsOnFS().size());</span>
-<span class="source-line-no">118</span><span id="line-118">    assertEquals(0, hbckReport.getOrphanRegionsOnRS().size());</span>
-<span class="source-line-no">119</span><span id="line-119"></span>
-<span class="source-line-no">120</span><span id="line-120">    HRegion region0 = hRegionServer0.getRegions().get(0);</span>
-<span class="source-line-no">121</span><span id="line-121">    // move all regions from server1 to server0</span>
-<span class="source-line-no">122</span><span id="line-122">    for (HRegion region : hRegionServer1.getRegions()) {</span>
-<span class="source-line-no">123</span><span id="line-123">      TEST_UTIL.getAdmin().move(region.getRegionInfo().getEncodedNameAsBytes(), rs0);</span>
-<span class="source-line-no">124</span><span id="line-124">    }</span>
-<span class="source-line-no">125</span><span id="line-125">    TEST_UTIL.getAdmin().move(region0.getRegionInfo().getEncodedNameAsBytes());</span>
-<span class="source-line-no">126</span><span id="line-126">    HMaster master = TEST_UTIL.getHBaseCluster().getMaster();</span>
-<span class="source-line-no">127</span><span id="line-127"></span>
-<span class="source-line-no">128</span><span id="line-128">    // Ensure:</span>
-<span class="source-line-no">129</span><span id="line-129">    // 1. num of regions before and after scheduling SCP remain same</span>
-<span class="source-line-no">130</span><span id="line-130">    // 2. all procedures including SCPs are successfully completed</span>
-<span class="source-line-no">131</span><span id="line-131">    // 3. two servers have SCPs scheduled</span>
-<span class="source-line-no">132</span><span id="line-132">    TEST_UTIL.waitFor(5000, 1000, () -&gt; {</span>
-<span class="source-line-no">133</span><span id="line-133">      LOG.info("numRegions0: {} , numRegions1: {} , numRegions2: {}", numRegions0, numRegions1,</span>
-<span class="source-line-no">134</span><span id="line-134">        numRegions2);</span>
-<span class="source-line-no">135</span><span id="line-135">      LOG.info("Online regions - server0 : {} , server1: {} , server2: {}",</span>
-<span class="source-line-no">136</span><span id="line-136">        cluster.getRegionServer(0).getNumberOfOnlineRegions(),</span>
-<span class="source-line-no">137</span><span id="line-137">        cluster.getRegionServer(1).getNumberOfOnlineRegions(),</span>
-<span class="source-line-no">138</span><span id="line-138">        cluster.getRegionServer(2).getNumberOfOnlineRegions());</span>
-<span class="source-line-no">139</span><span id="line-139">      LOG.info("Num of successfully completed procedures: {} , num of all procedures: {}",</span>
-<span class="source-line-no">140</span><span id="line-140">        master.getMasterProcedureExecutor().getProcedures().stream()</span>
-<span class="source-line-no">141</span><span id="line-141">          .filter(masterProcedureEnvProcedure -&gt; masterProcedureEnvProcedure.getState()</span>
-<span class="source-line-no">142</span><span id="line-142">              == ProcedureProtos.ProcedureState.SUCCESS)</span>
-<span class="source-line-no">143</span><span id="line-143">          .count(),</span>
-<span class="source-line-no">144</span><span id="line-144">        master.getMasterProcedureExecutor().getProcedures().size());</span>
-<span class="source-line-no">145</span><span id="line-145">      LOG.info("Num of SCPs: " + master.getMasterProcedureExecutor().getProcedures().stream()</span>
-<span class="source-line-no">146</span><span id="line-146">        .filter(proc -&gt; proc instanceof ServerCrashProcedure).count());</span>
-<span class="source-line-no">147</span><span id="line-147">      return (numRegions0 + numRegions1 + numRegions2)</span>
-<span class="source-line-no">148</span><span id="line-148">          == (cluster.getRegionServer(0).getNumberOfOnlineRegions()</span>
-<span class="source-line-no">149</span><span id="line-149">            + cluster.getRegionServer(1).getNumberOfOnlineRegions()</span>
-<span class="source-line-no">150</span><span id="line-150">            + cluster.getRegionServer(2).getNumberOfOnlineRegions())</span>
-<span class="source-line-no">151</span><span id="line-151">        &amp;&amp; master.getMasterProcedureExecutor().getProcedures().stream()</span>
-<span class="source-line-no">152</span><span id="line-152">          .filter(masterProcedureEnvProcedure -&gt; masterProcedureEnvProcedure.getState()</span>
-<span class="source-line-no">153</span><span id="line-153">              == ProcedureProtos.ProcedureState.SUCCESS)</span>
-<span class="source-line-no">154</span><span id="line-154">          .count() == master.getMasterProcedureExecutor().getProcedures().size()</span>
-<span class="source-line-no">155</span><span id="line-155">        &amp;&amp; master.getMasterProcedureExecutor().getProcedures().stream()</span>
-<span class="source-line-no">156</span><span id="line-156">          .anyMatch(proc -&gt; proc instanceof ServerCrashProcedure);</span>
-<span class="source-line-no">157</span><span id="line-157">    });</span>
-<span class="source-line-no">158</span><span id="line-158"></span>
-<span class="source-line-no">159</span><span id="line-159">    // Ensure we have no inconsistent regions</span>
-<span class="source-line-no">160</span><span id="line-160">    TEST_UTIL.waitFor(5000, 1000, () -&gt; {</span>
-<span class="source-line-no">161</span><span id="line-161">      hbckChore.choreForTesting();</span>
-<span class="source-line-no">162</span><span id="line-162">      HbckReport report = hbckChore.getLastReport();</span>
-<span class="source-line-no">163</span><span id="line-163">      return report.getInconsistentRegions().isEmpty() &amp;&amp; report.getOrphanRegionsOnFS().isEmpty()</span>
-<span class="source-line-no">164</span><span id="line-164">        &amp;&amp; report.getOrphanRegionsOnRS().isEmpty();</span>
-<span class="source-line-no">165</span><span id="line-165">    });</span>
-<span class="source-line-no">166</span><span id="line-166"></span>
-<span class="source-line-no">167</span><span id="line-167">  }</span>
-<span class="source-line-no">168</span><span id="line-168"></span>
-<span class="source-line-no">169</span><span id="line-169">}</span>
+<span class="source-line-no">045</span><span id="line-45">import org.junit.jupiter.api.AfterEach;</span>
+<span class="source-line-no">046</span><span id="line-46">import org.junit.jupiter.api.BeforeAll;</span>
+<span class="source-line-no">047</span><span id="line-47">import org.junit.jupiter.api.BeforeEach;</span>
+<span class="source-line-no">048</span><span id="line-48">import org.junit.jupiter.api.Tag;</span>
+<span class="source-line-no">049</span><span id="line-49">import org.junit.jupiter.api.Test;</span>
+<span class="source-line-no">050</span><span id="line-50">import org.junit.jupiter.api.TestInfo;</span>
+<span class="source-line-no">051</span><span id="line-51">import org.slf4j.Logger;</span>
+<span class="source-line-no">052</span><span id="line-52">import org.slf4j.LoggerFactory;</span>
+<span class="source-line-no">053</span><span id="line-53"></span>
+<span class="source-line-no">054</span><span id="line-54">import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;</span>
+<span class="source-line-no">055</span><span id="line-55"></span>
+<span class="source-line-no">056</span><span id="line-56">/**</span>
+<span class="source-line-no">057</span><span id="line-57"> * Testing custom RSProcedureDispatcher to ensure retry limit can be imposed on certain errors.</span>
+<span class="source-line-no">058</span><span id="line-58"> */</span>
+<span class="source-line-no">059</span><span id="line-59">@Tag(MiscTests.TAG)</span>
+<span class="source-line-no">060</span><span id="line-60">@Tag(LargeTests.TAG)</span>
+<span class="source-line-no">061</span><span id="line-61">public class TestProcDispatcher {</span>
+<span class="source-line-no">062</span><span id="line-62"></span>
+<span class="source-line-no">063</span><span id="line-63">  private static final Logger LOG = LoggerFactory.getLogger(TestProcDispatcher.class);</span>
+<span class="source-line-no">064</span><span id="line-64"></span>
+<span class="source-line-no">065</span><span id="line-65">  private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();</span>
+<span class="source-line-no">066</span><span id="line-66">  private static ServerName rs0;</span>
+<span class="source-line-no">067</span><span id="line-67"></span>
+<span class="source-line-no">068</span><span id="line-68">  @BeforeAll</span>
+<span class="source-line-no">069</span><span id="line-69">  public static void setUpBeforeClass() throws Exception {</span>
+<span class="source-line-no">070</span><span id="line-70">    TEST_UTIL.getConfiguration().set(HBASE_MASTER_RSPROC_DISPATCHER_CLASS,</span>
+<span class="source-line-no">071</span><span id="line-71">      RSProcDispatcher.class.getName());</span>
+<span class="source-line-no">072</span><span id="line-72">    TEST_UTIL.getConfiguration().setInt(RSProcDispatcher.FAIL_FAST_LIMIT_KEY, 5);</span>
+<span class="source-line-no">073</span><span id="line-73">    TEST_UTIL.startMiniCluster(3);</span>
+<span class="source-line-no">074</span><span id="line-74">    SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();</span>
+<span class="source-line-no">075</span><span id="line-75">    rs0 = cluster.getRegionServer(0).getServerName();</span>
+<span class="source-line-no">076</span><span id="line-76">    TEST_UTIL.getAdmin().balancerSwitch(false, true);</span>
+<span class="source-line-no">077</span><span id="line-77">  }</span>
+<span class="source-line-no">078</span><span id="line-78"></span>
+<span class="source-line-no">079</span><span id="line-79">  @AfterAll</span>
+<span class="source-line-no">080</span><span id="line-80">  public static void tearDownAfterClass() throws Exception {</span>
+<span class="source-line-no">081</span><span id="line-81">    TEST_UTIL.shutdownMiniCluster();</span>
+<span class="source-line-no">082</span><span id="line-82">  }</span>
+<span class="source-line-no">083</span><span id="line-83"></span>
+<span class="source-line-no">084</span><span id="line-84">  @BeforeEach</span>
+<span class="source-line-no">085</span><span id="line-85">  public void setUp(TestInfo testInfo) throws Exception {</span>
+<span class="source-line-no">086</span><span id="line-86">    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());</span>
+<span class="source-line-no">087</span><span id="line-87">    TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(tableName)</span>
+<span class="source-line-no">088</span><span id="line-88">      .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();</span>
+<span class="source-line-no">089</span><span id="line-89">    int startKey = 0;</span>
+<span class="source-line-no">090</span><span id="line-90">    int endKey = 80000;</span>
+<span class="source-line-no">091</span><span id="line-91">    TEST_UTIL.getAdmin().createTable(tableDesc, Bytes.toBytes(startKey), Bytes.toBytes(endKey), 9);</span>
+<span class="source-line-no">092</span><span id="line-92">  }</span>
+<span class="source-line-no">093</span><span id="line-93"></span>
+<span class="source-line-no">094</span><span id="line-94">  @AfterEach</span>
+<span class="source-line-no">095</span><span id="line-95">  public void tearDown() {</span>
+<span class="source-line-no">096</span><span id="line-96">    RSProcDispatcher.stopInjecting();</span>
+<span class="source-line-no">097</span><span id="line-97">  }</span>
+<span class="source-line-no">098</span><span id="line-98"></span>
+<span class="source-line-no">099</span><span id="line-99">  @Test</span>
+<span class="source-line-no">100</span><span id="line-100">  public void testRetryLimitOnConnClosedErrors(TestInfo testInfo) throws Exception {</span>
+<span class="source-line-no">101</span><span id="line-101">    HbckChore hbckChore = new HbckChore(TEST_UTIL.getHBaseCluster().getMaster());</span>
+<span class="source-line-no">102</span><span id="line-102">    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());</span>
+<span class="source-line-no">103</span><span id="line-103">    SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();</span>
+<span class="source-line-no">104</span><span id="line-104">    Admin admin = TEST_UTIL.getAdmin();</span>
+<span class="source-line-no">105</span><span id="line-105">    List&lt;Put&gt; puts = IntStream.range(10, 50000).mapToObj(i -&gt; new Put(Bytes.toBytes(i))</span>
+<span class="source-line-no">106</span><span id="line-106">      .addColumn(Bytes.toBytes("fam1"), Bytes.toBytes("q1"), Bytes.toBytes("val_" + i)))</span>
+<span class="source-line-no">107</span><span id="line-107">      .collect(Collectors.toList());</span>
+<span class="source-line-no">108</span><span id="line-108">    try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {</span>
+<span class="source-line-no">109</span><span id="line-109">      table.put(puts);</span>
+<span class="source-line-no">110</span><span id="line-110">    }</span>
+<span class="source-line-no">111</span><span id="line-111">    admin.flush(tableName);</span>
+<span class="source-line-no">112</span><span id="line-112">    admin.compact(tableName);</span>
+<span class="source-line-no">113</span><span id="line-113">    Thread.sleep(3000);</span>
+<span class="source-line-no">114</span><span id="line-114">    HRegionServer hRegionServer0 = cluster.getRegionServer(0);</span>
+<span class="source-line-no">115</span><span id="line-115">    HRegionServer hRegionServer1 = cluster.getRegionServer(1);</span>
+<span class="source-line-no">116</span><span id="line-116">    HRegionServer hRegionServer2 = cluster.getRegionServer(2);</span>
+<span class="source-line-no">117</span><span id="line-117">    int numRegions0 = hRegionServer0.getNumberOfOnlineRegions();</span>
+<span class="source-line-no">118</span><span id="line-118">    int numRegions1 = hRegionServer1.getNumberOfOnlineRegions();</span>
+<span class="source-line-no">119</span><span id="line-119">    int numRegions2 = hRegionServer2.getNumberOfOnlineRegions();</span>
+<span class="source-line-no">120</span><span id="line-120"></span>
+<span class="source-line-no">121</span><span id="line-121">    hbckChore.choreForTesting();</span>
+<span class="source-line-no">122</span><span id="line-122">    HbckReport hbckReport = hbckChore.getLastReport();</span>
+<span class="source-line-no">123</span><span id="line-123">    assertEquals(0, hbckReport.getInconsistentRegions().size());</span>
+<span class="source-line-no">124</span><span id="line-124">    assertEquals(0, hbckReport.getOrphanRegionsOnFS().size());</span>
+<span class="source-line-no">125</span><span id="line-125">    assertEquals(0, hbckReport.getOrphanRegionsOnRS().size());</span>
+<span class="source-line-no">126</span><span id="line-126"></span>
+<span class="source-line-no">127</span><span id="line-127">    HRegion region0 = hRegionServer0.getRegions().get(0);</span>
+<span class="source-line-no">128</span><span id="line-128">    // Fail the next two open/close-region requests for this table so the moves trigger SCP(s).</span>
+<span class="source-line-no">129</span><span id="line-129">    RSProcDispatcher.injectErrorsForNextRequests(tableName, 2);</span>
+<span class="source-line-no">130</span><span id="line-130">    // move all regions from server1 to server0</span>
+<span class="source-line-no">131</span><span id="line-131">    for (HRegion region : hRegionServer1.getRegions()) {</span>
+<span class="source-line-no">132</span><span id="line-132">      TEST_UTIL.getAdmin().move(region.getRegionInfo().getEncodedNameAsBytes(), rs0);</span>
+<span class="source-line-no">133</span><span id="line-133">    }</span>
+<span class="source-line-no">134</span><span id="line-134">    TEST_UTIL.getAdmin().move(region0.getRegionInfo().getEncodedNameAsBytes());</span>
+<span class="source-line-no">135</span><span id="line-135">    HMaster master = TEST_UTIL.getHBaseCluster().getMaster();</span>
+<span class="source-line-no">136</span><span id="line-136"></span>
+<span class="source-line-no">137</span><span id="line-137">    // Ensure, after the injected connection errors:</span>
+<span class="source-line-no">138</span><span id="line-138">    // 1. the total number of regions is unchanged before and after the SCP(s)</span>
+<span class="source-line-no">139</span><span id="line-139">    // 2. all procedures (including the SCP(s)) complete successfully</span>
+<span class="source-line-no">140</span><span id="line-140">    // 3. at least one ServerCrashProcedure was scheduled</span>
+<span class="source-line-no">141</span><span id="line-141">    TEST_UTIL.waitFor(60000, 1000, () -&gt; {</span>
+<span class="source-line-no">142</span><span id="line-142">      LOG.info("numRegions0: {} , numRegions1: {} , numRegions2: {}", numRegions0, numRegions1,</span>
+<span class="source-line-no">143</span><span id="line-143">        numRegions2);</span>
+<span class="source-line-no">144</span><span id="line-144">      LOG.info("Online regions - server0 : {} , server1: {} , server2: {}",</span>
+<span class="source-line-no">145</span><span id="line-145">        cluster.getRegionServer(0).getNumberOfOnlineRegions(),</span>
+<span class="source-line-no">146</span><span id="line-146">        cluster.getRegionServer(1).getNumberOfOnlineRegions(),</span>
+<span class="source-line-no">147</span><span id="line-147">        cluster.getRegionServer(2).getNumberOfOnlineRegions());</span>
+<span class="source-line-no">148</span><span id="line-148">      LOG.info("Num of successfully completed procedures: {} , num of all procedures: {}",</span>
+<span class="source-line-no">149</span><span id="line-149">        master.getMasterProcedureExecutor().getProcedures().stream()</span>
+<span class="source-line-no">150</span><span id="line-150">          .filter(masterProcedureEnvProcedure -&gt; masterProcedureEnvProcedure.getState()</span>
+<span class="source-line-no">151</span><span id="line-151">              == ProcedureProtos.ProcedureState.SUCCESS)</span>
+<span class="source-line-no">152</span><span id="line-152">          .count(),</span>
+<span class="source-line-no">153</span><span id="line-153">        master.getMasterProcedureExecutor().getProcedures().size());</span>
+<span class="source-line-no">154</span><span id="line-154">      LOG.info("Num of SCPs: {}", master.getMasterProcedureExecutor().getProcedures().stream()</span>
+<span class="source-line-no">155</span><span id="line-155">        .filter(proc -&gt; proc instanceof ServerCrashProcedure).count());</span>
+<span class="source-line-no">156</span><span id="line-156">      return (numRegions0 + numRegions1 + numRegions2)</span>
+<span class="source-line-no">157</span><span id="line-157">          == (cluster.getRegionServer(0).getNumberOfOnlineRegions()</span>
+<span class="source-line-no">158</span><span id="line-158">            + cluster.getRegionServer(1).getNumberOfOnlineRegions()</span>
+<span class="source-line-no">159</span><span id="line-159">            + cluster.getRegionServer(2).getNumberOfOnlineRegions())</span>
+<span class="source-line-no">160</span><span id="line-160">        &amp;&amp; master.getMasterProcedureExecutor().getProcedures().stream()</span>
+<span class="source-line-no">161</span><span id="line-161">          .filter(masterProcedureEnvProcedure -&gt; masterProcedureEnvProcedure.getState()</span>
+<span class="source-line-no">162</span><span id="line-162">              == ProcedureProtos.ProcedureState.SUCCESS)</span>
+<span class="source-line-no">163</span><span id="line-163">          .count() == master.getMasterProcedureExecutor().getProcedures().size()</span>
+<span class="source-line-no">164</span><span id="line-164">        &amp;&amp; master.getMasterProcedureExecutor().getProcedures().stream()</span>
+<span class="source-line-no">165</span><span id="line-165">          .anyMatch(proc -&gt; proc instanceof ServerCrashProcedure);</span>
+<span class="source-line-no">166</span><span id="line-166">    });</span>
+<span class="source-line-no">167</span><span id="line-167"></span>
+<span class="source-line-no">168</span><span id="line-168">    // Ensure we have no inconsistent regions</span>
+<span class="source-line-no">169</span><span id="line-169">    TEST_UTIL.waitFor(60000, 1000, () -&gt; {</span>
+<span class="source-line-no">170</span><span id="line-170">      hbckChore.choreForTesting();</span>
+<span class="source-line-no">171</span><span id="line-171">      HbckReport report = hbckChore.getLastReport();</span>
+<span class="source-line-no">172</span><span id="line-172">      return report.getInconsistentRegions().isEmpty() &amp;&amp; report.getOrphanRegionsOnFS().isEmpty()</span>
+<span class="source-line-no">173</span><span id="line-173">        &amp;&amp; report.getOrphanRegionsOnRS().isEmpty();</span>
+<span class="source-line-no">174</span><span id="line-174">    });</span>
+<span class="source-line-no">175</span><span id="line-175">  }</span>
+<span class="source-line-no">176</span><span id="line-176">}</span>
 
 
 
diff --git a/testdevapidocs/constant-values.html b/testdevapidocs/constant-values.html
index 9450e353dfe..7cf15e1c8b5 100644
--- a/testdevapidocs/constant-values.html
+++ b/testdevapidocs/constant-values.html
@@ -10654,6 +10654,17 @@ loadScripts(document, 'script');</script>
 </div>
 </li>
 <li>
+<div class="caption"><span>org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Constant Field</div>
+<div class="table-header col-last">Value</div>
+<div class="col-first even-row-color"><code id="org.apache.hadoop.hbase.util.RSProcDispatcher.FAIL_FAST_LIMIT_KEY">static&nbsp;final&nbsp;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></code></div>
+<div class="col-second even-row-color"><code><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#FAIL_FAST_LIMIT_KEY">FAIL_FAST_LIMIT_KEY</a></code></div>
+<div class="col-last even-row-color"><code>"hbase.master.rs.remote.proc.fail.fast.limit"</code></div>
+</div>
+</li>
+<li>
 <div class="caption"><span>org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/TestBoundedPriorityBlockingQueue.html" title="class in org.apache.hadoop.hbase.util">TestBoundedPriorityBlockingQueue</a></span></div>
 <div class="summary-table three-column-summary">
 <div class="table-header col-first">Modifier and Type</div>
diff --git a/testdevapidocs/index-all.html b/testdevapidocs/index-all.html
index 5be01da18c5..5e01ac29607 100644
--- a/testdevapidocs/index-all.html
+++ b/testdevapidocs/index-all.html
@@ -2877,6 +2877,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/replication/TestReplicationWithWALExtendedAttributes.TestReplicationSinkRegionServerEndpoint.html#attachWALExtendedAttributesToMutation(org.apache.hadoop.hbase.client.Mutation,java.util.List)" class="member-name-link">attachWALExtendedAttributesToMutation(Mutation, List&lt;WALProtos.Attribute&gt;)</a> - Method in class org.apache.hadoop.hbase.replication.<a href="org/apache/hadoop/hbase/replication/TestReplicationWithWALExtendedAttributes.TestReplicat [...]
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#attempts" class="member-name-link">attempts</a> - Variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher.TestExecuteProceduresRemoteCall</a></dt>
+<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/client/TestConnectionAttributes.AttributesCoprocessor.html#%3Cinit%3E()" class="member-name-link">AttributesCoprocessor()</a> - Constructor for class org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/TestConnectionAttributes.AttributesCoprocessor.html" title="class in org.apache.hadoop.hbase.client">TestConnectionAttributes.AttributesCoprocessor</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/client/TestRequestAttributes.AttributesCoprocessor.html#%3Cinit%3E()" class="member-name-link">AttributesCoprocessor()</a> - Constructor for class org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/TestRequestAttributes.AttributesCoprocessor.html" title="class in org.apache.hadoop.hbase.client">TestRequestAttributes.AttributesCoprocessor</a></dt>
@@ -15768,6 +15770,10 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/master/replication/TestTransitPeerSyncReplicationStateProcedureBackoff.html#FAIL" class="member-name-link">FAIL</a> - Static variable in class org.apache.hadoop.hbase.master.replication.<a href="org/apache/hadoop/hbase/master/replication/TestTransitPeerSyncReplicationStateProcedureBackoff.html" title="class in org.apache.hadoop.hbase.master.replication">TestTransitPeerSyncReplicationStateProcedureBackoff</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#FAIL_FAST_LIMIT_KEY" class="member-name-link">FAIL_FAST_LIMIT_KEY</a> - Static variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
+<dd>
+<div class="block">Config key for the fail-fast retry limit, shared with the test so the two cannot drift.</div>
+</dd>
 <dt><a href="org/apache/hadoop/hbase/master/TestLoadProcedureError.html#FAIL_LOAD" class="member-name-link">FAIL_LOAD</a> - Static variable in class org.apache.hadoop.hbase.master.<a href="org/apache/hadoop/hbase/master/TestLoadProcedureError.html" title="class in org.apache.hadoop.hbase.master">TestLoadProcedureError</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/client/AbstractTestAsyncTableRegionReplicasRead.html#FAIL_PRIMARY_GET" class="member-name-link">FAIL_PRIMARY_GET</a> - Static variable in class org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/AbstractTestAsyncTableRegionReplicasRead.html" title="class in org.apache.hadoop.hbase.client">AbstractTestAsyncTableRegionReplicasRead</a></dt>
@@ -15796,6 +15802,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/replication/ReplicationEndpointTestBase.InterClusterReplicationEndpointForTest.html#failedOnce" class="member-name-link">failedOnce</a> - Static variable in class org.apache.hadoop.hbase.replication.<a href="org/apache/hadoop/hbase/replication/ReplicationEndpointTestBase.InterClusterReplicationEndpointForTest.html" title="class in org.apache.hadoop.hbase.replication">ReplicationEndpointTestBase.InterClusterReplicationEndpointForTest</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#failFastLimit" class="member-name-link">failFastLimit</a> - Variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
+<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/replication/regionserver/TestReplicationSource.BadReplicationEndpoint.html#failing" class="member-name-link">failing</a> - Static variable in class org.apache.hadoop.hbase.replication.regionserver.<a href="org/apache/hadoop/hbase/replication/regionserver/TestReplicationSource.BadReplicationEndpoint.html" title="class in org.apache.hadoop.hbase.replication.regionserver">TestReplicationSource.BadReplicationEndpoint</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/util/TestEncryptionTest.FailingCipherProvider.html#%3Cinit%3E()" class="member-name-link">FailingCipherProvider()</a> - Constructor for class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/TestEncryptionTest.FailingCipherProvider.html" title="class in org.apache.hadoop.hbase.util">TestEncryptionTest.FailingCipherProvider</a></dt>
@@ -25013,8 +25021,6 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/HBaseTestingUtil.SeenRowTracker.html#i(byte)" class="member-name-link">i(byte)</a> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HBaseTestingUtil.SeenRowTracker.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtil.SeenRowTracker</a></dt>
 <dd>&nbsp;</dd>
-<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#I" class="member-name-link">I</a> - Static variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
-<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/util/TestOrderedBytes.html#I_LENGTHS" class="member-name-link">I_LENGTHS</a> - Static variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/TestOrderedBytes.html" title="class in org.apache.hadoop.hbase.util">TestOrderedBytes</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/util/TestOrderedBytes.html#I_VALS" class="member-name-link">I_VALS</a> - Static variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/TestOrderedBytes.html" title="class in org.apache.hadoop.hbase.util">TestOrderedBytes</a></dt>
@@ -25730,6 +25736,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/client/FromClientSideScanExcpetionTestBase.html#inject()" class="member-name-link">inject()</a> - Static method in class org.apache.hadoop.hbase.client.<a href="org/apache/hadoop/hbase/client/FromClientSideScanExcpetionTestBase.html" title="class in org.apache.hadoop.hbase.client">FromClientSideScanExcpetionTestBase</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#INJECT" class="member-name-link">INJECT</a> - Static variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
+<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/master/procedure/MasterProcedureTestingUtility.InjectAbortOnLoadListener.html#%3Cinit%3E(org.apache.hadoop.hbase.procedure2.ProcedureExecutor)" class="member-name-link">InjectAbortOnLoadListener(ProcedureExecutor&lt;MasterProcedureEnv&gt;)</a> - Constructor for class org.apache.hadoop.hbase.master.procedure.<a href="org/apache/hadoop/hbase/master/procedure/MasterProcedureTestingUtility.InjectAbortOnLoadListener.html" title="class in org.apache.hadoop. [...]
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/master/assignment/TestTRSPPersistUninitializedSubProc.TRSPForTest.html#injected" class="member-name-link">injected</a> - Variable in class org.apache.hadoop.hbase.master.assignment.<a href="org/apache/hadoop/hbase/master/assignment/TestTRSPPersistUninitializedSubProc.TRSPForTest.html" title="class in org.apache.hadoop.hbase.master.assignment">TestTRSPPersistUninitializedSubProc.TRSPForTest</a></dt>
@@ -25747,6 +25755,13 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/replication/TestReplicationEmptyWALRecovery.html#injectEmptyWAL(int,java.util.List)" class="member-name-link">injectEmptyWAL(int, List&lt;Path&gt;)</a> - Method in class org.apache.hadoop.hbase.replication.<a href="org/apache/hadoop/hbase/replication/TestReplicationEmptyWALRecovery.html" title="class in org.apache.hadoop.hbase.replication">TestReplicationEmptyWALRecovery</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#injectErrors" class="member-name-link">injectErrors</a> - Variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher.TestExecuteProceduresRemoteCall</a></dt>
+<dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#injectErrorsForNextRequests(org.apache.hadoop.hbase.TableName,int)" class="member-name-link">injectErrorsForNextRequests(TableName, int)</a> - Static method in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
+<dd>
+<div class="block">Fails the next <code>n</code> open/close-region requests for <code>table</code> with connection errors
+ until the fail-fast retry limit is exhausted, so the master schedules an SCP.</div>
+</dd>
 <dt><a href="org/apache/hadoop/hbase/regionserver/TestFSErrorsExposed.FaultyInputStream.html#injectFault()" class="member-name-link">injectFault()</a> - Method in class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/TestFSErrorsExposed.FaultyInputStream.html" title="class in org.apache.hadoop.hbase.regionserver">TestFSErrorsExposed.FaultyInputStream</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/regionserver/TestHStore.FaultyOutputStream.html#injectFault()" class="member-name-link">injectFault()</a> - Method in class org.apache.hadoop.hbase.regionserver.<a href="org/apache/hadoop/hbase/regionserver/TestHStore.FaultyOutputStream.html" title="class in org.apache.hadoop.hbase.regionserver">TestHStore.FaultyOutputStream</a></dt>
@@ -51535,6 +51550,10 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt><a href="org/apache/hadoop/hbase/SingleProcessHBaseCluster.html#stopDataNode(org.apache.hadoop.hbase.ServerName)" class="member-name-link">stopDataNode(ServerName)</a> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/SingleProcessHBaseCluster.html" title="class in org.apache.hadoop.hbase">SingleProcessHBaseCluster</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#stopInjecting()" class="member-name-link">stopInjecting()</a> - Static method in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
+<dd>
+<div class="block">Stops error injection.</div>
+</dd>
 <dt><a href="org/apache/hadoop/hbase/DistributedHBaseCluster.html#stopJournalNode(org.apache.hadoop.hbase.ServerName)" class="member-name-link">stopJournalNode(ServerName)</a> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/DistributedHBaseCluster.html" title="class in org.apache.hadoop.hbase">DistributedHBaseCluster</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/HBaseClusterInterface.html#stopJournalNode(org.apache.hadoop.hbase.ServerName)" class="member-name-link">stopJournalNode(ServerName)</a> - Method in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HBaseClusterInterface.html" title="class in org.apache.hadoop.hbase">HBaseClusterInterface</a></dt>
@@ -53798,12 +53817,18 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/AcidGuaranteesTestTool.AtomicityWriter.html#targetRows" class="member-name-link">targetRows</a> - Variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/AcidGuaranteesTestTool.AtomicityWriter.html" title="class in org.apache.hadoop.hbase">AcidGuaranteesTestTool.AtomicityWriter</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#targetsInjectionTable(org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresRequest)" class="member-name-link">targetsInjectionTable(AdminProtos.ExecuteProceduresRequest)</a> - Static method in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
+<dd>
+<div class="block">True if the request opens or closes a region of the injection target table.</div>
+</dd>
 <dt><a href="org/apache/hadoop/hbase/backup/TestBackupRestoreOnEmptyEnvironment.html#targetTable" class="member-name-link">targetTable</a> - Variable in class org.apache.hadoop.hbase.backup.<a href="org/apache/hadoop/hbase/backup/TestBackupRestoreOnEmptyEnvironment.html" title="class in org.apache.hadoop.hbase.backup">TestBackupRestoreOnEmptyEnvironment</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/backup/TestBackupRestoreWithModifications.html#targetTable" class="member-name-link">targetTable</a> - Variable in class org.apache.hadoop.hbase.backup.<a href="org/apache/hadoop/hbase/backup/TestBackupRestoreWithModifications.html" title="class in org.apache.hadoop.hbase.backup">TestBackupRestoreWithModifications</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/backup/TestIncrementalBackupMergeWithBulkLoad.html#targetTable" class="member-name-link">targetTable</a> - Variable in class org.apache.hadoop.hbase.backup.<a href="org/apache/hadoop/hbase/backup/TestIncrementalBackupMergeWithBulkLoad.html" title="class in org.apache.hadoop.hbase.backup">TestIncrementalBackupMergeWithBulkLoad</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#targetTable" class="member-name-link">targetTable</a> - Static variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
+<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/procedure/TestProcedureCoordinator.html#task" class="member-name-link">task</a> - Variable in class org.apache.hadoop.hbase.procedure.<a href="org/apache/hadoop/hbase/procedure/TestProcedureCoordinator.html" title="class in org.apache.hadoop.hbase.procedure">TestProcedureCoordinator</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/ChaosZKClient.html#TASK_BOOLEAN_FALSE" class="member-name-link">TASK_BOOLEAN_FALSE</a> - Static variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/ChaosZKClient.html" title="class in org.apache.hadoop.hbase">ChaosZKClient</a></dt>
@@ -55006,6 +55031,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/util/TestMiniClusterLoadSequential.html#tearDown()" class="member-name-link">tearDown()</a> - Method in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/TestMiniClusterLoadSequential.html" title="class in org.apache.hadoop.hbase.util">TestMiniClusterLoadSequential</a></dt>
 <dd>&nbsp;</dd>
+<dt><a href="org/apache/hadoop/hbase/util/TestProcDispatcher.html#tearDown()" class="member-name-link">tearDown()</a> - Method in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/TestProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">TestProcDispatcher</a></dt>
+<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/util/TestRegionMover1.html#tearDown()" class="member-name-link">tearDown()</a> - Method in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/TestRegionMover1.html" title="class in org.apache.hadoop.hbase.util">TestRegionMover1</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/util/TestRegionMover2.html#tearDown()" class="member-name-link">tearDown()</a> - Method in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/TestRegionMover2.html" title="class in org.apache.hadoop.hbase.util">TestRegionMover2</a></dt>
@@ -93070,6 +93097,8 @@ the order they are declared.</div>
 <div class="block">Tag a test as region tests which takes longer than 5 minutes to run on public build
  infrastructure.</div>
 </dd>
+<dt><a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html#VICTIMS_REMAINING" class="member-name-link">VICTIMS_REMAINING</a> - Static variable in class org.apache.hadoop.hbase.util.<a href="org/apache/hadoop/hbase/util/RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dt>
+<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/IntegrationTestIngestWithVisibilityLabels.html#VISIBILITY_EXPS" class="member-name-link">VISIBILITY_EXPS</a> - Static variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/IntegrationTestIngestWithVisibilityLabels.html" title="class in org.apache.hadoop.hbase">IntegrationTestIngestWithVisibilityLabels</a></dt>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/test/IntegrationTestWithCellVisibilityLoadAndVerify.html#VISIBILITY_EXPS" class="member-name-link">VISIBILITY_EXPS</a> - Static variable in class org.apache.hadoop.hbase.test.<a href="org/apache/hadoop/hbase/test/IntegrationTestWithCellVisibilityLoadAndVerify.html" title="class in org.apache.hadoop.hbase.test">IntegrationTestWithCellVisibilityLoadAndVerify</a></dt>
diff --git a/testdevapidocs/member-search-index.js b/testdevapidocs/member-search-index.js
index 860921bc043..436682cd229 100644
--- a/testdevapidocs/member-search-index.js
+++ b/testdevapidocs/member-search-index.js
@@ -1 +1 @@
-memberSearchIndex = [{"p":"org.apache.hadoop.hbase.master.janitor","c":"TestMetaFixerNoCluster","l":"_ARI"},{"p":"org.apache.hadoop.hbase.io","c":"TestHalfStoreFileReader","l":"_b(String)","u":"_b(java.lang.String)"},{"p":"org.apache.hadoop.hbase.master.janitor","c":"TestMetaFixerNoCluster","l":"_BRI"},{"p":"org.apache.hadoop.hbase.backup","c":"TestSystemTableSnapshot","l":"_testBackupRestoreSystemTable()"},{"p":"org.apache.hadoop.hbase.regionserver","c":"TestBlocksScanned","l":"_testBlo [...]
\ No newline at end of file
+memberSearchIndex = [{"p":"org.apache.hadoop.hbase.master.janitor","c":"TestMetaFixerNoCluster","l":"_ARI"},{"p":"org.apache.hadoop.hbase.io","c":"TestHalfStoreFileReader","l":"_b(String)","u":"_b(java.lang.String)"},{"p":"org.apache.hadoop.hbase.master.janitor","c":"TestMetaFixerNoCluster","l":"_BRI"},{"p":"org.apache.hadoop.hbase.backup","c":"TestSystemTableSnapshot","l":"_testBackupRestoreSystemTable()"},{"p":"org.apache.hadoop.hbase.regionserver","c":"TestBlocksScanned","l":"_testBlo [...]
\ No newline at end of file
diff --git a/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html b/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html
index 65f3c8abe89..d9623540754 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html
@@ -85,7 +85,7 @@ loadScripts(document, 'script');</script>
 <dd><a href="RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dd>
 </dl>
 <hr>
-<div class="type-signature"><span class="modifiers">private class </span><span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-103">RSProcDispatcher.DeadRSRemoteCall</a></span>
+<div class="type-signature"><span class="modifiers">private class </span><span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-172">RSProcDispatcher.DeadRSRemoteCall</a></span>
 <span class="extends-implements">extends <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a></span></div>
 </section>
 <section class="summary">
@@ -138,7 +138,7 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="&lt;init&gt;(org.apache.hadoop.hbase.ServerName,java.util.Set)">
 <h3>DeadRSRemoteCall</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html#line-105">DeadRSRemoteCall</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html#line-174">DeadRSRemoteCall</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher.RemoteProcedure&gt;&nbsp;remoteProcedures)</span></div>
 </section>
 </li>
@@ -153,7 +153,7 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="run()">
 <h3>run</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html#line-109">run</a></span>()</div>
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html#line-178">run</a></span>()</div>
 <dl class="notes">
 <dt>Specified by:</dt>
 <dd><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Runnable.html#run()" title="class or interface in java.lang" class="external-link">run</a></code>&nbsp;in interface&nbsp;<code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Runnable.html" title="class or interface in java.lang" class="external-link">Runnable</a></code></dd>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html b/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html
index 03c5421c1eb..5e3422d58e4 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html
@@ -46,13 +46,13 @@ loadScripts(document, 'script');</script>
 <ul class="sub-nav-list">
 <li>Summary:&nbsp;</li>
 <li>Nested&nbsp;|&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
+<li><a href="#field-summary">Field</a>&nbsp;|&nbsp;</li>
 <li><a href="#constructor-summary">Constr</a>&nbsp;|&nbsp;</li>
 <li><a href="#method-summary">Method</a></li>
 </ul>
 <ul class="sub-nav-list">
 <li>Detail:&nbsp;</li>
-<li>Field&nbsp;|&nbsp;</li>
+<li><a href="#field-detail">Field</a>&nbsp;|&nbsp;</li>
 <li><a href="#constructor-detail">Constr</a>&nbsp;|&nbsp;</li>
 <li><a href="#method-detail">Method</a></li>
 </ul>
@@ -85,11 +85,29 @@ loadScripts(document, 'script');</script>
 <dd><a href="RSProcDispatcher.html" title="class in org.apache.hadoop.hbase.util">RSProcDispatcher</a></dd>
 </dl>
 <hr>
-<div class="type-signature"><span class="modifiers">class </span><span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-69">RSProcDispatcher.TestExecuteProceduresRemoteCall</a></span>
+<div class="type-signature"><span class="modifiers">class </span><span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-133">RSProcDispatcher.TestExecuteProceduresRemoteCall</a></span>
 <span class="extends-implements">extends <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a></span></div>
 </section>
 <section class="summary">
 <ul class="summary-list">
+<!-- =========== FIELD SUMMARY =========== -->
+<li>
+<section class="field-summary" id="field-summary">
+<h2>Field Summary</h2>
+<div class="caption"><span>Fields</span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Field</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>private int</code></div>
+<div class="col-second even-row-color"><code><a href="#attempts" class="member-name-link">attempts</a></code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>private <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a></code></div>
+<div class="col-second odd-row-color"><code><a href="#injectErrors" class="member-name-link">injectErrors</a></code></div>
+<div class="col-last odd-row-color">&nbsp;</div>
+</div>
+</section>
+</li>
 <!-- ======== CONSTRUCTOR SUMMARY ======== -->
 <li>
 <section class="constructor-summary" id="constructor-summary">
@@ -134,6 +152,26 @@ loadScripts(document, 'script');</script>
 </section>
 <section class="details">
 <ul class="details-list">
+<!-- ============ FIELD DETAIL =========== -->
+<li>
+<section class="field-details" id="field-detail">
+<h2>Field Details</h2>
+<ul class="member-list">
+<li>
+<section class="detail" id="attempts">
+<h3>attempts</h3>
+<div class="member-signature"><span class="modifiers">private</span>&nbsp;<span class="return-type">int</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#line-138">attempts</a></span></div>
+</section>
+</li>
+<li>
+<section class="detail" id="injectErrors">
+<h3>injectErrors</h3>
+<div class="member-signature"><span class="modifiers">private</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html" title="class or interface in java.lang" class="external-link">Boolean</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#line-139">injectErrors</a></span></div>
+</section>
+</li>
+</ul>
+</section>
+</li>
 <!-- ========= CONSTRUCTOR DETAIL ======== -->
 <li>
 <section class="constructor-details" id="constructor-detail">
@@ -142,7 +180,7 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="&lt;init&gt;(org.apache.hadoop.hbase.ServerName,java.util.Set)">
 <h3>TestExecuteProceduresRemoteCall</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#line-71">TestExecuteProceduresRemoteCall</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#line-141">TestExecuteProceduresRemoteCall</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher.RemoteProcedure&gt;&nbsp;remoteProcedures)</span></div>
 </section>
 </li>
@@ -157,7 +195,7 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="sendRequest(org.apache.hadoop.hbase.ServerName,org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresRequest)">
 <h3>sendRequest</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresResponse</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#line-76">sendRequest</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresResponse</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#line-146">sendRequest</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
  org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresRequest&nbsp;request)</span>
                                                                                                     throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a></span></div>
 <dl class="notes">
@@ -169,7 +207,7 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="getRsAdmin()">
 <h3>getRsAdmin</h3>
-<div class="member-signature"><span class="modifiers">private</span>&nbsp;<span class="return-type">org.apache.hadoop.hbase.client.AsyncRegionServerAdmin</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#line-98">getRsAdmin</a></span>()</div>
+<div class="member-signature"><span class="modifiers">private</span>&nbsp;<span class="return-type">org.apache.hadoop.hbase.client.AsyncRegionServerAdmin</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html#line-167">getRsAdmin</a></span>()</div>
 </section>
 </li>
 </ul>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.html b/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.html
index fd898abe03c..9f14ae013a4 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/util/RSProcDispatcher.html
@@ -85,7 +85,7 @@ loadScripts(document, 'script');</script>
 <dd><code>org.apache.hadoop.hbase.master.ServerListener</code></dd>
 </dl>
 <hr>
-<div class="type-signature"><span class="modifiers">public class </span><span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-41">RSProcDispatcher</a></span>
+<div class="type-signature"><span class="modifiers">public class </span><span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-46">RSProcDispatcher</a></span>
 <span class="extends-implements">extends org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher</span></div>
 <div class="block">Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</div>
 </section>
@@ -130,12 +130,26 @@ loadScripts(document, 'script');</script>
 <div class="col-first odd-row-color"><code>private static final <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a>&gt;</code></div>
 <div class="col-second odd-row-color"><code><a href="#ERRORS" class="member-name-link">ERRORS</a></code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><code>private static final <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/AtomicInteger.html" title="class or interface in java.util.concurrent.atomic" class="external-link">AtomicInteger</a></code></div>
-<div class="col-second even-row-color"><code><a href="#I" class="member-name-link">I</a></code></div>
+<div class="col-first even-row-color"><code>(package private) static final <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></code></div>
+<div class="col-second even-row-color"><code><a href="#FAIL_FAST_LIMIT_KEY" class="member-name-link">FAIL_FAST_LIMIT_KEY</a></code></div>
+<div class="col-last even-row-color">
+<div class="block">Config key for the fail-fast retry limit, shared with the test so the two cannot drift.</div>
+</div>
+<div class="col-first odd-row-color"><code>private final int</code></div>
+<div class="col-second odd-row-color"><code><a href="#failFastLimit" class="member-name-link">failFastLimit</a></code></div>
+<div class="col-last odd-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><code>private static final <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/AtomicBoolean.html" title="class or interface in java.util.concurrent.atomic" class="external-link">AtomicBoolean</a></code></div>
+<div class="col-second even-row-color"><code><a href="#INJECT" class="member-name-link">INJECT</a></code></div>
 <div class="col-last even-row-color">&nbsp;</div>
 <div class="col-first odd-row-color"><code>private static final org.slf4j.Logger</code></div>
 <div class="col-second odd-row-color"><code><a href="#LOG" class="member-name-link">LOG</a></code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><code>private static org.apache.hadoop.hbase.TableName</code></div>
+<div class="col-second even-row-color"><code><a href="#targetTable" class="member-name-link">targetTable</a></code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>private static final <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/AtomicInteger.html" title="class or interface in java.util.concurrent.atomic" class="external-link">AtomicInteger</a></code></div>
+<div class="col-second odd-row-color"><code><a href="#VICTIMS_REMAINING" class="member-name-link">VICTIMS_REMAINING</a></code></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <div class="inherited-list">
 <h3 id="fields-inherited-from-class-org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher">Fields inherited from class&nbsp;org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher</h3>
@@ -163,16 +177,33 @@ loadScripts(document, 'script');</script>
 <section class="method-summary" id="method-summary">
 <h2>Method Summary</h2>
 <div id="method-summary-table">
-<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="method-summary-table-tab0" role="tab" aria-selected="true" aria-controls="method-summary-table.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table', 3)" class="active-table-tab">All Methods</button><button id="method-summary-table-tab2" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab( [...]
+<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="method-summary-table-tab0" role="tab" aria-selected="true" aria-controls="method-summary-table.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table', 3)" class="active-table-tab">All Methods</button><button id="method-summary-table-tab1" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab( [...]
 <div id="method-summary-table.tabpanel" role="tabpanel">
 <div class="summary-table three-column-summary" aria-labelledby="method-summary-table-tab0">
 <div class="table-header col-first">Modifier and Type</div>
 <div class="table-header col-second">Method</div>
 <div class="table-header col-last">Description</div>
-<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>protected void</code></div>
-<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#remoteDispatch(org.apache.hadoop.hbase.ServerName,java.util.Set)" class="member-name-link">remoteDispatch</a><wbr>(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
+<div class="col-first even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code>(package private) static void</code></div>
+<div class="col-second even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code><a href="#injectErrorsForNextRequests(org.apache.hadoop.hbase.TableName,int)" class="member-name-link">injectErrorsForNextRequests</a><wbr>(org.apache.hadoop.hbase.TableName&nbsp;table,
+ int&nbsp;n)</code></div>
+<div class="col-last even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4">
+<div class="block">Fails the next <code>n</code> open/close-region requests for <code>table</code> with connection errors
+ until the fail-fast retry limit is exhausted, so the master schedules an SCP.</div>
+</div>
+<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>protected void</code></div>
+<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#remoteDispatch(org.apache.hadoop.hbase.ServerName,java.util.Set)" class="member-name-link">remoteDispatch</a><wbr>(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher.RemoteProcedure&gt;&nbsp;remoteProcedures)</code></div>
-<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div>
+<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div>
+<div class="col-first even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code>(package private) static void</code></div>
+<div class="col-second even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code><a href="#stopInjecting()" class="member-name-link">stopInjecting</a>()</code></div>
+<div class="col-last even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4">
+<div class="block">Stops error injection.</div>
+</div>
+<div class="col-first odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code>private static boolean</code></div>
+<div class="col-second odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code><a href="#targetsInjectionTable(org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresRequest)" class="member-name-link">targetsInjectionTable</a><wbr>(org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresRequest&nbsp;request)</code></div>
+<div class="col-last odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4">
+<div class="block">True if the request opens or closes a region of the injection target table.</div>
+</div>
 </div>
 </div>
 </div>
@@ -202,25 +233,58 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="LOG">
 <h3>LOG</h3>
-<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type">org.slf4j.Logger</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-43">LOG</a></span></div>
+<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type">org.slf4j.Logger</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-48">LOG</a></span></div>
 </section>
 </li>
 <li>
-<section class="detail" id="I">
-<h3>I</h3>
-<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/AtomicInteger.html" title="class or interface in java.util.concurrent.atomic" class="external-link">AtomicInteger</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-45">I</a></span></div>
+<section class="detail" id="FAIL_FAST_LIMIT_KEY">
+<h3>FAIL_FAST_LIMIT_KEY</h3>
+<div class="member-signature"><span class="modifiers">static final</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-51">FAIL_FAST_LIMIT_KEY</a></span></div>
+<div class="block">Config key for the fail-fast retry limit, shared with the test so the two cannot drift.</div>
+<dl class="notes">
+<dt>See Also:</dt>
+<dd>
+<ul class="see-list">
+<li><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RSProcDispatcher.FAIL_FAST_LIMIT_KEY">Constant Field Values</a></li>
+</ul>
+</dd>
+</dl>
 </section>
 </li>
 <li>
 <section class="detail" id="ERRORS">
 <h3>ERRORS</h3>
-<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a>&gt;</span>&nbsp;<span class="element-name" [...]
+<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html" title="class or interface in java.util" class="external-link">List</a>&lt;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html" title="class or interface in java.io" class="external-link">IOException</a>&gt;</span>&nbsp;<span class="element-name" [...]
 </section>
 </li>
 <li>
 <section class="detail" id="ERROR_IDX">
 <h3>ERROR_IDX</h3>
-<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/AtomicInteger.html" title="class or interface in java.util.concurrent.atomic" class="external-link">AtomicInteger</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-52">ERROR_IDX</a></span></div>
+<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/AtomicInteger.html" title="class or interface in java.util.concurrent.atomic" class="external-link">AtomicInteger</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-58">ERROR_IDX</a></span></div>
+</section>
+</li>
+<li>
+<section class="detail" id="INJECT">
+<h3>INJECT</h3>
+<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/AtomicBoolean.html" title="class or interface in java.util.concurrent.atomic" class="external-link">AtomicBoolean</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-63">INJECT</a></span></div>
+</section>
+</li>
+<li>
+<section class="detail" id="VICTIMS_REMAINING">
+<h3>VICTIMS_REMAINING</h3>
+<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/atomic/AtomicInteger.html" title="class or interface in java.util.concurrent.atomic" class="external-link">AtomicInteger</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-64">VICTIMS_REMAINING</a></span></div>
+</section>
+</li>
+<li>
+<section class="detail" id="targetTable">
+<h3>targetTable</h3>
+<div class="member-signature"><span class="modifiers">private static volatile</span>&nbsp;<span class="return-type">org.apache.hadoop.hbase.TableName</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-65">targetTable</a></span></div>
+</section>
+</li>
+<li>
+<section class="detail" id="failFastLimit">
+<h3>failFastLimit</h3>
+<div class="member-signature"><span class="modifiers">private final</span>&nbsp;<span class="return-type">int</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-68">failFastLimit</a></span></div>
 </section>
 </li>
 </ul>
@@ -234,7 +298,7 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="&lt;init&gt;(org.apache.hadoop.hbase.master.MasterServices)">
 <h3>RSProcDispatcher</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-54">RSProcDispatcher</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.master.MasterServices&nbsp;master)</span></div>
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-89">RSProcDispatcher</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.master.MasterServices&nbsp;master)</span></div>
 </section>
 </li>
 </ul>
@@ -246,9 +310,26 @@ loadScripts(document, 'script');</script>
 <h2>Method Details</h2>
 <ul class="member-list">
 <li>
+<section class="detail" id="injectErrorsForNextRequests(org.apache.hadoop.hbase.TableName,int)">
+<h3>injectErrorsForNextRequests</h3>
+<div class="member-signature"><span class="modifiers">static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-75">injectErrorsForNextRequests</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.TableName&nbsp;table,
+ int&nbsp;n)</span></div>
+<div class="block">Fails the next <code>n</code> open/close-region requests for <code>table</code> with connection errors
+ until the fail-fast retry limit is exhausted, so the master schedules an SCP. Call right before
+ the operations under test.</div>
+</section>
+</li>
+<li>
+<section class="detail" id="stopInjecting()">
+<h3>stopInjecting</h3>
+<div class="member-signature"><span class="modifiers">static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-83">stopInjecting</a></span>()</div>
+<div class="block">Stops error injection. Safe to call unconditionally, e.g. from test teardown.</div>
+</section>
+</li>
+<li>
 <section class="detail" id="remoteDispatch(org.apache.hadoop.hbase.ServerName,java.util.Set)">
 <h3>remoteDispatch</h3>
-<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-58">remoteDispatch</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
+<div class="member-signature"><span class="modifiers">protected</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-94">remoteDispatch</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.ServerName&nbsp;serverName,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html" title="class or interface in java.util" class="external-link">Set</a>&lt;org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher.RemoteProcedure&gt;&nbsp;remoteProcedures)</span></div>
 <dl class="notes">
 <dt>Overrides:</dt>
@@ -256,6 +337,14 @@ loadScripts(document, 'script');</script>
 </dl>
 </section>
 </li>
+<li>
+<section class="detail" id="targetsInjectionTable(org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresRequest)">
+<h3>targetsInjectionTable</h3>
+<div class="member-signature"><span class="modifiers">private static</span>&nbsp;<span class="return-type">boolean</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html#line-109">targetsInjectionTable</a></span><wbr><span class="parameters">(org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ExecuteProceduresRequest&nbsp;request)</span></div>
+<div class="block">True if the request opens or closes a region of the injection target table. Open requests carry
+ a full RegionInfo; close requests carry a REGION_NAME specifier the table is parsed from.</div>
+</section>
+</li>
 </ul>
 </section>
 </li>
diff --git a/testdevapidocs/org/apache/hadoop/hbase/util/TestProcDispatcher.html b/testdevapidocs/org/apache/hadoop/hbase/util/TestProcDispatcher.html
index 35af0a1533a..067e9cb1186 100644
--- a/testdevapidocs/org/apache/hadoop/hbase/util/TestProcDispatcher.html
+++ b/testdevapidocs/org/apache/hadoop/hbase/util/TestProcDispatcher.html
@@ -78,7 +78,7 @@ loadScripts(document, 'script');</script>
 <section class="class-description" id="class-description">
 <hr>
 <div class="type-signature"><span class="annotations">@Tag("org.apache.hadoop.hbase.testclassification.MiscTests") @Tag("org.apache.hadoop.hbase.testclassification.LargeTests")
-</span><span class="modifiers">public class </span><span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-58">TestProcDispatcher</a></span>
+</span><span class="modifiers">public class </span><span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-59">TestProcDispatcher</a></span>
 <span class="extends-implements">extends <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a></span></div>
 <div class="block">Testing custom RSProcedureDispatcher to ensure retry limit can be imposed on certain errors.</div>
 </section>
@@ -135,12 +135,15 @@ loadScripts(document, 'script');</script>
 <div class="col-first odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code>static void</code></div>
 <div class="col-second odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code><a href="#setUpBeforeClass()" class="member-name-link">setUpBeforeClass</a>()</code></div>
 <div class="col-last odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4">&nbsp;</div>
-<div class="col-first even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code>static void</code></div>
-<div class="col-second even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code><a href="#tearDownAfterClass()" class="member-name-link">tearDownAfterClass</a>()</code></div>
-<div class="col-last even-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4">&nbsp;</div>
-<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div>
-<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#testRetryLimitOnConnClosedErrors(org.junit.jupiter.api.TestInfo)" class="member-name-link">testRetryLimitOnConnClosedErrors</a><wbr>(org.junit.jupiter.api.TestInfo&nbsp;testInfo)</code></div>
-<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div>
+<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div>
+<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#tearDown()" class="member-name-link">tearDown</a>()</code></div>
+<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div>
+<div class="col-first odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code>static void</code></div>
+<div class="col-second odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4"><code><a href="#tearDownAfterClass()" class="member-name-link">tearDownAfterClass</a>()</code></div>
+<div class="col-last odd-row-color method-summary-table method-summary-table-tab1 method-summary-table-tab4">&nbsp;</div>
+<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div>
+<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#testRetryLimitOnConnClosedErrors(org.junit.jupiter.api.TestInfo)" class="member-name-link">testRetryLimitOnConnClosedErrors</a><wbr>(org.junit.jupiter.api.TestInfo&nbsp;testInfo)</code></div>
+<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div>
 </div>
 </div>
 </div>
@@ -161,19 +164,19 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="LOG">
 <h3>LOG</h3>
-<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type">org.slf4j.Logger</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-62">LOG</a></span></div>
+<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type">org.slf4j.Logger</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-63">LOG</a></span></div>
 </section>
 </li>
 <li>
 <section class="detail" id="TEST_UTIL">
 <h3>TEST_UTIL</h3>
-<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="../HBaseTestingUtil.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtil</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-64">TEST_UTIL</a></span></div>
+<div class="member-signature"><span class="modifiers">private static final</span>&nbsp;<span class="return-type"><a href="../HBaseTestingUtil.html" title="class in org.apache.hadoop.hbase">HBaseTestingUtil</a></span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-65">TEST_UTIL</a></span></div>
 </section>
 </li>
 <li>
 <section class="detail" id="rs0">
 <h3>rs0</h3>
-<div class="member-signature"><span class="modifiers">private static</span>&nbsp;<span class="return-type">org.apache.hadoop.hbase.ServerName</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-65">rs0</a></span></div>
+<div class="member-signature"><span class="modifiers">private static</span>&nbsp;<span class="return-type">org.apache.hadoop.hbase.ServerName</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-66">rs0</a></span></div>
 </section>
 </li>
 </ul>
@@ -187,7 +190,7 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="&lt;init&gt;()">
 <h3>TestProcDispatcher</h3>
-<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-60">TestProcDispatcher</a></span>()</div>
+<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-61">TestProcDispatcher</a></span>()</div>
 </section>
 </li>
 </ul>
@@ -202,7 +205,7 @@ loadScripts(document, 'script');</script>
 <section class="detail" id="setUpBeforeClass()">
 <h3>setUpBeforeClass</h3>
 <div class="member-signature"><span class="annotations">@BeforeAll
-</span><span class="modifiers">public static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-67">setUpBeforeClass</a></span>()
+</span><span class="modifiers">public static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-68">setUpBeforeClass</a></span>()
                              throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Exception.html" title="class or interface in java.lang" class="external-link">Exception</a></span></div>
 <dl class="notes">
 <dt>Throws:</dt>
@@ -214,7 +217,7 @@ loadScripts(document, 'script');</script>
 <section class="detail" id="tearDownAfterClass()">
 <h3>tearDownAfterClass</h3>
 <div class="member-signature"><span class="annotations">@AfterAll
-</span><span class="modifiers">public static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-78">tearDownAfterClass</a></span>()
+</span><span class="modifiers">public static</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-79">tearDownAfterClass</a></span>()
                                throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Exception.html" title="class or interface in java.lang" class="external-link">Exception</a></span></div>
 <dl class="notes">
 <dt>Throws:</dt>
@@ -226,7 +229,7 @@ loadScripts(document, 'script');</script>
 <section class="detail" id="setUp(org.junit.jupiter.api.TestInfo)">
 <h3>setUp</h3>
 <div class="member-signature"><span class="annotations">@BeforeEach
-</span><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-83">setUp</a></span><wbr><span class="parameters">(org.junit.jupiter.api.TestInfo&nbsp;testInfo)</span>
+</span><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-84">setUp</a></span><wbr><span class="parameters">(org.junit.jupiter.api.TestInfo&nbsp;testInfo)</span>
            throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Exception.html" title="class or interface in java.lang" class="external-link">Exception</a></span></div>
 <dl class="notes">
 <dt>Throws:</dt>
@@ -235,10 +238,17 @@ loadScripts(document, 'script');</script>
 </section>
 </li>
 <li>
+<section class="detail" id="tearDown()">
+<h3>tearDown</h3>
+<div class="member-signature"><span class="annotations">@AfterEach
+</span><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-94">tearDown</a></span>()</div>
+</section>
+</li>
+<li>
 <section class="detail" id="testRetryLimitOnConnClosedErrors(org.junit.jupiter.api.TestInfo)">
 <h3>testRetryLimitOnConnClosedErrors</h3>
 <div class="member-signature"><span class="annotations">@Test
-</span><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-93">testRetryLimitOnConnClosedErrors</a></span><wbr><span class="parameters">(org.junit.jupiter.api.TestInfo&nbsp;testInfo)</span>
+</span><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../../../src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html#line-99">testRetryLimitOnConnClosedErrors</a></span><wbr><span class="parameters">(org.junit.jupiter.api.TestInfo&nbsp;testInfo)</span>
                                       throws <span class="exceptions"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Exception.html" title="class or interface in java.lang" class="external-link">Exception</a></span></div>
 <dl class="notes">
 <dt>Throws:</dt>
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html
index 5baa2fe87d7..9b63bfdaa12 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.DeadRSRemoteCall.html
@@ -36,97 +36,165 @@
 <span class="source-line-no">023</span><span id="line-23">import java.util.Arrays;</span>
 <span class="source-line-no">024</span><span id="line-24">import java.util.List;</span>
 <span class="source-line-no">025</span><span id="line-25">import java.util.Set;</span>
-<span class="source-line-no">026</span><span id="line-26">import java.util.concurrent.atomic.AtomicInteger;</span>
-<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.ServerName;</span>
-<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;</span>
-<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;</span>
-<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.master.MasterServices;</span>
-<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;</span>
-<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;</span>
-<span class="source-line-no">033</span><span id="line-33">import org.slf4j.Logger;</span>
-<span class="source-line-no">034</span><span id="line-34">import org.slf4j.LoggerFactory;</span>
-<span class="source-line-no">035</span><span id="line-35"></span>
-<span class="source-line-no">036</span><span id="line-36">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;</span>
-<span class="source-line-no">037</span><span id="line-37"></span>
-<span class="source-line-no">038</span><span id="line-38">/**</span>
-<span class="source-line-no">039</span><span id="line-39"> * Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</span>
-<span class="source-line-no">040</span><span id="line-40"> */</span>
-<span class="source-line-no">041</span><span id="line-41">public class RSProcDispatcher extends RSProcedureDispatcher {</span>
+<span class="source-line-no">026</span><span id="line-26">import java.util.concurrent.atomic.AtomicBoolean;</span>
+<span class="source-line-no">027</span><span id="line-27">import java.util.concurrent.atomic.AtomicInteger;</span>
+<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.ServerName;</span>
+<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.TableName;</span>
+<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;</span>
+<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.client.RegionInfo;</span>
+<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;</span>
+<span class="source-line-no">033</span><span id="line-33">import org.apache.hadoop.hbase.master.MasterServices;</span>
+<span class="source-line-no">034</span><span id="line-34">import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;</span>
+<span class="source-line-no">035</span><span id="line-35">import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;</span>
+<span class="source-line-no">036</span><span id="line-36">import org.slf4j.Logger;</span>
+<span class="source-line-no">037</span><span id="line-37">import org.slf4j.LoggerFactory;</span>
+<span class="source-line-no">038</span><span id="line-38"></span>
+<span class="source-line-no">039</span><span id="line-39">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span>
+<span class="source-line-no">040</span><span id="line-40">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;</span>
+<span class="source-line-no">041</span><span id="line-41">import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;</span>
 <span class="source-line-no">042</span><span id="line-42"></span>
-<span class="source-line-no">043</span><span id="line-43">  private static final Logger LOG = LoggerFactory.getLogger(RSProcDispatcher.class);</span>
-<span class="source-line-no">044</span><span id="line-44"></span>
-<span class="source-line-no">045</span><span id="line-45">  private static final AtomicInteger I = new AtomicInteger();</span>
-<span class="source-line-no">046</span><span id="line-46"></span>
-<span class="source-line-no">047</span><span id="line-47">  private static final List&lt;IOException&gt; ERRORS =</span>
-<span class="source-line-no">048</span><span id="line-48">    Arrays.asList(new ConnectionClosedException("test connection closed error..."),</span>
-<span class="source-line-no">049</span><span id="line-49">      new UnknownHostException("test unknown host error..."),</span>
-<span class="source-line-no">050</span><span id="line-50">      new ConnectException("test connect error..."));</span>
-<span class="source-line-no">051</span><span id="line-51"></span>
-<span class="source-line-no">052</span><span id="line-52">  private static final AtomicInteger ERROR_IDX = new AtomicInteger();</span>
-<span class="source-line-no">053</span><span id="line-53"></span>
-<span class="source-line-no">054</span><span id="line-54">  public RSProcDispatcher(MasterServices master) {</span>
-<span class="source-line-no">055</span><span id="line-55">    super(master);</span>
-<span class="source-line-no">056</span><span id="line-56">  }</span>
+<span class="source-line-no">043</span><span id="line-43">/**</span>
+<span class="source-line-no">044</span><span id="line-44"> * Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</span>
+<span class="source-line-no">045</span><span id="line-45"> */</span>
+<span class="source-line-no">046</span><span id="line-46">public class RSProcDispatcher extends RSProcedureDispatcher {</span>
+<span class="source-line-no">047</span><span id="line-47"></span>
+<span class="source-line-no">048</span><span id="line-48">  private static final Logger LOG = LoggerFactory.getLogger(RSProcDispatcher.class);</span>
+<span class="source-line-no">049</span><span id="line-49"></span>
+<span class="source-line-no">050</span><span id="line-50">  /** Config key for the fail-fast retry limit, shared with the test so the two cannot drift. */</span>
+<span class="source-line-no">051</span><span id="line-51">  static final String FAIL_FAST_LIMIT_KEY = "hbase.master.rs.remote.proc.fail.fast.limit";</span>
+<span class="source-line-no">052</span><span id="line-52"></span>
+<span class="source-line-no">053</span><span id="line-53">  private static final List&lt;IOException&gt; ERRORS =</span>
+<span class="source-line-no">054</span><span id="line-54">    Arrays.asList(new ConnectionClosedException("test connection closed error..."),</span>
+<span class="source-line-no">055</span><span id="line-55">      new UnknownHostException("test unknown host error..."),</span>
+<span class="source-line-no">056</span><span id="line-56">      new ConnectException("test connect error..."));</span>
 <span class="source-line-no">057</span><span id="line-57"></span>
-<span class="source-line-no">058</span><span id="line-58">  @Override</span>
-<span class="source-line-no">059</span><span id="line-59">  protected void remoteDispatch(final ServerName serverName,</span>
-<span class="source-line-no">060</span><span id="line-60">    final Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">061</span><span id="line-61">    if (!master.getServerManager().isServerOnline(serverName)) {</span>
-<span class="source-line-no">062</span><span id="line-62">      // fail fast</span>
-<span class="source-line-no">063</span><span id="line-63">      submitTask(new DeadRSRemoteCall(serverName, remoteProcedures));</span>
-<span class="source-line-no">064</span><span id="line-64">    } else {</span>
-<span class="source-line-no">065</span><span id="line-65">      submitTask(new TestExecuteProceduresRemoteCall(serverName, remoteProcedures));</span>
-<span class="source-line-no">066</span><span id="line-66">    }</span>
-<span class="source-line-no">067</span><span id="line-67">  }</span>
-<span class="source-line-no">068</span><span id="line-68"></span>
-<span class="source-line-no">069</span><span id="line-69">  class TestExecuteProceduresRemoteCall extends ExecuteProceduresRemoteCall {</span>
-<span class="source-line-no">070</span><span id="line-70"></span>
-<span class="source-line-no">071</span><span id="line-71">    public TestExecuteProceduresRemoteCall(ServerName serverName,</span>
-<span class="source-line-no">072</span><span id="line-72">      Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">073</span><span id="line-73">      super(serverName, remoteProcedures);</span>
-<span class="source-line-no">074</span><span id="line-74">    }</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76">    @Override</span>
-<span class="source-line-no">077</span><span id="line-77">    public AdminProtos.ExecuteProceduresResponse sendRequest(final ServerName serverName,</span>
-<span class="source-line-no">078</span><span id="line-78">      final AdminProtos.ExecuteProceduresRequest request) throws IOException {</span>
-<span class="source-line-no">079</span><span id="line-79">      int j = I.addAndGet(1);</span>
-<span class="source-line-no">080</span><span id="line-80">      LOG.info("sendRequest() req: {} , j: {}", request, j);</span>
-<span class="source-line-no">081</span><span id="line-81">      if (j == 12 || j == 22) {</span>
-<span class="source-line-no">082</span><span id="line-82">        // Execute the remote close and open region requests in the last (5th) retry before</span>
-<span class="source-line-no">083</span><span id="line-83">        // throwing ConnectionClosedException. This is to ensure even if the region open/close</span>
-<span class="source-line-no">084</span><span id="line-84">        // is successfully completed by regionserver, master still schedules SCP because</span>
-<span class="source-line-no">085</span><span id="line-85">        // sendRequest() throws error which has retry-limit exhausted.</span>
-<span class="source-line-no">086</span><span id="line-86">        FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
-<span class="source-line-no">087</span><span id="line-87">      }</span>
-<span class="source-line-no">088</span><span id="line-88">      // For one of the close region requests and one of the open region requests,</span>
-<span class="source-line-no">089</span><span id="line-89">      // throw ConnectionClosedException until retry limit is exhausted and master</span>
-<span class="source-line-no">090</span><span id="line-90">      // schedules recoveries for the server.</span>
-<span class="source-line-no">091</span><span id="line-91">      // We will have ABNORMALLY_CLOSED regions, and they are expected to recover on their own.</span>
-<span class="source-line-no">092</span><span id="line-92">      if (j &gt;= 8 &amp;&amp; j &lt;= 13 || j &gt;= 18 &amp;&amp; j &lt;= 23) {</span>
-<span class="source-line-no">093</span><span id="line-93">        throw ERRORS.get(ERROR_IDX.getAndIncrement() % ERRORS.size());</span>
-<span class="source-line-no">094</span><span id="line-94">      }</span>
-<span class="source-line-no">095</span><span id="line-95">      return FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
-<span class="source-line-no">096</span><span id="line-96">    }</span>
-<span class="source-line-no">097</span><span id="line-97"></span>
-<span class="source-line-no">098</span><span id="line-98">    private AsyncRegionServerAdmin getRsAdmin() {</span>
-<span class="source-line-no">099</span><span id="line-99">      return master.getAsyncClusterConnection().getRegionServerAdmin(getServerName());</span>
-<span class="source-line-no">100</span><span id="line-100">    }</span>
-<span class="source-line-no">101</span><span id="line-101">  }</span>
-<span class="source-line-no">102</span><span id="line-102"></span>
-<span class="source-line-no">103</span><span id="line-103">  private class DeadRSRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">058</span><span id="line-58">  private static final AtomicInteger ERROR_IDX = new AtomicInteger();</span>
+<span class="source-line-no">059</span><span id="line-59"></span>
+<span class="source-line-no">060</span><span id="line-60">  // Injection is driven by the test and bound to a target table, not a global call count:</span>
+<span class="source-line-no">061</span><span id="line-61">  // remoteDispatch() fires for every remote procedure in the cluster (startup, table creation,</span>
+<span class="source-line-no">062</span><span id="line-62">  // chores, background assignments), so counting calls drifts and misses the operations under test.</span>
+<span class="source-line-no">063</span><span id="line-63">  private static final AtomicBoolean INJECT = new AtomicBoolean(false);</span>
+<span class="source-line-no">064</span><span id="line-64">  private static final AtomicInteger VICTIMS_REMAINING = new AtomicInteger(0);</span>
+<span class="source-line-no">065</span><span id="line-65">  private static volatile TableName targetTable;</span>
+<span class="source-line-no">066</span><span id="line-66"></span>
+<span class="source-line-no">067</span><span id="line-67">  // Fail-fast retry limit after which the master schedules an SCP; read from conf to match test.</span>
+<span class="source-line-no">068</span><span id="line-68">  private final int failFastLimit;</span>
+<span class="source-line-no">069</span><span id="line-69"></span>
+<span class="source-line-no">070</span><span id="line-70">  /**</span>
+<span class="source-line-no">071</span><span id="line-71">   * Fails the next {@code n} open/close-region requests for {@code table} with connection errors</span>
+<span class="source-line-no">072</span><span id="line-72">   * until the fail-fast retry limit is exhausted, so the master schedules an SCP. Call right before</span>
+<span class="source-line-no">073</span><span id="line-73">   * the operations under test.</span>
+<span class="source-line-no">074</span><span id="line-74">   */</span>
+<span class="source-line-no">075</span><span id="line-75">  static void injectErrorsForNextRequests(TableName table, int n) {</span>
+<span class="source-line-no">076</span><span id="line-76">    ERROR_IDX.set(0);</span>
+<span class="source-line-no">077</span><span id="line-77">    targetTable = table;</span>
+<span class="source-line-no">078</span><span id="line-78">    VICTIMS_REMAINING.set(n);</span>
+<span class="source-line-no">079</span><span id="line-79">    INJECT.set(true);</span>
+<span class="source-line-no">080</span><span id="line-80">  }</span>
+<span class="source-line-no">081</span><span id="line-81"></span>
+<span class="source-line-no">082</span><span id="line-82">  /** Stops error injection. Safe to call unconditionally, e.g. from test teardown. */</span>
+<span class="source-line-no">083</span><span id="line-83">  static void stopInjecting() {</span>
+<span class="source-line-no">084</span><span id="line-84">    INJECT.set(false);</span>
+<span class="source-line-no">085</span><span id="line-85">    VICTIMS_REMAINING.set(0);</span>
+<span class="source-line-no">086</span><span id="line-86">    targetTable = null;</span>
+<span class="source-line-no">087</span><span id="line-87">  }</span>
+<span class="source-line-no">088</span><span id="line-88"></span>
+<span class="source-line-no">089</span><span id="line-89">  public RSProcDispatcher(MasterServices master) {</span>
+<span class="source-line-no">090</span><span id="line-90">    super(master);</span>
+<span class="source-line-no">091</span><span id="line-91">    this.failFastLimit = master.getConfiguration().getInt(FAIL_FAST_LIMIT_KEY, 10);</span>
+<span class="source-line-no">092</span><span id="line-92">  }</span>
+<span class="source-line-no">093</span><span id="line-93"></span>
+<span class="source-line-no">094</span><span id="line-94">  @Override</span>
+<span class="source-line-no">095</span><span id="line-95">  protected void remoteDispatch(final ServerName serverName,</span>
+<span class="source-line-no">096</span><span id="line-96">    final Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">097</span><span id="line-97">    if (!master.getServerManager().isServerOnline(serverName)) {</span>
+<span class="source-line-no">098</span><span id="line-98">      // fail fast</span>
+<span class="source-line-no">099</span><span id="line-99">      submitTask(new DeadRSRemoteCall(serverName, remoteProcedures));</span>
+<span class="source-line-no">100</span><span id="line-100">    } else {</span>
+<span class="source-line-no">101</span><span id="line-101">      submitTask(new TestExecuteProceduresRemoteCall(serverName, remoteProcedures));</span>
+<span class="source-line-no">102</span><span id="line-102">    }</span>
+<span class="source-line-no">103</span><span id="line-103">  }</span>
 <span class="source-line-no">104</span><span id="line-104"></span>
-<span class="source-line-no">105</span><span id="line-105">    public DeadRSRemoteCall(ServerName serverName, Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">106</span><span id="line-106">      super(serverName, remoteProcedures);</span>
-<span class="source-line-no">107</span><span id="line-107">    }</span>
-<span class="source-line-no">108</span><span id="line-108"></span>
-<span class="source-line-no">109</span><span id="line-109">    @Override</span>
-<span class="source-line-no">110</span><span id="line-110">    public void run() {</span>
-<span class="source-line-no">111</span><span id="line-111">      remoteCallFailed(master.getMasterProcedureExecutor().getEnvironment(),</span>
-<span class="source-line-no">112</span><span id="line-112">        new RegionServerStoppedException("Server " + getServerName() + " is not online"));</span>
+<span class="source-line-no">105</span><span id="line-105">  /**</span>
+<span class="source-line-no">106</span><span id="line-106">   * True if the request opens or closes a region of the injection target table. Open requests carry</span>
+<span class="source-line-no">107</span><span id="line-107">   * a full RegionInfo; close requests carry a REGION_NAME specifier the table is parsed from.</span>
+<span class="source-line-no">108</span><span id="line-108">   */</span>
+<span class="source-line-no">109</span><span id="line-109">  private static boolean targetsInjectionTable(AdminProtos.ExecuteProceduresRequest request) {</span>
+<span class="source-line-no">110</span><span id="line-110">    TableName table = targetTable;</span>
+<span class="source-line-no">111</span><span id="line-111">    if (table == null) {</span>
+<span class="source-line-no">112</span><span id="line-112">      return false;</span>
 <span class="source-line-no">113</span><span id="line-113">    }</span>
-<span class="source-line-no">114</span><span id="line-114">  }</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116">}</span>
+<span class="source-line-no">114</span><span id="line-114">    for (AdminProtos.OpenRegionRequest open : request.getOpenRegionList()) {</span>
+<span class="source-line-no">115</span><span id="line-115">      for (AdminProtos.OpenRegionRequest.RegionOpenInfo info : open.getOpenInfoList()) {</span>
+<span class="source-line-no">116</span><span id="line-116">        if (table.equals(ProtobufUtil.toTableName(info.getRegion().getTableName()))) {</span>
+<span class="source-line-no">117</span><span id="line-117">          return true;</span>
+<span class="source-line-no">118</span><span id="line-118">        }</span>
+<span class="source-line-no">119</span><span id="line-119">      }</span>
+<span class="source-line-no">120</span><span id="line-120">    }</span>
+<span class="source-line-no">121</span><span id="line-121">    for (AdminProtos.CloseRegionRequest close : request.getCloseRegionList()) {</span>
+<span class="source-line-no">122</span><span id="line-122">      HBaseProtos.RegionSpecifier region = close.getRegion();</span>
+<span class="source-line-no">123</span><span id="line-123">      if (</span>
+<span class="source-line-no">124</span><span id="line-124">        region.getType() == HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME</span>
+<span class="source-line-no">125</span><span id="line-125">          &amp;&amp; table.equals(RegionInfo.getTable(region.getValue().toByteArray()))</span>
+<span class="source-line-no">126</span><span id="line-126">      ) {</span>
+<span class="source-line-no">127</span><span id="line-127">        return true;</span>
+<span class="source-line-no">128</span><span id="line-128">      }</span>
+<span class="source-line-no">129</span><span id="line-129">    }</span>
+<span class="source-line-no">130</span><span id="line-130">    return false;</span>
+<span class="source-line-no">131</span><span id="line-131">  }</span>
+<span class="source-line-no">132</span><span id="line-132"></span>
+<span class="source-line-no">133</span><span id="line-133">  class TestExecuteProceduresRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">134</span><span id="line-134"></span>
+<span class="source-line-no">135</span><span id="line-135">    // attempts: retries of this single request instance (mirrors the dispatcher's</span>
+<span class="source-line-no">136</span><span id="line-136">    // numberOfAttemptsSoFar). injectErrors: whether this instance is failed with injected errors,</span>
+<span class="source-line-no">137</span><span id="line-137">    // decided once on the first call and kept across its retries.</span>
+<span class="source-line-no">138</span><span id="line-138">    private int attempts = 0;</span>
+<span class="source-line-no">139</span><span id="line-139">    private Boolean injectErrors = null;</span>
+<span class="source-line-no">140</span><span id="line-140"></span>
+<span class="source-line-no">141</span><span id="line-141">    public TestExecuteProceduresRemoteCall(ServerName serverName,</span>
+<span class="source-line-no">142</span><span id="line-142">      Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">143</span><span id="line-143">      super(serverName, remoteProcedures);</span>
+<span class="source-line-no">144</span><span id="line-144">    }</span>
+<span class="source-line-no">145</span><span id="line-145"></span>
+<span class="source-line-no">146</span><span id="line-146">    @Override</span>
+<span class="source-line-no">147</span><span id="line-147">    public AdminProtos.ExecuteProceduresResponse sendRequest(final ServerName serverName,</span>
+<span class="source-line-no">148</span><span id="line-148">      final AdminProtos.ExecuteProceduresRequest request) throws IOException {</span>
+<span class="source-line-no">149</span><span id="line-149">      if (injectErrors == null) {</span>
+<span class="source-line-no">150</span><span id="line-150">        // Claim a slot only for a target-table open/close request, once per instance.</span>
+<span class="source-line-no">151</span><span id="line-151">        injectErrors =</span>
+<span class="source-line-no">152</span><span id="line-152">          INJECT.get() &amp;&amp; targetsInjectionTable(request) &amp;&amp; VICTIMS_REMAINING.getAndDecrement() &gt; 0;</span>
+<span class="source-line-no">153</span><span id="line-153">      }</span>
+<span class="source-line-no">154</span><span id="line-154">      LOG.info("sendRequest() req: {}, attempts: {}, injectErrors: {}", request, attempts,</span>
+<span class="source-line-no">155</span><span id="line-155">        injectErrors);</span>
+<span class="source-line-no">156</span><span id="line-156">      if (!injectErrors) {</span>
+<span class="source-line-no">157</span><span id="line-157">        return FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
+<span class="source-line-no">158</span><span id="line-158">      }</span>
+<span class="source-line-no">159</span><span id="line-159">      // Throw a connection error each attempt until the retry limit is exhausted (-&gt; SCP). On the</span>
+<span class="source-line-no">160</span><span id="line-160">      // last attempt run the real open/close first so the region still recovers.</span>
+<span class="source-line-no">161</span><span id="line-161">      if (attempts++ &gt;= failFastLimit - 1) {</span>
+<span class="source-line-no">162</span><span id="line-162">        FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
+<span class="source-line-no">163</span><span id="line-163">      }</span>
+<span class="source-line-no">164</span><span id="line-164">      throw ERRORS.get(ERROR_IDX.getAndIncrement() % ERRORS.size());</span>
+<span class="source-line-no">165</span><span id="line-165">    }</span>
+<span class="source-line-no">166</span><span id="line-166"></span>
+<span class="source-line-no">167</span><span id="line-167">    private AsyncRegionServerAdmin getRsAdmin() {</span>
+<span class="source-line-no">168</span><span id="line-168">      return master.getAsyncClusterConnection().getRegionServerAdmin(getServerName());</span>
+<span class="source-line-no">169</span><span id="line-169">    }</span>
+<span class="source-line-no">170</span><span id="line-170">  }</span>
+<span class="source-line-no">171</span><span id="line-171"></span>
+<span class="source-line-no">172</span><span id="line-172">  private class DeadRSRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">173</span><span id="line-173"></span>
+<span class="source-line-no">174</span><span id="line-174">    public DeadRSRemoteCall(ServerName serverName, Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">175</span><span id="line-175">      super(serverName, remoteProcedures);</span>
+<span class="source-line-no">176</span><span id="line-176">    }</span>
+<span class="source-line-no">177</span><span id="line-177"></span>
+<span class="source-line-no">178</span><span id="line-178">    @Override</span>
+<span class="source-line-no">179</span><span id="line-179">    public void run() {</span>
+<span class="source-line-no">180</span><span id="line-180">      remoteCallFailed(master.getMasterProcedureExecutor().getEnvironment(),</span>
+<span class="source-line-no">181</span><span id="line-181">        new RegionServerStoppedException("Server " + getServerName() + " is not online"));</span>
+<span class="source-line-no">182</span><span id="line-182">    }</span>
+<span class="source-line-no">183</span><span id="line-183">  }</span>
+<span class="source-line-no">184</span><span id="line-184">}</span>
 
 
 
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html
index f746d603faa..08180d7a118 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.TestExecuteProceduresRemoteCall.html
@@ -36,97 +36,165 @@
 <span class="source-line-no">023</span><span id="line-23">import java.util.Arrays;</span>
 <span class="source-line-no">024</span><span id="line-24">import java.util.List;</span>
 <span class="source-line-no">025</span><span id="line-25">import java.util.Set;</span>
-<span class="source-line-no">026</span><span id="line-26">import java.util.concurrent.atomic.AtomicInteger;</span>
-<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.ServerName;</span>
-<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;</span>
-<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;</span>
-<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.master.MasterServices;</span>
-<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;</span>
-<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;</span>
-<span class="source-line-no">033</span><span id="line-33">import org.slf4j.Logger;</span>
-<span class="source-line-no">034</span><span id="line-34">import org.slf4j.LoggerFactory;</span>
-<span class="source-line-no">035</span><span id="line-35"></span>
-<span class="source-line-no">036</span><span id="line-36">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;</span>
-<span class="source-line-no">037</span><span id="line-37"></span>
-<span class="source-line-no">038</span><span id="line-38">/**</span>
-<span class="source-line-no">039</span><span id="line-39"> * Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</span>
-<span class="source-line-no">040</span><span id="line-40"> */</span>
-<span class="source-line-no">041</span><span id="line-41">public class RSProcDispatcher extends RSProcedureDispatcher {</span>
+<span class="source-line-no">026</span><span id="line-26">import java.util.concurrent.atomic.AtomicBoolean;</span>
+<span class="source-line-no">027</span><span id="line-27">import java.util.concurrent.atomic.AtomicInteger;</span>
+<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.ServerName;</span>
+<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.TableName;</span>
+<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;</span>
+<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.client.RegionInfo;</span>
+<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;</span>
+<span class="source-line-no">033</span><span id="line-33">import org.apache.hadoop.hbase.master.MasterServices;</span>
+<span class="source-line-no">034</span><span id="line-34">import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;</span>
+<span class="source-line-no">035</span><span id="line-35">import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;</span>
+<span class="source-line-no">036</span><span id="line-36">import org.slf4j.Logger;</span>
+<span class="source-line-no">037</span><span id="line-37">import org.slf4j.LoggerFactory;</span>
+<span class="source-line-no">038</span><span id="line-38"></span>
+<span class="source-line-no">039</span><span id="line-39">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span>
+<span class="source-line-no">040</span><span id="line-40">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;</span>
+<span class="source-line-no">041</span><span id="line-41">import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;</span>
 <span class="source-line-no">042</span><span id="line-42"></span>
-<span class="source-line-no">043</span><span id="line-43">  private static final Logger LOG = LoggerFactory.getLogger(RSProcDispatcher.class);</span>
-<span class="source-line-no">044</span><span id="line-44"></span>
-<span class="source-line-no">045</span><span id="line-45">  private static final AtomicInteger I = new AtomicInteger();</span>
-<span class="source-line-no">046</span><span id="line-46"></span>
-<span class="source-line-no">047</span><span id="line-47">  private static final List&lt;IOException&gt; ERRORS =</span>
-<span class="source-line-no">048</span><span id="line-48">    Arrays.asList(new ConnectionClosedException("test connection closed error..."),</span>
-<span class="source-line-no">049</span><span id="line-49">      new UnknownHostException("test unknown host error..."),</span>
-<span class="source-line-no">050</span><span id="line-50">      new ConnectException("test connect error..."));</span>
-<span class="source-line-no">051</span><span id="line-51"></span>
-<span class="source-line-no">052</span><span id="line-52">  private static final AtomicInteger ERROR_IDX = new AtomicInteger();</span>
-<span class="source-line-no">053</span><span id="line-53"></span>
-<span class="source-line-no">054</span><span id="line-54">  public RSProcDispatcher(MasterServices master) {</span>
-<span class="source-line-no">055</span><span id="line-55">    super(master);</span>
-<span class="source-line-no">056</span><span id="line-56">  }</span>
+<span class="source-line-no">043</span><span id="line-43">/**</span>
+<span class="source-line-no">044</span><span id="line-44"> * Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</span>
+<span class="source-line-no">045</span><span id="line-45"> */</span>
+<span class="source-line-no">046</span><span id="line-46">public class RSProcDispatcher extends RSProcedureDispatcher {</span>
+<span class="source-line-no">047</span><span id="line-47"></span>
+<span class="source-line-no">048</span><span id="line-48">  private static final Logger LOG = LoggerFactory.getLogger(RSProcDispatcher.class);</span>
+<span class="source-line-no">049</span><span id="line-49"></span>
+<span class="source-line-no">050</span><span id="line-50">  /** Config key for the fail-fast retry limit, shared with the test so the two cannot drift. */</span>
+<span class="source-line-no">051</span><span id="line-51">  static final String FAIL_FAST_LIMIT_KEY = "hbase.master.rs.remote.proc.fail.fast.limit";</span>
+<span class="source-line-no">052</span><span id="line-52"></span>
+<span class="source-line-no">053</span><span id="line-53">  private static final List&lt;IOException&gt; ERRORS =</span>
+<span class="source-line-no">054</span><span id="line-54">    Arrays.asList(new ConnectionClosedException("test connection closed error..."),</span>
+<span class="source-line-no">055</span><span id="line-55">      new UnknownHostException("test unknown host error..."),</span>
+<span class="source-line-no">056</span><span id="line-56">      new ConnectException("test connect error..."));</span>
 <span class="source-line-no">057</span><span id="line-57"></span>
-<span class="source-line-no">058</span><span id="line-58">  @Override</span>
-<span class="source-line-no">059</span><span id="line-59">  protected void remoteDispatch(final ServerName serverName,</span>
-<span class="source-line-no">060</span><span id="line-60">    final Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">061</span><span id="line-61">    if (!master.getServerManager().isServerOnline(serverName)) {</span>
-<span class="source-line-no">062</span><span id="line-62">      // fail fast</span>
-<span class="source-line-no">063</span><span id="line-63">      submitTask(new DeadRSRemoteCall(serverName, remoteProcedures));</span>
-<span class="source-line-no">064</span><span id="line-64">    } else {</span>
-<span class="source-line-no">065</span><span id="line-65">      submitTask(new TestExecuteProceduresRemoteCall(serverName, remoteProcedures));</span>
-<span class="source-line-no">066</span><span id="line-66">    }</span>
-<span class="source-line-no">067</span><span id="line-67">  }</span>
-<span class="source-line-no">068</span><span id="line-68"></span>
-<span class="source-line-no">069</span><span id="line-69">  class TestExecuteProceduresRemoteCall extends ExecuteProceduresRemoteCall {</span>
-<span class="source-line-no">070</span><span id="line-70"></span>
-<span class="source-line-no">071</span><span id="line-71">    public TestExecuteProceduresRemoteCall(ServerName serverName,</span>
-<span class="source-line-no">072</span><span id="line-72">      Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">073</span><span id="line-73">      super(serverName, remoteProcedures);</span>
-<span class="source-line-no">074</span><span id="line-74">    }</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76">    @Override</span>
-<span class="source-line-no">077</span><span id="line-77">    public AdminProtos.ExecuteProceduresResponse sendRequest(final ServerName serverName,</span>
-<span class="source-line-no">078</span><span id="line-78">      final AdminProtos.ExecuteProceduresRequest request) throws IOException {</span>
-<span class="source-line-no">079</span><span id="line-79">      int j = I.addAndGet(1);</span>
-<span class="source-line-no">080</span><span id="line-80">      LOG.info("sendRequest() req: {} , j: {}", request, j);</span>
-<span class="source-line-no">081</span><span id="line-81">      if (j == 12 || j == 22) {</span>
-<span class="source-line-no">082</span><span id="line-82">        // Execute the remote close and open region requests in the last (5th) retry before</span>
-<span class="source-line-no">083</span><span id="line-83">        // throwing ConnectionClosedException. This is to ensure even if the region open/close</span>
-<span class="source-line-no">084</span><span id="line-84">        // is successfully completed by regionserver, master still schedules SCP because</span>
-<span class="source-line-no">085</span><span id="line-85">        // sendRequest() throws error which has retry-limit exhausted.</span>
-<span class="source-line-no">086</span><span id="line-86">        FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
-<span class="source-line-no">087</span><span id="line-87">      }</span>
-<span class="source-line-no">088</span><span id="line-88">      // For one of the close region requests and one of the open region requests,</span>
-<span class="source-line-no">089</span><span id="line-89">      // throw ConnectionClosedException until retry limit is exhausted and master</span>
-<span class="source-line-no">090</span><span id="line-90">      // schedules recoveries for the server.</span>
-<span class="source-line-no">091</span><span id="line-91">      // We will have ABNORMALLY_CLOSED regions, and they are expected to recover on their own.</span>
-<span class="source-line-no">092</span><span id="line-92">      if (j &gt;= 8 &amp;&amp; j &lt;= 13 || j &gt;= 18 &amp;&amp; j &lt;= 23) {</span>
-<span class="source-line-no">093</span><span id="line-93">        throw ERRORS.get(ERROR_IDX.getAndIncrement() % ERRORS.size());</span>
-<span class="source-line-no">094</span><span id="line-94">      }</span>
-<span class="source-line-no">095</span><span id="line-95">      return FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
-<span class="source-line-no">096</span><span id="line-96">    }</span>
-<span class="source-line-no">097</span><span id="line-97"></span>
-<span class="source-line-no">098</span><span id="line-98">    private AsyncRegionServerAdmin getRsAdmin() {</span>
-<span class="source-line-no">099</span><span id="line-99">      return master.getAsyncClusterConnection().getRegionServerAdmin(getServerName());</span>
-<span class="source-line-no">100</span><span id="line-100">    }</span>
-<span class="source-line-no">101</span><span id="line-101">  }</span>
-<span class="source-line-no">102</span><span id="line-102"></span>
-<span class="source-line-no">103</span><span id="line-103">  private class DeadRSRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">058</span><span id="line-58">  private static final AtomicInteger ERROR_IDX = new AtomicInteger();</span>
+<span class="source-line-no">059</span><span id="line-59"></span>
+<span class="source-line-no">060</span><span id="line-60">  // Injection is driven by the test and bound to a target table, not a global call count:</span>
+<span class="source-line-no">061</span><span id="line-61">  // remoteDispatch() fires for every remote procedure in the cluster (startup, table creation,</span>
+<span class="source-line-no">062</span><span id="line-62">  // chores, background assignments), so counting calls drifts and misses the operations under test.</span>
+<span class="source-line-no">063</span><span id="line-63">  private static final AtomicBoolean INJECT = new AtomicBoolean(false);</span>
+<span class="source-line-no">064</span><span id="line-64">  private static final AtomicInteger VICTIMS_REMAINING = new AtomicInteger(0);</span>
+<span class="source-line-no">065</span><span id="line-65">  private static volatile TableName targetTable;</span>
+<span class="source-line-no">066</span><span id="line-66"></span>
+<span class="source-line-no">067</span><span id="line-67">  // Fail-fast retry limit after which the master schedules an SCP; read from conf to match test.</span>
+<span class="source-line-no">068</span><span id="line-68">  private final int failFastLimit;</span>
+<span class="source-line-no">069</span><span id="line-69"></span>
+<span class="source-line-no">070</span><span id="line-70">  /**</span>
+<span class="source-line-no">071</span><span id="line-71">   * Fails the next {@code n} open/close-region requests for {@code table} with connection errors</span>
+<span class="source-line-no">072</span><span id="line-72">   * until the fail-fast retry limit is exhausted, so the master schedules an SCP. Call right before</span>
+<span class="source-line-no">073</span><span id="line-73">   * the operations under test.</span>
+<span class="source-line-no">074</span><span id="line-74">   */</span>
+<span class="source-line-no">075</span><span id="line-75">  static void injectErrorsForNextRequests(TableName table, int n) {</span>
+<span class="source-line-no">076</span><span id="line-76">    ERROR_IDX.set(0);</span>
+<span class="source-line-no">077</span><span id="line-77">    targetTable = table;</span>
+<span class="source-line-no">078</span><span id="line-78">    VICTIMS_REMAINING.set(n);</span>
+<span class="source-line-no">079</span><span id="line-79">    INJECT.set(true);</span>
+<span class="source-line-no">080</span><span id="line-80">  }</span>
+<span class="source-line-no">081</span><span id="line-81"></span>
+<span class="source-line-no">082</span><span id="line-82">  /** Stops error injection. Safe to call unconditionally, e.g. from test teardown. */</span>
+<span class="source-line-no">083</span><span id="line-83">  static void stopInjecting() {</span>
+<span class="source-line-no">084</span><span id="line-84">    INJECT.set(false);</span>
+<span class="source-line-no">085</span><span id="line-85">    VICTIMS_REMAINING.set(0);</span>
+<span class="source-line-no">086</span><span id="line-86">    targetTable = null;</span>
+<span class="source-line-no">087</span><span id="line-87">  }</span>
+<span class="source-line-no">088</span><span id="line-88"></span>
+<span class="source-line-no">089</span><span id="line-89">  public RSProcDispatcher(MasterServices master) {</span>
+<span class="source-line-no">090</span><span id="line-90">    super(master);</span>
+<span class="source-line-no">091</span><span id="line-91">    this.failFastLimit = master.getConfiguration().getInt(FAIL_FAST_LIMIT_KEY, 10);</span>
+<span class="source-line-no">092</span><span id="line-92">  }</span>
+<span class="source-line-no">093</span><span id="line-93"></span>
+<span class="source-line-no">094</span><span id="line-94">  @Override</span>
+<span class="source-line-no">095</span><span id="line-95">  protected void remoteDispatch(final ServerName serverName,</span>
+<span class="source-line-no">096</span><span id="line-96">    final Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">097</span><span id="line-97">    if (!master.getServerManager().isServerOnline(serverName)) {</span>
+<span class="source-line-no">098</span><span id="line-98">      // fail fast</span>
+<span class="source-line-no">099</span><span id="line-99">      submitTask(new DeadRSRemoteCall(serverName, remoteProcedures));</span>
+<span class="source-line-no">100</span><span id="line-100">    } else {</span>
+<span class="source-line-no">101</span><span id="line-101">      submitTask(new TestExecuteProceduresRemoteCall(serverName, remoteProcedures));</span>
+<span class="source-line-no">102</span><span id="line-102">    }</span>
+<span class="source-line-no">103</span><span id="line-103">  }</span>
 <span class="source-line-no">104</span><span id="line-104"></span>
-<span class="source-line-no">105</span><span id="line-105">    public DeadRSRemoteCall(ServerName serverName, Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">106</span><span id="line-106">      super(serverName, remoteProcedures);</span>
-<span class="source-line-no">107</span><span id="line-107">    }</span>
-<span class="source-line-no">108</span><span id="line-108"></span>
-<span class="source-line-no">109</span><span id="line-109">    @Override</span>
-<span class="source-line-no">110</span><span id="line-110">    public void run() {</span>
-<span class="source-line-no">111</span><span id="line-111">      remoteCallFailed(master.getMasterProcedureExecutor().getEnvironment(),</span>
-<span class="source-line-no">112</span><span id="line-112">        new RegionServerStoppedException("Server " + getServerName() + " is not online"));</span>
+<span class="source-line-no">105</span><span id="line-105">  /**</span>
+<span class="source-line-no">106</span><span id="line-106">   * True if the request opens or closes a region of the injection target table. Open requests carry</span>
+<span class="source-line-no">107</span><span id="line-107">   * a full RegionInfo; close requests carry a REGION_NAME specifier the table is parsed from.</span>
+<span class="source-line-no">108</span><span id="line-108">   */</span>
+<span class="source-line-no">109</span><span id="line-109">  private static boolean targetsInjectionTable(AdminProtos.ExecuteProceduresRequest request) {</span>
+<span class="source-line-no">110</span><span id="line-110">    TableName table = targetTable;</span>
+<span class="source-line-no">111</span><span id="line-111">    if (table == null) {</span>
+<span class="source-line-no">112</span><span id="line-112">      return false;</span>
 <span class="source-line-no">113</span><span id="line-113">    }</span>
-<span class="source-line-no">114</span><span id="line-114">  }</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116">}</span>
+<span class="source-line-no">114</span><span id="line-114">    for (AdminProtos.OpenRegionRequest open : request.getOpenRegionList()) {</span>
+<span class="source-line-no">115</span><span id="line-115">      for (AdminProtos.OpenRegionRequest.RegionOpenInfo info : open.getOpenInfoList()) {</span>
+<span class="source-line-no">116</span><span id="line-116">        if (table.equals(ProtobufUtil.toTableName(info.getRegion().getTableName()))) {</span>
+<span class="source-line-no">117</span><span id="line-117">          return true;</span>
+<span class="source-line-no">118</span><span id="line-118">        }</span>
+<span class="source-line-no">119</span><span id="line-119">      }</span>
+<span class="source-line-no">120</span><span id="line-120">    }</span>
+<span class="source-line-no">121</span><span id="line-121">    for (AdminProtos.CloseRegionRequest close : request.getCloseRegionList()) {</span>
+<span class="source-line-no">122</span><span id="line-122">      HBaseProtos.RegionSpecifier region = close.getRegion();</span>
+<span class="source-line-no">123</span><span id="line-123">      if (</span>
+<span class="source-line-no">124</span><span id="line-124">        region.getType() == HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME</span>
+<span class="source-line-no">125</span><span id="line-125">          &amp;&amp; table.equals(RegionInfo.getTable(region.getValue().toByteArray()))</span>
+<span class="source-line-no">126</span><span id="line-126">      ) {</span>
+<span class="source-line-no">127</span><span id="line-127">        return true;</span>
+<span class="source-line-no">128</span><span id="line-128">      }</span>
+<span class="source-line-no">129</span><span id="line-129">    }</span>
+<span class="source-line-no">130</span><span id="line-130">    return false;</span>
+<span class="source-line-no">131</span><span id="line-131">  }</span>
+<span class="source-line-no">132</span><span id="line-132"></span>
+<span class="source-line-no">133</span><span id="line-133">  class TestExecuteProceduresRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">134</span><span id="line-134"></span>
+<span class="source-line-no">135</span><span id="line-135">    // attempts: retries of this single request instance (mirrors the dispatcher's</span>
+<span class="source-line-no">136</span><span id="line-136">    // numberOfAttemptsSoFar). injectErrors: whether this instance is failed with injected errors,</span>
+<span class="source-line-no">137</span><span id="line-137">    // decided once on the first call and kept across its retries.</span>
+<span class="source-line-no">138</span><span id="line-138">    private int attempts = 0;</span>
+<span class="source-line-no">139</span><span id="line-139">    private Boolean injectErrors = null;</span>
+<span class="source-line-no">140</span><span id="line-140"></span>
+<span class="source-line-no">141</span><span id="line-141">    public TestExecuteProceduresRemoteCall(ServerName serverName,</span>
+<span class="source-line-no">142</span><span id="line-142">      Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">143</span><span id="line-143">      super(serverName, remoteProcedures);</span>
+<span class="source-line-no">144</span><span id="line-144">    }</span>
+<span class="source-line-no">145</span><span id="line-145"></span>
+<span class="source-line-no">146</span><span id="line-146">    @Override</span>
+<span class="source-line-no">147</span><span id="line-147">    public AdminProtos.ExecuteProceduresResponse sendRequest(final ServerName serverName,</span>
+<span class="source-line-no">148</span><span id="line-148">      final AdminProtos.ExecuteProceduresRequest request) throws IOException {</span>
+<span class="source-line-no">149</span><span id="line-149">      if (injectErrors == null) {</span>
+<span class="source-line-no">150</span><span id="line-150">        // Claim a slot only for a target-table open/close request, once per instance.</span>
+<span class="source-line-no">151</span><span id="line-151">        injectErrors =</span>
+<span class="source-line-no">152</span><span id="line-152">          INJECT.get() &amp;&amp; targetsInjectionTable(request) &amp;&amp; VICTIMS_REMAINING.getAndDecrement() &gt; 0;</span>
+<span class="source-line-no">153</span><span id="line-153">      }</span>
+<span class="source-line-no">154</span><span id="line-154">      LOG.info("sendRequest() req: {}, attempts: {}, injectErrors: {}", request, attempts,</span>
+<span class="source-line-no">155</span><span id="line-155">        injectErrors);</span>
+<span class="source-line-no">156</span><span id="line-156">      if (!injectErrors) {</span>
+<span class="source-line-no">157</span><span id="line-157">        return FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
+<span class="source-line-no">158</span><span id="line-158">      }</span>
+<span class="source-line-no">159</span><span id="line-159">      // Throw a connection error each attempt until the retry limit is exhausted (-&gt; SCP). On the</span>
+<span class="source-line-no">160</span><span id="line-160">      // last attempt run the real open/close first so the region still recovers.</span>
+<span class="source-line-no">161</span><span id="line-161">      if (attempts++ &gt;= failFastLimit - 1) {</span>
+<span class="source-line-no">162</span><span id="line-162">        FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
+<span class="source-line-no">163</span><span id="line-163">      }</span>
+<span class="source-line-no">164</span><span id="line-164">      throw ERRORS.get(ERROR_IDX.getAndIncrement() % ERRORS.size());</span>
+<span class="source-line-no">165</span><span id="line-165">    }</span>
+<span class="source-line-no">166</span><span id="line-166"></span>
+<span class="source-line-no">167</span><span id="line-167">    private AsyncRegionServerAdmin getRsAdmin() {</span>
+<span class="source-line-no">168</span><span id="line-168">      return master.getAsyncClusterConnection().getRegionServerAdmin(getServerName());</span>
+<span class="source-line-no">169</span><span id="line-169">    }</span>
+<span class="source-line-no">170</span><span id="line-170">  }</span>
+<span class="source-line-no">171</span><span id="line-171"></span>
+<span class="source-line-no">172</span><span id="line-172">  private class DeadRSRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">173</span><span id="line-173"></span>
+<span class="source-line-no">174</span><span id="line-174">    public DeadRSRemoteCall(ServerName serverName, Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">175</span><span id="line-175">      super(serverName, remoteProcedures);</span>
+<span class="source-line-no">176</span><span id="line-176">    }</span>
+<span class="source-line-no">177</span><span id="line-177"></span>
+<span class="source-line-no">178</span><span id="line-178">    @Override</span>
+<span class="source-line-no">179</span><span id="line-179">    public void run() {</span>
+<span class="source-line-no">180</span><span id="line-180">      remoteCallFailed(master.getMasterProcedureExecutor().getEnvironment(),</span>
+<span class="source-line-no">181</span><span id="line-181">        new RegionServerStoppedException("Server " + getServerName() + " is not online"));</span>
+<span class="source-line-no">182</span><span id="line-182">    }</span>
+<span class="source-line-no">183</span><span id="line-183">  }</span>
+<span class="source-line-no">184</span><span id="line-184">}</span>
 
 
 
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html
index b676f94e16b..fcca06ad2ba 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/util/RSProcDispatcher.html
@@ -36,97 +36,165 @@
 <span class="source-line-no">023</span><span id="line-23">import java.util.Arrays;</span>
 <span class="source-line-no">024</span><span id="line-24">import java.util.List;</span>
 <span class="source-line-no">025</span><span id="line-25">import java.util.Set;</span>
-<span class="source-line-no">026</span><span id="line-26">import java.util.concurrent.atomic.AtomicInteger;</span>
-<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.ServerName;</span>
-<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;</span>
-<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;</span>
-<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.master.MasterServices;</span>
-<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;</span>
-<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;</span>
-<span class="source-line-no">033</span><span id="line-33">import org.slf4j.Logger;</span>
-<span class="source-line-no">034</span><span id="line-34">import org.slf4j.LoggerFactory;</span>
-<span class="source-line-no">035</span><span id="line-35"></span>
-<span class="source-line-no">036</span><span id="line-36">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;</span>
-<span class="source-line-no">037</span><span id="line-37"></span>
-<span class="source-line-no">038</span><span id="line-38">/**</span>
-<span class="source-line-no">039</span><span id="line-39"> * Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</span>
-<span class="source-line-no">040</span><span id="line-40"> */</span>
-<span class="source-line-no">041</span><span id="line-41">public class RSProcDispatcher extends RSProcedureDispatcher {</span>
+<span class="source-line-no">026</span><span id="line-26">import java.util.concurrent.atomic.AtomicBoolean;</span>
+<span class="source-line-no">027</span><span id="line-27">import java.util.concurrent.atomic.AtomicInteger;</span>
+<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.ServerName;</span>
+<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.TableName;</span>
+<span class="source-line-no">030</span><span id="line-30">import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;</span>
+<span class="source-line-no">031</span><span id="line-31">import org.apache.hadoop.hbase.client.RegionInfo;</span>
+<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.exceptions.ConnectionClosedException;</span>
+<span class="source-line-no">033</span><span id="line-33">import org.apache.hadoop.hbase.master.MasterServices;</span>
+<span class="source-line-no">034</span><span id="line-34">import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;</span>
+<span class="source-line-no">035</span><span id="line-35">import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;</span>
+<span class="source-line-no">036</span><span id="line-36">import org.slf4j.Logger;</span>
+<span class="source-line-no">037</span><span id="line-37">import org.slf4j.LoggerFactory;</span>
+<span class="source-line-no">038</span><span id="line-38"></span>
+<span class="source-line-no">039</span><span id="line-39">import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;</span>
+<span class="source-line-no">040</span><span id="line-40">import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;</span>
+<span class="source-line-no">041</span><span id="line-41">import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;</span>
 <span class="source-line-no">042</span><span id="line-42"></span>
-<span class="source-line-no">043</span><span id="line-43">  private static final Logger LOG = LoggerFactory.getLogger(RSProcDispatcher.class);</span>
-<span class="source-line-no">044</span><span id="line-44"></span>
-<span class="source-line-no">045</span><span id="line-45">  private static final AtomicInteger I = new AtomicInteger();</span>
-<span class="source-line-no">046</span><span id="line-46"></span>
-<span class="source-line-no">047</span><span id="line-47">  private static final List&lt;IOException&gt; ERRORS =</span>
-<span class="source-line-no">048</span><span id="line-48">    Arrays.asList(new ConnectionClosedException("test connection closed error..."),</span>
-<span class="source-line-no">049</span><span id="line-49">      new UnknownHostException("test unknown host error..."),</span>
-<span class="source-line-no">050</span><span id="line-50">      new ConnectException("test connect error..."));</span>
-<span class="source-line-no">051</span><span id="line-51"></span>
-<span class="source-line-no">052</span><span id="line-52">  private static final AtomicInteger ERROR_IDX = new AtomicInteger();</span>
-<span class="source-line-no">053</span><span id="line-53"></span>
-<span class="source-line-no">054</span><span id="line-54">  public RSProcDispatcher(MasterServices master) {</span>
-<span class="source-line-no">055</span><span id="line-55">    super(master);</span>
-<span class="source-line-no">056</span><span id="line-56">  }</span>
+<span class="source-line-no">043</span><span id="line-43">/**</span>
+<span class="source-line-no">044</span><span id="line-44"> * Test implementation of RSProcedureDispatcher that throws desired errors for testing purpose.</span>
+<span class="source-line-no">045</span><span id="line-45"> */</span>
+<span class="source-line-no">046</span><span id="line-46">public class RSProcDispatcher extends RSProcedureDispatcher {</span>
+<span class="source-line-no">047</span><span id="line-47"></span>
+<span class="source-line-no">048</span><span id="line-48">  private static final Logger LOG = LoggerFactory.getLogger(RSProcDispatcher.class);</span>
+<span class="source-line-no">049</span><span id="line-49"></span>
+<span class="source-line-no">050</span><span id="line-50">  /** Config key for the fail-fast retry limit, shared with the test so the two cannot drift. */</span>
+<span class="source-line-no">051</span><span id="line-51">  static final String FAIL_FAST_LIMIT_KEY = "hbase.master.rs.remote.proc.fail.fast.limit";</span>
+<span class="source-line-no">052</span><span id="line-52"></span>
+<span class="source-line-no">053</span><span id="line-53">  private static final List&lt;IOException&gt; ERRORS =</span>
+<span class="source-line-no">054</span><span id="line-54">    Arrays.asList(new ConnectionClosedException("test connection closed error..."),</span>
+<span class="source-line-no">055</span><span id="line-55">      new UnknownHostException("test unknown host error..."),</span>
+<span class="source-line-no">056</span><span id="line-56">      new ConnectException("test connect error..."));</span>
 <span class="source-line-no">057</span><span id="line-57"></span>
-<span class="source-line-no">058</span><span id="line-58">  @Override</span>
-<span class="source-line-no">059</span><span id="line-59">  protected void remoteDispatch(final ServerName serverName,</span>
-<span class="source-line-no">060</span><span id="line-60">    final Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">061</span><span id="line-61">    if (!master.getServerManager().isServerOnline(serverName)) {</span>
-<span class="source-line-no">062</span><span id="line-62">      // fail fast</span>
-<span class="source-line-no">063</span><span id="line-63">      submitTask(new DeadRSRemoteCall(serverName, remoteProcedures));</span>
-<span class="source-line-no">064</span><span id="line-64">    } else {</span>
-<span class="source-line-no">065</span><span id="line-65">      submitTask(new TestExecuteProceduresRemoteCall(serverName, remoteProcedures));</span>
-<span class="source-line-no">066</span><span id="line-66">    }</span>
-<span class="source-line-no">067</span><span id="line-67">  }</span>
-<span class="source-line-no">068</span><span id="line-68"></span>
-<span class="source-line-no">069</span><span id="line-69">  class TestExecuteProceduresRemoteCall extends ExecuteProceduresRemoteCall {</span>
-<span class="source-line-no">070</span><span id="line-70"></span>
-<span class="source-line-no">071</span><span id="line-71">    public TestExecuteProceduresRemoteCall(ServerName serverName,</span>
-<span class="source-line-no">072</span><span id="line-72">      Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">073</span><span id="line-73">      super(serverName, remoteProcedures);</span>
-<span class="source-line-no">074</span><span id="line-74">    }</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76">    @Override</span>
-<span class="source-line-no">077</span><span id="line-77">    public AdminProtos.ExecuteProceduresResponse sendRequest(final ServerName serverName,</span>
-<span class="source-line-no">078</span><span id="line-78">      final AdminProtos.ExecuteProceduresRequest request) throws IOException {</span>
-<span class="source-line-no">079</span><span id="line-79">      int j = I.addAndGet(1);</span>
-<span class="source-line-no">080</span><span id="line-80">      LOG.info("sendRequest() req: {} , j: {}", request, j);</span>
-<span class="source-line-no">081</span><span id="line-81">      if (j == 12 || j == 22) {</span>
-<span class="source-line-no">082</span><span id="line-82">        // Execute the remote close and open region requests in the last (5th) retry before</span>
-<span class="source-line-no">083</span><span id="line-83">        // throwing ConnectionClosedException. This is to ensure even if the region open/close</span>
-<span class="source-line-no">084</span><span id="line-84">        // is successfully completed by regionserver, master still schedules SCP because</span>
-<span class="source-line-no">085</span><span id="line-85">        // sendRequest() throws error which has retry-limit exhausted.</span>
-<span class="source-line-no">086</span><span id="line-86">        FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
-<span class="source-line-no">087</span><span id="line-87">      }</span>
-<span class="source-line-no">088</span><span id="line-88">      // For one of the close region requests and one of the open region requests,</span>
-<span class="source-line-no">089</span><span id="line-89">      // throw ConnectionClosedException until retry limit is exhausted and master</span>
-<span class="source-line-no">090</span><span id="line-90">      // schedules recoveries for the server.</span>
-<span class="source-line-no">091</span><span id="line-91">      // We will have ABNORMALLY_CLOSED regions, and they are expected to recover on their own.</span>
-<span class="source-line-no">092</span><span id="line-92">      if (j &gt;= 8 &amp;&amp; j &lt;= 13 || j &gt;= 18 &amp;&amp; j &lt;= 23) {</span>
-<span class="source-line-no">093</span><span id="line-93">        throw ERRORS.get(ERROR_IDX.getAndIncrement() % ERRORS.size());</span>
-<span class="source-line-no">094</span><span id="line-94">      }</span>
-<span class="source-line-no">095</span><span id="line-95">      return FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
-<span class="source-line-no">096</span><span id="line-96">    }</span>
-<span class="source-line-no">097</span><span id="line-97"></span>
-<span class="source-line-no">098</span><span id="line-98">    private AsyncRegionServerAdmin getRsAdmin() {</span>
-<span class="source-line-no">099</span><span id="line-99">      return master.getAsyncClusterConnection().getRegionServerAdmin(getServerName());</span>
-<span class="source-line-no">100</span><span id="line-100">    }</span>
-<span class="source-line-no">101</span><span id="line-101">  }</span>
-<span class="source-line-no">102</span><span id="line-102"></span>
-<span class="source-line-no">103</span><span id="line-103">  private class DeadRSRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">058</span><span id="line-58">  private static final AtomicInteger ERROR_IDX = new AtomicInteger();</span>
+<span class="source-line-no">059</span><span id="line-59"></span>
+<span class="source-line-no">060</span><span id="line-60">  // Injection is driven by the test and bound to a target table, not a global call count:</span>
+<span class="source-line-no">061</span><span id="line-61">  // remoteDispatch() fires for every remote procedure in the cluster (startup, table creation,</span>
+<span class="source-line-no">062</span><span id="line-62">  // chores, background assignments), so counting calls drifts and misses the operations under test.</span>
+<span class="source-line-no">063</span><span id="line-63">  private static final AtomicBoolean INJECT = new AtomicBoolean(false);</span>
+<span class="source-line-no">064</span><span id="line-64">  private static final AtomicInteger VICTIMS_REMAINING = new AtomicInteger(0);</span>
+<span class="source-line-no">065</span><span id="line-65">  private static volatile TableName targetTable;</span>
+<span class="source-line-no">066</span><span id="line-66"></span>
+<span class="source-line-no">067</span><span id="line-67">  // Fail-fast retry limit after which the master schedules an SCP; read from conf to match test.</span>
+<span class="source-line-no">068</span><span id="line-68">  private final int failFastLimit;</span>
+<span class="source-line-no">069</span><span id="line-69"></span>
+<span class="source-line-no">070</span><span id="line-70">  /**</span>
+<span class="source-line-no">071</span><span id="line-71">   * Fails the next {@code n} open/close-region requests for {@code table} with connection errors</span>
+<span class="source-line-no">072</span><span id="line-72">   * until the fail-fast retry limit is exhausted, so the master schedules an SCP. Call right before</span>
+<span class="source-line-no">073</span><span id="line-73">   * the operations under test.</span>
+<span class="source-line-no">074</span><span id="line-74">   */</span>
+<span class="source-line-no">075</span><span id="line-75">  static void injectErrorsForNextRequests(TableName table, int n) {</span>
+<span class="source-line-no">076</span><span id="line-76">    ERROR_IDX.set(0);</span>
+<span class="source-line-no">077</span><span id="line-77">    targetTable = table;</span>
+<span class="source-line-no">078</span><span id="line-78">    VICTIMS_REMAINING.set(n);</span>
+<span class="source-line-no">079</span><span id="line-79">    INJECT.set(true);</span>
+<span class="source-line-no">080</span><span id="line-80">  }</span>
+<span class="source-line-no">081</span><span id="line-81"></span>
+<span class="source-line-no">082</span><span id="line-82">  /** Stops error injection. Safe to call unconditionally, e.g. from test teardown. */</span>
+<span class="source-line-no">083</span><span id="line-83">  static void stopInjecting() {</span>
+<span class="source-line-no">084</span><span id="line-84">    INJECT.set(false);</span>
+<span class="source-line-no">085</span><span id="line-85">    VICTIMS_REMAINING.set(0);</span>
+<span class="source-line-no">086</span><span id="line-86">    targetTable = null;</span>
+<span class="source-line-no">087</span><span id="line-87">  }</span>
+<span class="source-line-no">088</span><span id="line-88"></span>
+<span class="source-line-no">089</span><span id="line-89">  public RSProcDispatcher(MasterServices master) {</span>
+<span class="source-line-no">090</span><span id="line-90">    super(master);</span>
+<span class="source-line-no">091</span><span id="line-91">    this.failFastLimit = master.getConfiguration().getInt(FAIL_FAST_LIMIT_KEY, 10);</span>
+<span class="source-line-no">092</span><span id="line-92">  }</span>
+<span class="source-line-no">093</span><span id="line-93"></span>
+<span class="source-line-no">094</span><span id="line-94">  @Override</span>
+<span class="source-line-no">095</span><span id="line-95">  protected void remoteDispatch(final ServerName serverName,</span>
+<span class="source-line-no">096</span><span id="line-96">    final Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">097</span><span id="line-97">    if (!master.getServerManager().isServerOnline(serverName)) {</span>
+<span class="source-line-no">098</span><span id="line-98">      // fail fast</span>
+<span class="source-line-no">099</span><span id="line-99">      submitTask(new DeadRSRemoteCall(serverName, remoteProcedures));</span>
+<span class="source-line-no">100</span><span id="line-100">    } else {</span>
+<span class="source-line-no">101</span><span id="line-101">      submitTask(new TestExecuteProceduresRemoteCall(serverName, remoteProcedures));</span>
+<span class="source-line-no">102</span><span id="line-102">    }</span>
+<span class="source-line-no">103</span><span id="line-103">  }</span>
 <span class="source-line-no">104</span><span id="line-104"></span>
-<span class="source-line-no">105</span><span id="line-105">    public DeadRSRemoteCall(ServerName serverName, Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
-<span class="source-line-no">106</span><span id="line-106">      super(serverName, remoteProcedures);</span>
-<span class="source-line-no">107</span><span id="line-107">    }</span>
-<span class="source-line-no">108</span><span id="line-108"></span>
-<span class="source-line-no">109</span><span id="line-109">    @Override</span>
-<span class="source-line-no">110</span><span id="line-110">    public void run() {</span>
-<span class="source-line-no">111</span><span id="line-111">      remoteCallFailed(master.getMasterProcedureExecutor().getEnvironment(),</span>
-<span class="source-line-no">112</span><span id="line-112">        new RegionServerStoppedException("Server " + getServerName() + " is not online"));</span>
+<span class="source-line-no">105</span><span id="line-105">  /**</span>
+<span class="source-line-no">106</span><span id="line-106">   * True if the request opens or closes a region of the injection target table. Open requests carry</span>
+<span class="source-line-no">107</span><span id="line-107">   * a full RegionInfo; close requests carry a REGION_NAME specifier the table is parsed from.</span>
+<span class="source-line-no">108</span><span id="line-108">   */</span>
+<span class="source-line-no">109</span><span id="line-109">  private static boolean targetsInjectionTable(AdminProtos.ExecuteProceduresRequest request) {</span>
+<span class="source-line-no">110</span><span id="line-110">    TableName table = targetTable;</span>
+<span class="source-line-no">111</span><span id="line-111">    if (table == null) {</span>
+<span class="source-line-no">112</span><span id="line-112">      return false;</span>
 <span class="source-line-no">113</span><span id="line-113">    }</span>
-<span class="source-line-no">114</span><span id="line-114">  }</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116">}</span>
+<span class="source-line-no">114</span><span id="line-114">    for (AdminProtos.OpenRegionRequest open : request.getOpenRegionList()) {</span>
+<span class="source-line-no">115</span><span id="line-115">      for (AdminProtos.OpenRegionRequest.RegionOpenInfo info : open.getOpenInfoList()) {</span>
+<span class="source-line-no">116</span><span id="line-116">        if (table.equals(ProtobufUtil.toTableName(info.getRegion().getTableName()))) {</span>
+<span class="source-line-no">117</span><span id="line-117">          return true;</span>
+<span class="source-line-no">118</span><span id="line-118">        }</span>
+<span class="source-line-no">119</span><span id="line-119">      }</span>
+<span class="source-line-no">120</span><span id="line-120">    }</span>
+<span class="source-line-no">121</span><span id="line-121">    for (AdminProtos.CloseRegionRequest close : request.getCloseRegionList()) {</span>
+<span class="source-line-no">122</span><span id="line-122">      HBaseProtos.RegionSpecifier region = close.getRegion();</span>
+<span class="source-line-no">123</span><span id="line-123">      if (</span>
+<span class="source-line-no">124</span><span id="line-124">        region.getType() == HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME</span>
+<span class="source-line-no">125</span><span id="line-125">          &amp;&amp; table.equals(RegionInfo.getTable(region.getValue().toByteArray()))</span>
+<span class="source-line-no">126</span><span id="line-126">      ) {</span>
+<span class="source-line-no">127</span><span id="line-127">        return true;</span>
+<span class="source-line-no">128</span><span id="line-128">      }</span>
+<span class="source-line-no">129</span><span id="line-129">    }</span>
+<span class="source-line-no">130</span><span id="line-130">    return false;</span>
+<span class="source-line-no">131</span><span id="line-131">  }</span>
+<span class="source-line-no">132</span><span id="line-132"></span>
+<span class="source-line-no">133</span><span id="line-133">  class TestExecuteProceduresRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">134</span><span id="line-134"></span>
+<span class="source-line-no">135</span><span id="line-135">    // attempts: retries of this single request instance (mirrors the dispatcher's</span>
+<span class="source-line-no">136</span><span id="line-136">    // numberOfAttemptsSoFar). injectErrors: whether this instance is failed with injected errors,</span>
+<span class="source-line-no">137</span><span id="line-137">    // decided once on the first call and kept across its retries.</span>
+<span class="source-line-no">138</span><span id="line-138">    private int attempts = 0;</span>
+<span class="source-line-no">139</span><span id="line-139">    private Boolean injectErrors = null;</span>
+<span class="source-line-no">140</span><span id="line-140"></span>
+<span class="source-line-no">141</span><span id="line-141">    public TestExecuteProceduresRemoteCall(ServerName serverName,</span>
+<span class="source-line-no">142</span><span id="line-142">      Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">143</span><span id="line-143">      super(serverName, remoteProcedures);</span>
+<span class="source-line-no">144</span><span id="line-144">    }</span>
+<span class="source-line-no">145</span><span id="line-145"></span>
+<span class="source-line-no">146</span><span id="line-146">    @Override</span>
+<span class="source-line-no">147</span><span id="line-147">    public AdminProtos.ExecuteProceduresResponse sendRequest(final ServerName serverName,</span>
+<span class="source-line-no">148</span><span id="line-148">      final AdminProtos.ExecuteProceduresRequest request) throws IOException {</span>
+<span class="source-line-no">149</span><span id="line-149">      if (injectErrors == null) {</span>
+<span class="source-line-no">150</span><span id="line-150">        // Claim a slot only for a target-table open/close request, once per instance.</span>
+<span class="source-line-no">151</span><span id="line-151">        injectErrors =</span>
+<span class="source-line-no">152</span><span id="line-152">          INJECT.get() &amp;&amp; targetsInjectionTable(request) &amp;&amp; VICTIMS_REMAINING.getAndDecrement() &gt; 0;</span>
+<span class="source-line-no">153</span><span id="line-153">      }</span>
+<span class="source-line-no">154</span><span id="line-154">      LOG.info("sendRequest() req: {}, attempts: {}, injectErrors: {}", request, attempts,</span>
+<span class="source-line-no">155</span><span id="line-155">        injectErrors);</span>
+<span class="source-line-no">156</span><span id="line-156">      if (!injectErrors) {</span>
+<span class="source-line-no">157</span><span id="line-157">        return FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
+<span class="source-line-no">158</span><span id="line-158">      }</span>
+<span class="source-line-no">159</span><span id="line-159">      // Throw a connection error each attempt until the retry limit is exhausted (-&gt; SCP). On the</span>
+<span class="source-line-no">160</span><span id="line-160">      // last attempt run the real open/close first so the region still recovers.</span>
+<span class="source-line-no">161</span><span id="line-161">      if (attempts++ &gt;= failFastLimit - 1) {</span>
+<span class="source-line-no">162</span><span id="line-162">        FutureUtils.get(getRsAdmin().executeProcedures(request));</span>
+<span class="source-line-no">163</span><span id="line-163">      }</span>
+<span class="source-line-no">164</span><span id="line-164">      throw ERRORS.get(ERROR_IDX.getAndIncrement() % ERRORS.size());</span>
+<span class="source-line-no">165</span><span id="line-165">    }</span>
+<span class="source-line-no">166</span><span id="line-166"></span>
+<span class="source-line-no">167</span><span id="line-167">    private AsyncRegionServerAdmin getRsAdmin() {</span>
+<span class="source-line-no">168</span><span id="line-168">      return master.getAsyncClusterConnection().getRegionServerAdmin(getServerName());</span>
+<span class="source-line-no">169</span><span id="line-169">    }</span>
+<span class="source-line-no">170</span><span id="line-170">  }</span>
+<span class="source-line-no">171</span><span id="line-171"></span>
+<span class="source-line-no">172</span><span id="line-172">  private class DeadRSRemoteCall extends ExecuteProceduresRemoteCall {</span>
+<span class="source-line-no">173</span><span id="line-173"></span>
+<span class="source-line-no">174</span><span id="line-174">    public DeadRSRemoteCall(ServerName serverName, Set&lt;RemoteProcedure&gt; remoteProcedures) {</span>
+<span class="source-line-no">175</span><span id="line-175">      super(serverName, remoteProcedures);</span>
+<span class="source-line-no">176</span><span id="line-176">    }</span>
+<span class="source-line-no">177</span><span id="line-177"></span>
+<span class="source-line-no">178</span><span id="line-178">    @Override</span>
+<span class="source-line-no">179</span><span id="line-179">    public void run() {</span>
+<span class="source-line-no">180</span><span id="line-180">      remoteCallFailed(master.getMasterProcedureExecutor().getEnvironment(),</span>
+<span class="source-line-no">181</span><span id="line-181">        new RegionServerStoppedException("Server " + getServerName() + " is not online"));</span>
+<span class="source-line-no">182</span><span id="line-182">    }</span>
+<span class="source-line-no">183</span><span id="line-183">  }</span>
+<span class="source-line-no">184</span><span id="line-184">}</span>
 
 
 
diff --git a/testdevapidocs/src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html b/testdevapidocs/src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html
index 9316d77f071..151ac524f28 100644
--- a/testdevapidocs/src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html
+++ b/testdevapidocs/src-html/org/apache/hadoop/hbase/util/TestProcDispatcher.html
@@ -55,131 +55,138 @@
 <span class="source-line-no">042</span><span id="line-42">import org.apache.hadoop.hbase.testclassification.LargeTests;</span>
 <span class="source-line-no">043</span><span id="line-43">import org.apache.hadoop.hbase.testclassification.MiscTests;</span>
 <span class="source-line-no">044</span><span id="line-44">import org.junit.jupiter.api.AfterAll;</span>
-<span class="source-line-no">045</span><span id="line-45">import org.junit.jupiter.api.BeforeAll;</span>
-<span class="source-line-no">046</span><span id="line-46">import org.junit.jupiter.api.BeforeEach;</span>
-<span class="source-line-no">047</span><span id="line-47">import org.junit.jupiter.api.Tag;</span>
-<span class="source-line-no">048</span><span id="line-48">import org.junit.jupiter.api.Test;</span>
-<span class="source-line-no">049</span><span id="line-49">import org.junit.jupiter.api.TestInfo;</span>
-<span class="source-line-no">050</span><span id="line-50">import org.slf4j.Logger;</span>
-<span class="source-line-no">051</span><span id="line-51">import org.slf4j.LoggerFactory;</span>
-<span class="source-line-no">052</span><span id="line-52"></span>
-<span class="source-line-no">053</span><span id="line-53">import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;</span>
-<span class="source-line-no">054</span><span id="line-54"></span>
-<span class="source-line-no">055</span><span id="line-55">/**</span>
-<span class="source-line-no">056</span><span id="line-56"> * Testing custom RSProcedureDispatcher to ensure retry limit can be imposed on certain errors.</span>
-<span class="source-line-no">057</span><span id="line-57"> */</span>
-<span class="source-line-no">058</span><span id="line-58">@Tag(MiscTests.TAG)</span>
-<span class="source-line-no">059</span><span id="line-59">@Tag(LargeTests.TAG)</span>
-<span class="source-line-no">060</span><span id="line-60">public class TestProcDispatcher {</span>
-<span class="source-line-no">061</span><span id="line-61"></span>
-<span class="source-line-no">062</span><span id="line-62">  private static final Logger LOG = LoggerFactory.getLogger(TestProcDispatcher.class);</span>
-<span class="source-line-no">063</span><span id="line-63"></span>
-<span class="source-line-no">064</span><span id="line-64">  private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();</span>
-<span class="source-line-no">065</span><span id="line-65">  private static ServerName rs0;</span>
-<span class="source-line-no">066</span><span id="line-66"></span>
-<span class="source-line-no">067</span><span id="line-67">  @BeforeAll</span>
-<span class="source-line-no">068</span><span id="line-68">  public static void setUpBeforeClass() throws Exception {</span>
-<span class="source-line-no">069</span><span id="line-69">    TEST_UTIL.getConfiguration().set(HBASE_MASTER_RSPROC_DISPATCHER_CLASS,</span>
-<span class="source-line-no">070</span><span id="line-70">      RSProcDispatcher.class.getName());</span>
-<span class="source-line-no">071</span><span id="line-71">    TEST_UTIL.getConfiguration().setInt("hbase.master.rs.remote.proc.fail.fast.limit", 5);</span>
-<span class="source-line-no">072</span><span id="line-72">    TEST_UTIL.startMiniCluster(3);</span>
-<span class="source-line-no">073</span><span id="line-73">    SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();</span>
-<span class="source-line-no">074</span><span id="line-74">    rs0 = cluster.getRegionServer(0).getServerName();</span>
-<span class="source-line-no">075</span><span id="line-75">    TEST_UTIL.getAdmin().balancerSwitch(false, true);</span>
-<span class="source-line-no">076</span><span id="line-76">  }</span>
-<span class="source-line-no">077</span><span id="line-77"></span>
-<span class="source-line-no">078</span><span id="line-78">  @AfterAll</span>
-<span class="source-line-no">079</span><span id="line-79">  public static void tearDownAfterClass() throws Exception {</span>
-<span class="source-line-no">080</span><span id="line-80">    TEST_UTIL.shutdownMiniCluster();</span>
-<span class="source-line-no">081</span><span id="line-81">  }</span>
-<span class="source-line-no">082</span><span id="line-82"></span>
-<span class="source-line-no">083</span><span id="line-83">  @BeforeEach</span>
-<span class="source-line-no">084</span><span id="line-84">  public void setUp(TestInfo testInfo) throws Exception {</span>
-<span class="source-line-no">085</span><span id="line-85">    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());</span>
-<span class="source-line-no">086</span><span id="line-86">    TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(tableName)</span>
-<span class="source-line-no">087</span><span id="line-87">      .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();</span>
-<span class="source-line-no">088</span><span id="line-88">    int startKey = 0;</span>
-<span class="source-line-no">089</span><span id="line-89">    int endKey = 80000;</span>
-<span class="source-line-no">090</span><span id="line-90">    TEST_UTIL.getAdmin().createTable(tableDesc, Bytes.toBytes(startKey), Bytes.toBytes(endKey), 9);</span>
-<span class="source-line-no">091</span><span id="line-91">  }</span>
-<span class="source-line-no">092</span><span id="line-92"></span>
-<span class="source-line-no">093</span><span id="line-93">  @Test</span>
-<span class="source-line-no">094</span><span id="line-94">  public void testRetryLimitOnConnClosedErrors(TestInfo testInfo) throws Exception {</span>
-<span class="source-line-no">095</span><span id="line-95">    HbckChore hbckChore = new HbckChore(TEST_UTIL.getHBaseCluster().getMaster());</span>
-<span class="source-line-no">096</span><span id="line-96">    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());</span>
-<span class="source-line-no">097</span><span id="line-97">    SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();</span>
-<span class="source-line-no">098</span><span id="line-98">    Admin admin = TEST_UTIL.getAdmin();</span>
-<span class="source-line-no">099</span><span id="line-99">    Table table = TEST_UTIL.getConnection().getTable(tableName);</span>
-<span class="source-line-no">100</span><span id="line-100">    List&lt;Put&gt; puts = IntStream.range(10, 50000).mapToObj(i -&gt; new Put(Bytes.toBytes(i))</span>
-<span class="source-line-no">101</span><span id="line-101">      .addColumn(Bytes.toBytes("fam1"), Bytes.toBytes("q1"), Bytes.toBytes("val_" + i)))</span>
-<span class="source-line-no">102</span><span id="line-102">      .collect(Collectors.toList());</span>
-<span class="source-line-no">103</span><span id="line-103">    table.put(puts);</span>
-<span class="source-line-no">104</span><span id="line-104">    admin.flush(tableName);</span>
-<span class="source-line-no">105</span><span id="line-105">    admin.compact(tableName);</span>
-<span class="source-line-no">106</span><span id="line-106">    Thread.sleep(3000);</span>
-<span class="source-line-no">107</span><span id="line-107">    HRegionServer hRegionServer0 = cluster.getRegionServer(0);</span>
-<span class="source-line-no">108</span><span id="line-108">    HRegionServer hRegionServer1 = cluster.getRegionServer(1);</span>
-<span class="source-line-no">109</span><span id="line-109">    HRegionServer hRegionServer2 = cluster.getRegionServer(2);</span>
-<span class="source-line-no">110</span><span id="line-110">    int numRegions0 = hRegionServer0.getNumberOfOnlineRegions();</span>
-<span class="source-line-no">111</span><span id="line-111">    int numRegions1 = hRegionServer1.getNumberOfOnlineRegions();</span>
-<span class="source-line-no">112</span><span id="line-112">    int numRegions2 = hRegionServer2.getNumberOfOnlineRegions();</span>
-<span class="source-line-no">113</span><span id="line-113"></span>
-<span class="source-line-no">114</span><span id="line-114">    hbckChore.choreForTesting();</span>
-<span class="source-line-no">115</span><span id="line-115">    HbckReport hbckReport = hbckChore.getLastReport();</span>
-<span class="source-line-no">116</span><span id="line-116">    assertEquals(0, hbckReport.getInconsistentRegions().size());</span>
-<span class="source-line-no">117</span><span id="line-117">    assertEquals(0, hbckReport.getOrphanRegionsOnFS().size());</span>
-<span class="source-line-no">118</span><span id="line-118">    assertEquals(0, hbckReport.getOrphanRegionsOnRS().size());</span>
-<span class="source-line-no">119</span><span id="line-119"></span>
-<span class="source-line-no">120</span><span id="line-120">    HRegion region0 = hRegionServer0.getRegions().get(0);</span>
-<span class="source-line-no">121</span><span id="line-121">    // move all regions from server1 to server0</span>
-<span class="source-line-no">122</span><span id="line-122">    for (HRegion region : hRegionServer1.getRegions()) {</span>
-<span class="source-line-no">123</span><span id="line-123">      TEST_UTIL.getAdmin().move(region.getRegionInfo().getEncodedNameAsBytes(), rs0);</span>
-<span class="source-line-no">124</span><span id="line-124">    }</span>
-<span class="source-line-no">125</span><span id="line-125">    TEST_UTIL.getAdmin().move(region0.getRegionInfo().getEncodedNameAsBytes());</span>
-<span class="source-line-no">126</span><span id="line-126">    HMaster master = TEST_UTIL.getHBaseCluster().getMaster();</span>
-<span class="source-line-no">127</span><span id="line-127"></span>
-<span class="source-line-no">128</span><span id="line-128">    // Ensure:</span>
-<span class="source-line-no">129</span><span id="line-129">    // 1. num of regions before and after scheduling SCP remain same</span>
-<span class="source-line-no">130</span><span id="line-130">    // 2. all procedures including SCPs are successfully completed</span>
-<span class="source-line-no">131</span><span id="line-131">    // 3. two servers have SCPs scheduled</span>
-<span class="source-line-no">132</span><span id="line-132">    TEST_UTIL.waitFor(5000, 1000, () -&gt; {</span>
-<span class="source-line-no">133</span><span id="line-133">      LOG.info("numRegions0: {} , numRegions1: {} , numRegions2: {}", numRegions0, numRegions1,</span>
-<span class="source-line-no">134</span><span id="line-134">        numRegions2);</span>
-<span class="source-line-no">135</span><span id="line-135">      LOG.info("Online regions - server0 : {} , server1: {} , server2: {}",</span>
-<span class="source-line-no">136</span><span id="line-136">        cluster.getRegionServer(0).getNumberOfOnlineRegions(),</span>
-<span class="source-line-no">137</span><span id="line-137">        cluster.getRegionServer(1).getNumberOfOnlineRegions(),</span>
-<span class="source-line-no">138</span><span id="line-138">        cluster.getRegionServer(2).getNumberOfOnlineRegions());</span>
-<span class="source-line-no">139</span><span id="line-139">      LOG.info("Num of successfully completed procedures: {} , num of all procedures: {}",</span>
-<span class="source-line-no">140</span><span id="line-140">        master.getMasterProcedureExecutor().getProcedures().stream()</span>
-<span class="source-line-no">141</span><span id="line-141">          .filter(masterProcedureEnvProcedure -&gt; masterProcedureEnvProcedure.getState()</span>
-<span class="source-line-no">142</span><span id="line-142">              == ProcedureProtos.ProcedureState.SUCCESS)</span>
-<span class="source-line-no">143</span><span id="line-143">          .count(),</span>
-<span class="source-line-no">144</span><span id="line-144">        master.getMasterProcedureExecutor().getProcedures().size());</span>
-<span class="source-line-no">145</span><span id="line-145">      LOG.info("Num of SCPs: " + master.getMasterProcedureExecutor().getProcedures().stream()</span>
-<span class="source-line-no">146</span><span id="line-146">        .filter(proc -&gt; proc instanceof ServerCrashProcedure).count());</span>
-<span class="source-line-no">147</span><span id="line-147">      return (numRegions0 + numRegions1 + numRegions2)</span>
-<span class="source-line-no">148</span><span id="line-148">          == (cluster.getRegionServer(0).getNumberOfOnlineRegions()</span>
-<span class="source-line-no">149</span><span id="line-149">            + cluster.getRegionServer(1).getNumberOfOnlineRegions()</span>
-<span class="source-line-no">150</span><span id="line-150">            + cluster.getRegionServer(2).getNumberOfOnlineRegions())</span>
-<span class="source-line-no">151</span><span id="line-151">        &amp;&amp; master.getMasterProcedureExecutor().getProcedures().stream()</span>
-<span class="source-line-no">152</span><span id="line-152">          .filter(masterProcedureEnvProcedure -&gt; masterProcedureEnvProcedure.getState()</span>
-<span class="source-line-no">153</span><span id="line-153">              == ProcedureProtos.ProcedureState.SUCCESS)</span>
-<span class="source-line-no">154</span><span id="line-154">          .count() == master.getMasterProcedureExecutor().getProcedures().size()</span>
-<span class="source-line-no">155</span><span id="line-155">        &amp;&amp; master.getMasterProcedureExecutor().getProcedures().stream()</span>
-<span class="source-line-no">156</span><span id="line-156">          .anyMatch(proc -&gt; proc instanceof ServerCrashProcedure);</span>
-<span class="source-line-no">157</span><span id="line-157">    });</span>
-<span class="source-line-no">158</span><span id="line-158"></span>
-<span class="source-line-no">159</span><span id="line-159">    // Ensure we have no inconsistent regions</span>
-<span class="source-line-no">160</span><span id="line-160">    TEST_UTIL.waitFor(5000, 1000, () -&gt; {</span>
-<span class="source-line-no">161</span><span id="line-161">      hbckChore.choreForTesting();</span>
-<span class="source-line-no">162</span><span id="line-162">      HbckReport report = hbckChore.getLastReport();</span>
-<span class="source-line-no">163</span><span id="line-163">      return report.getInconsistentRegions().isEmpty() &amp;&amp; report.getOrphanRegionsOnFS().isEmpty()</span>
-<span class="source-line-no">164</span><span id="line-164">        &amp;&amp; report.getOrphanRegionsOnRS().isEmpty();</span>
-<span class="source-line-no">165</span><span id="line-165">    });</span>
-<span class="source-line-no">166</span><span id="line-166"></span>
-<span class="source-line-no">167</span><span id="line-167">  }</span>
-<span class="source-line-no">168</span><span id="line-168"></span>
-<span class="source-line-no">169</span><span id="line-169">}</span>
+<span class="source-line-no">045</span><span id="line-45">import org.junit.jupiter.api.AfterEach;</span>
+<span class="source-line-no">046</span><span id="line-46">import org.junit.jupiter.api.BeforeAll;</span>
+<span class="source-line-no">047</span><span id="line-47">import org.junit.jupiter.api.BeforeEach;</span>
+<span class="source-line-no">048</span><span id="line-48">import org.junit.jupiter.api.Tag;</span>
+<span class="source-line-no">049</span><span id="line-49">import org.junit.jupiter.api.Test;</span>
+<span class="source-line-no">050</span><span id="line-50">import org.junit.jupiter.api.TestInfo;</span>
+<span class="source-line-no">051</span><span id="line-51">import org.slf4j.Logger;</span>
+<span class="source-line-no">052</span><span id="line-52">import org.slf4j.LoggerFactory;</span>
+<span class="source-line-no">053</span><span id="line-53"></span>
+<span class="source-line-no">054</span><span id="line-54">import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;</span>
+<span class="source-line-no">055</span><span id="line-55"></span>
+<span class="source-line-no">056</span><span id="line-56">/**</span>
+<span class="source-line-no">057</span><span id="line-57"> * Testing custom RSProcedureDispatcher to ensure retry limit can be imposed on certain errors.</span>
+<span class="source-line-no">058</span><span id="line-58"> */</span>
+<span class="source-line-no">059</span><span id="line-59">@Tag(MiscTests.TAG)</span>
+<span class="source-line-no">060</span><span id="line-60">@Tag(LargeTests.TAG)</span>
+<span class="source-line-no">061</span><span id="line-61">public class TestProcDispatcher {</span>
+<span class="source-line-no">062</span><span id="line-62"></span>
+<span class="source-line-no">063</span><span id="line-63">  private static final Logger LOG = LoggerFactory.getLogger(TestProcDispatcher.class);</span>
+<span class="source-line-no">064</span><span id="line-64"></span>
+<span class="source-line-no">065</span><span id="line-65">  private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();</span>
+<span class="source-line-no">066</span><span id="line-66">  private static ServerName rs0;</span>
+<span class="source-line-no">067</span><span id="line-67"></span>
+<span class="source-line-no">068</span><span id="line-68">  @BeforeAll</span>
+<span class="source-line-no">069</span><span id="line-69">  public static void setUpBeforeClass() throws Exception {</span>
+<span class="source-line-no">070</span><span id="line-70">    TEST_UTIL.getConfiguration().set(HBASE_MASTER_RSPROC_DISPATCHER_CLASS,</span>
+<span class="source-line-no">071</span><span id="line-71">      RSProcDispatcher.class.getName());</span>
+<span class="source-line-no">072</span><span id="line-72">    TEST_UTIL.getConfiguration().setInt(RSProcDispatcher.FAIL_FAST_LIMIT_KEY, 5);</span>
+<span class="source-line-no">073</span><span id="line-73">    TEST_UTIL.startMiniCluster(3);</span>
+<span class="source-line-no">074</span><span id="line-74">    SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();</span>
+<span class="source-line-no">075</span><span id="line-75">    rs0 = cluster.getRegionServer(0).getServerName();</span>
+<span class="source-line-no">076</span><span id="line-76">    TEST_UTIL.getAdmin().balancerSwitch(false, true);</span>
+<span class="source-line-no">077</span><span id="line-77">  }</span>
+<span class="source-line-no">078</span><span id="line-78"></span>
+<span class="source-line-no">079</span><span id="line-79">  @AfterAll</span>
+<span class="source-line-no">080</span><span id="line-80">  public static void tearDownAfterClass() throws Exception {</span>
+<span class="source-line-no">081</span><span id="line-81">    TEST_UTIL.shutdownMiniCluster();</span>
+<span class="source-line-no">082</span><span id="line-82">  }</span>
+<span class="source-line-no">083</span><span id="line-83"></span>
+<span class="source-line-no">084</span><span id="line-84">  @BeforeEach</span>
+<span class="source-line-no">085</span><span id="line-85">  public void setUp(TestInfo testInfo) throws Exception {</span>
+<span class="source-line-no">086</span><span id="line-86">    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());</span>
+<span class="source-line-no">087</span><span id="line-87">    TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(tableName)</span>
+<span class="source-line-no">088</span><span id="line-88">      .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();</span>
+<span class="source-line-no">089</span><span id="line-89">    int startKey = 0;</span>
+<span class="source-line-no">090</span><span id="line-90">    int endKey = 80000;</span>
+<span class="source-line-no">091</span><span id="line-91">    TEST_UTIL.getAdmin().createTable(tableDesc, Bytes.toBytes(startKey), Bytes.toBytes(endKey), 9);</span>
+<span class="source-line-no">092</span><span id="line-92">  }</span>
+<span class="source-line-no">093</span><span id="line-93"></span>
+<span class="source-line-no">094</span><span id="line-94">  @AfterEach</span>
+<span class="source-line-no">095</span><span id="line-95">  public void tearDown() {</span>
+<span class="source-line-no">096</span><span id="line-96">    RSProcDispatcher.stopInjecting();</span>
+<span class="source-line-no">097</span><span id="line-97">  }</span>
+<span class="source-line-no">098</span><span id="line-98"></span>
+<span class="source-line-no">099</span><span id="line-99">  @Test</span>
+<span class="source-line-no">100</span><span id="line-100">  public void testRetryLimitOnConnClosedErrors(TestInfo testInfo) throws Exception {</span>
+<span class="source-line-no">101</span><span id="line-101">    HbckChore hbckChore = new HbckChore(TEST_UTIL.getHBaseCluster().getMaster());</span>
+<span class="source-line-no">102</span><span id="line-102">    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());</span>
+<span class="source-line-no">103</span><span id="line-103">    SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();</span>
+<span class="source-line-no">104</span><span id="line-104">    Admin admin = TEST_UTIL.getAdmin();</span>
+<span class="source-line-no">105</span><span id="line-105">    List&lt;Put&gt; puts = IntStream.range(10, 50000).mapToObj(i -&gt; new Put(Bytes.toBytes(i))</span>
+<span class="source-line-no">106</span><span id="line-106">      .addColumn(Bytes.toBytes("fam1"), Bytes.toBytes("q1"), Bytes.toBytes("val_" + i)))</span>
+<span class="source-line-no">107</span><span id="line-107">      .collect(Collectors.toList());</span>
+<span class="source-line-no">108</span><span id="line-108">    try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {</span>
+<span class="source-line-no">109</span><span id="line-109">      table.put(puts);</span>
+<span class="source-line-no">110</span><span id="line-110">    }</span>
+<span class="source-line-no">111</span><span id="line-111">    admin.flush(tableName);</span>
+<span class="source-line-no">112</span><span id="line-112">    admin.compact(tableName);</span>
+<span class="source-line-no">113</span><span id="line-113">    Thread.sleep(3000);</span>
+<span class="source-line-no">114</span><span id="line-114">    HRegionServer hRegionServer0 = cluster.getRegionServer(0);</span>
+<span class="source-line-no">115</span><span id="line-115">    HRegionServer hRegionServer1 = cluster.getRegionServer(1);</span>
+<span class="source-line-no">116</span><span id="line-116">    HRegionServer hRegionServer2 = cluster.getRegionServer(2);</span>
+<span class="source-line-no">117</span><span id="line-117">    int numRegions0 = hRegionServer0.getNumberOfOnlineRegions();</span>
+<span class="source-line-no">118</span><span id="line-118">    int numRegions1 = hRegionServer1.getNumberOfOnlineRegions();</span>
+<span class="source-line-no">119</span><span id="line-119">    int numRegions2 = hRegionServer2.getNumberOfOnlineRegions();</span>
+<span class="source-line-no">120</span><span id="line-120"></span>
+<span class="source-line-no">121</span><span id="line-121">    hbckChore.choreForTesting();</span>
+<span class="source-line-no">122</span><span id="line-122">    HbckReport hbckReport = hbckChore.getLastReport();</span>
+<span class="source-line-no">123</span><span id="line-123">    assertEquals(0, hbckReport.getInconsistentRegions().size());</span>
+<span class="source-line-no">124</span><span id="line-124">    assertEquals(0, hbckReport.getOrphanRegionsOnFS().size());</span>
+<span class="source-line-no">125</span><span id="line-125">    assertEquals(0, hbckReport.getOrphanRegionsOnRS().size());</span>
+<span class="source-line-no">126</span><span id="line-126"></span>
+<span class="source-line-no">127</span><span id="line-127">    HRegion region0 = hRegionServer0.getRegions().get(0);</span>
+<span class="source-line-no">128</span><span id="line-128">    // Fail the next two open/close-region requests for this table so the moves trigger SCP(s).</span>
+<span class="source-line-no">129</span><span id="line-129">    RSProcDispatcher.injectErrorsForNextRequests(tableName, 2);</span>
+<span class="source-line-no">130</span><span id="line-130">    // move all regions from server1 to server0</span>
+<span class="source-line-no">131</span><span id="line-131">    for (HRegion region : hRegionServer1.getRegions()) {</span>
+<span class="source-line-no">132</span><span id="line-132">      TEST_UTIL.getAdmin().move(region.getRegionInfo().getEncodedNameAsBytes(), rs0);</span>
+<span class="source-line-no">133</span><span id="line-133">    }</span>
+<span class="source-line-no">134</span><span id="line-134">    TEST_UTIL.getAdmin().move(region0.getRegionInfo().getEncodedNameAsBytes());</span>
+<span class="source-line-no">135</span><span id="line-135">    HMaster master = TEST_UTIL.getHBaseCluster().getMaster();</span>
+<span class="source-line-no">136</span><span id="line-136"></span>
+<span class="source-line-no">137</span><span id="line-137">    // Ensure, after the injected connection errors:</span>
+<span class="source-line-no">138</span><span id="line-138">    // 1. the total number of regions is unchanged before and after the SCP(s)</span>
+<span class="source-line-no">139</span><span id="line-139">    // 2. all procedures (including the SCP(s)) complete successfully</span>
+<span class="source-line-no">140</span><span id="line-140">    // 3. at least one ServerCrashProcedure was scheduled</span>
+<span class="source-line-no">141</span><span id="line-141">    TEST_UTIL.waitFor(60000, 1000, () -&gt; {</span>
+<span class="source-line-no">142</span><span id="line-142">      LOG.info("numRegions0: {} , numRegions1: {} , numRegions2: {}", numRegions0, numRegions1,</span>
+<span class="source-line-no">143</span><span id="line-143">        numRegions2);</span>
+<span class="source-line-no">144</span><span id="line-144">      LOG.info("Online regions - server0 : {} , server1: {} , server2: {}",</span>
+<span class="source-line-no">145</span><span id="line-145">        cluster.getRegionServer(0).getNumberOfOnlineRegions(),</span>
+<span class="source-line-no">146</span><span id="line-146">        cluster.getRegionServer(1).getNumberOfOnlineRegions(),</span>
+<span class="source-line-no">147</span><span id="line-147">        cluster.getRegionServer(2).getNumberOfOnlineRegions());</span>
+<span class="source-line-no">148</span><span id="line-148">      LOG.info("Num of successfully completed procedures: {} , num of all procedures: {}",</span>
+<span class="source-line-no">149</span><span id="line-149">        master.getMasterProcedureExecutor().getProcedures().stream()</span>
+<span class="source-line-no">150</span><span id="line-150">          .filter(masterProcedureEnvProcedure -&gt; masterProcedureEnvProcedure.getState()</span>
+<span class="source-line-no">151</span><span id="line-151">              == ProcedureProtos.ProcedureState.SUCCESS)</span>
+<span class="source-line-no">152</span><span id="line-152">          .count(),</span>
+<span class="source-line-no">153</span><span id="line-153">        master.getMasterProcedureExecutor().getProcedures().size());</span>
+<span class="source-line-no">154</span><span id="line-154">      LOG.info("Num of SCPs: {}", master.getMasterProcedureExecutor().getProcedures().stream()</span>
+<span class="source-line-no">155</span><span id="line-155">        .filter(proc -&gt; proc instanceof ServerCrashProcedure).count());</span>
+<span class="source-line-no">156</span><span id="line-156">      return (numRegions0 + numRegions1 + numRegions2)</span>
+<span class="source-line-no">157</span><span id="line-157">          == (cluster.getRegionServer(0).getNumberOfOnlineRegions()</span>
+<span class="source-line-no">158</span><span id="line-158">            + cluster.getRegionServer(1).getNumberOfOnlineRegions()</span>
+<span class="source-line-no">159</span><span id="line-159">            + cluster.getRegionServer(2).getNumberOfOnlineRegions())</span>
+<span class="source-line-no">160</span><span id="line-160">        &amp;&amp; master.getMasterProcedureExecutor().getProcedures().stream()</span>
+<span class="source-line-no">161</span><span id="line-161">          .filter(masterProcedureEnvProcedure -&gt; masterProcedureEnvProcedure.getState()</span>
+<span class="source-line-no">162</span><span id="line-162">              == ProcedureProtos.ProcedureState.SUCCESS)</span>
+<span class="source-line-no">163</span><span id="line-163">          .count() == master.getMasterProcedureExecutor().getProcedures().size()</span>
+<span class="source-line-no">164</span><span id="line-164">        &amp;&amp; master.getMasterProcedureExecutor().getProcedures().stream()</span>
+<span class="source-line-no">165</span><span id="line-165">          .anyMatch(proc -&gt; proc instanceof ServerCrashProcedure);</span>
+<span class="source-line-no">166</span><span id="line-166">    });</span>
+<span class="source-line-no">167</span><span id="line-167"></span>
+<span class="source-line-no">168</span><span id="line-168">    // Ensure we have no inconsistent regions</span>
+<span class="source-line-no">169</span><span id="line-169">    TEST_UTIL.waitFor(60000, 1000, () -&gt; {</span>
+<span class="source-line-no">170</span><span id="line-170">      hbckChore.choreForTesting();</span>
+<span class="source-line-no">171</span><span id="line-171">      HbckReport report = hbckChore.getLastReport();</span>
+<span class="source-line-no">172</span><span id="line-172">      return report.getInconsistentRegions().isEmpty() &amp;&amp; report.getOrphanRegionsOnFS().isEmpty()</span>
+<span class="source-line-no">173</span><span id="line-173">        &amp;&amp; report.getOrphanRegionsOnRS().isEmpty();</span>
+<span class="source-line-no">174</span><span id="line-174">    });</span>
+<span class="source-line-no">175</span><span id="line-175">  }</span>
+<span class="source-line-no">176</span><span id="line-176">}</span>