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/06/22 23:56:03 UTC

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

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 ec1bacfc326 Published site at c726596ae6d8ce0abe09f92a0cd631725c5d58a8.
ec1bacfc326 is described below

commit ec1bacfc326209de4ddb4ba9ef770288b8c30946
Author: HBase <de...@hbase.apache.org>
AuthorDate: Mon Jun 22 23:50:12 2026 +0000

    Published site at c726596ae6d8ce0abe09f92a0cd631725c5d58a8.
---
 apidocs/allclasses-index.html                      |    6 +
 apidocs/index-all.html                             |  146 +-
 apidocs/member-search-index.js                     |    2 +-
 apidocs/org/apache/hadoop/hbase/UserMetrics.html   |   14 +-
 .../hbase/class-use/ExtendedCellScanner.html       |   56 +-
 .../apache/hadoop/hbase/codec/class-use/Codec.html |    5 +
 .../hbase/ipc/class-use/RpcServer.CallCleanup.html |   23 +-
 .../hadoop/hbase/ipc/class-use/RpcServer.html      |   18 +
 .../hadoop/hbase/ipc/class-use/ServerCall.html     |   18 +
 .../ServerRpcConnection.PreambleResponse.html}     |   31 +-
 .../{ServerCall.html => ServerRpcConnection.html}  |   49 +-
 .../apache/hadoop/hbase/ipc/package-summary.html   |    8 +-
 .../org/apache/hadoop/hbase/ipc/package-tree.html  |   15 +
 .../org/apache/hadoop/hbase/ipc/package-use.html   |    6 +
 .../hadoop/hbase/nio/class-use/ByteBuff.html       |   32 +-
 .../org/apache/hadoop/hbase/nio/package-use.html   |   26 +-
 .../class-use/MetricsUserSource.ClientMetrics.html |   12 +-
 .../security/class-use/HBaseSaslRpcServer.html     |   29 +-
 .../hbase/security/class-use/SaslStatus.html       |   27 +-
 .../hadoop/hbase/security/class-use/User.html      |    3 +
 .../apache/hadoop/hbase/security/package-use.html  |    6 +
 apidocs/overview-tree.html                         |    2 +
 .../hadoop/hbase/UserMetrics.ClientMetrics.html    |   62 +-
 .../org/apache/hadoop/hbase/UserMetrics.html       |   62 +-
 .../UserMetricsBuilder.ClientMetricsImpl.html      |  272 +-
 .../apache/hadoop/hbase/UserMetricsBuilder.html    |  272 +-
 .../org/apache/hadoop/hbase/hbtop/field/Field.html |   64 +-
 .../hbase/hbtop/mode/ClientModeStrategy.html       |  222 +-
 .../ipc/RpcServer.BlockingServiceAndInterface.html |  214 +-
 .../hadoop/hbase/ipc/RpcServer.CallCleanup.html    |  214 +-
 .../org/apache/hadoop/hbase/ipc/RpcServer.html     |  214 +-
 .../org/apache/hadoop/hbase/ipc/ServerCall.html    |  696 +-
 .../ipc/ServerRpcConnection.PreambleResponse.html  |  742 +--
 .../hadoop/hbase/ipc/ServerRpcConnection.html      |  742 +--
 .../hadoop/hbase/regionserver/HRegionServer.html   | 4076 ++++++------
 .../regionserver/MetricsUserAggregateImpl.html     |  324 +-
 .../MetricsUserSource.ClientMetrics.html           |   71 +-
 .../hbase/regionserver/MetricsUserSource.html      |   71 +-
 .../hbase/regionserver/MetricsUserSourceImpl.html  |  460 +-
 apidocs/type-search-index.js                       |    2 +-
 books/apache-hbase-reference-guide-dark-mode.pdf   |  Bin 38919225 -> 38919224 bytes
 books/apache-hbase-reference-guide.pdf             |  Bin 38809477 -> 38809487 bytes
 checkstyle-aggregate.html                          |   16 +-
 dependency-convergence.html                        |    2 +-
 dependency-info.html                               |    2 +-
 dependency-management.html                         |    2 +-
 devapidocs/allclasses-index.html                   | 6874 ++++++++++----------
 devapidocs/index-all.html                          |   91 +-
 devapidocs/member-search-index.js                  |    2 +-
 .../hadoop/hbase/UserMetrics.ClientMetrics.html    |   40 +-
 .../org/apache/hadoop/hbase/UserMetrics.html       |   14 +-
 .../UserMetricsBuilder.ClientMetricsImpl.html      |  132 +-
 .../hbase/UserMetricsBuilder.UserMetricsImpl.html  |   20 +-
 .../apache/hadoop/hbase/UserMetricsBuilder.html    |   14 +-
 .../org/apache/hadoop/hbase/hbtop/field/Field.html |   80 +-
 .../hbase/hbtop/mode/ClientModeStrategy.html       |   18 +-
 .../apache/hadoop/hbase/ipc/NettyRpcServer.html    |    2 +-
 .../apache/hadoop/hbase/ipc/NettyServerCall.html   |    2 +-
 .../hadoop/hbase/ipc/NettyServerRpcConnection.html |    2 +-
 .../org/apache/hadoop/hbase/ipc/RpcServer.html     |  250 +-
 .../org/apache/hadoop/hbase/ipc/ServerCall.html    |  268 +-
 .../ipc/ServerRpcConnection.ByteBuffByteInput.html |   18 +-
 .../ipc/ServerRpcConnection.PreambleResponse.html  |   14 +-
 .../hadoop/hbase/ipc/ServerRpcConnection.html      |  133 +-
 .../apache/hadoop/hbase/ipc/SimpleRpcServer.html   |    2 +-
 .../apache/hadoop/hbase/ipc/SimpleServerCall.html  |   15 +-
 .../hbase/ipc/SimpleServerRpcConnection.html       |    2 +-
 .../hbase/ipc/class-use/ServerRpcConnection.html   |   12 +
 .../ipc/class-use/SimpleServerRpcConnection.html   |    2 +-
 .../HRegionServer.CompactionChecker.html           |   14 +-
 .../HRegionServer.MovedRegionInfo.html             |   12 +-
 .../HRegionServer.PeriodicMemStoreFlusher.html     |   14 +-
 .../HRegionServer.SystemExitWhenAbortTimeout.html  |    6 +-
 .../hadoop/hbase/regionserver/HRegionServer.html   |  232 +-
 ...UserAggregateImpl.ClientConnectionContext.html} |  117 +-
 .../regionserver/MetricsUserAggregateImpl.html     |  118 +-
 .../MetricsUserSource.ClientMetrics.html           |   40 +-
 .../hbase/regionserver/MetricsUserSource.html      |   40 +-
 .../MetricsUserSourceImpl.ClientMetricsImpl.html   |  124 +-
 .../hbase/regionserver/MetricsUserSourceImpl.html  |   54 +-
 ...sUserAggregateImpl.ClientConnectionContext.html |   25 +-
 .../class-use/MetricsUserSource.ClientMetrics.html |   12 +-
 .../hadoop/hbase/regionserver/package-summary.html |  576 +-
 .../hadoop/hbase/regionserver/package-tree.html    |    1 +
 .../hadoop/hbase/regionserver/package-use.html     |  364 +-
 devapidocs/overview-tree.html                      |    1 +
 .../hadoop/hbase/UserMetrics.ClientMetrics.html    |   62 +-
 .../org/apache/hadoop/hbase/UserMetrics.html       |   62 +-
 .../UserMetricsBuilder.ClientMetricsImpl.html      |  272 +-
 .../hbase/UserMetricsBuilder.UserMetricsImpl.html  |  272 +-
 .../apache/hadoop/hbase/UserMetricsBuilder.html    |  272 +-
 .../org/apache/hadoop/hbase/hbtop/field/Field.html |   64 +-
 .../hbase/hbtop/mode/ClientModeStrategy.html       |  222 +-
 .../ipc/RpcServer.BlockingServiceAndInterface.html |  214 +-
 .../hadoop/hbase/ipc/RpcServer.CallCleanup.html    |  214 +-
 .../org/apache/hadoop/hbase/ipc/RpcServer.html     |  214 +-
 .../org/apache/hadoop/hbase/ipc/ServerCall.html    |  696 +-
 .../ipc/ServerRpcConnection.ByteBuffByteInput.html |  742 +--
 .../ipc/ServerRpcConnection.PreambleResponse.html  |  742 +--
 .../hadoop/hbase/ipc/ServerRpcConnection.html      |  742 +--
 .../apache/hadoop/hbase/ipc/SimpleServerCall.html  |    9 +-
 .../HRegionServer.CompactionChecker.html           | 4076 ++++++------
 .../HRegionServer.MovedRegionInfo.html             | 4076 ++++++------
 .../HRegionServer.PeriodicMemStoreFlusher.html     | 4076 ++++++------
 .../HRegionServer.SystemExitWhenAbortTimeout.html  | 4076 ++++++------
 .../hadoop/hbase/regionserver/HRegionServer.html   | 4076 ++++++------
 ...sUserAggregateImpl.ClientConnectionContext.html |  330 +
 .../regionserver/MetricsUserAggregateImpl.html     |  324 +-
 .../MetricsUserSource.ClientMetrics.html           |   71 +-
 .../hbase/regionserver/MetricsUserSource.html      |   71 +-
 .../MetricsUserSourceImpl.ClientMetricsImpl.html   |  460 +-
 .../hbase/regionserver/MetricsUserSourceImpl.html  |  460 +-
 devapidocs/type-search-index.js                    |    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/allclasses-index.html                  | 3840 +++++------
 testapidocs/index-all.html                         |  110 +-
 testapidocs/member-search-index.js                 |    2 +-
 .../class-use/HBaseParameterizedTestTemplate.html  |   68 +-
 .../hadoop/hbase/class-use/HBaseTestingUtil.html   |   11 +-
 .../hbase/class-use/TestUserMetricsBuilder.html    |   32 +-
 .../org/apache/hadoop/hbase/package-summary.html   |   28 +-
 .../org/apache/hadoop/hbase/package-tree.html      |    1 +
 .../class-use/MajorCompactionTestBase.html}        |   34 +-
 .../TestMajorCompactionDataBlockEncoding.html      |   10 +-
 .../class-use/TestMajorCompactionRequest.html      |   10 +-
 .../class-use/TestMajorCompactionWithDeletes.html  |   10 +-
 .../class-use/TestTimeBasedMajorCompaction.html    |   10 +-
 .../hadoop/hbase/regionserver/package-summary.html |  414 +-
 .../hadoop/hbase/regionserver/package-tree.html    |   10 +-
 .../hadoop/hbase/regionserver/package-use.html     |   42 +-
 .../class-use/SyncReplicationTestBase.html         |    5 +-
 ...SyncReplicationStandbyKillMaster.TransitCP.html |   10 +-
 .../hadoop/hbase/replication/package-summary.html  |   38 +-
 .../hadoop/hbase/replication/package-tree.html     |    3 +-
 testapidocs/overview-tree.html                     |   14 +-
 .../hadoop/hbase/TestUserMetricsBuilder.html       |  132 +
 .../org/apache/hadoop/hbase/hbtop/TestUtils.html   |  815 +--
 .../regionserver/MajorCompactionTestBase.html      |  326 +
 .../hbase/regionserver/TestMajorCompaction.html    |  557 +-
 .../TestMajorCompactionDataBlockEncoding.html      |  146 +
 .../regionserver/TestMajorCompactionRequest.html   |  156 +
 .../TestMajorCompactionWithDeletes.html            |  180 +
 .../regionserver/TestTimeBasedMajorCompaction.html |  168 +
 ...SyncReplicationStandbyKillMaster.TransitCP.html |  192 +
 .../TestSyncReplicationStandbyKillMaster.html      |  157 +-
 testapidocs/type-search-index.js                   |    2 +-
 testdevapidocs/allclasses-index.html               | 5542 ++++++++--------
 testdevapidocs/constant-values.html                |   55 +-
 testdevapidocs/index-all.html                      |  238 +-
 testdevapidocs/member-search-index.js              |    2 +-
 .../hadoop/hbase/TestUserMetricsBuilder.html       |   74 +-
 .../class-use/HBaseParameterizedTestTemplate.html  |   68 +-
 .../hadoop/hbase/class-use/HBaseTestingUtil.html   |   40 +-
 .../hbase/class-use/TestUserMetricsBuilder.html    |   32 +-
 .../org/apache/hadoop/hbase/hbtop/TestUtils.html   |  192 +-
 ...C.FailingSimpleRpcServer.FailingConnection.html |  438 +-
 .../AbstractTestIPC.FailingSimpleRpcServer.html    |    2 +-
 .../FailingNettyRpcServer.FailingConnection.html   |  410 +-
 .../hadoop/hbase/ipc/FailingNettyRpcServer.html    |    2 +-
 .../org/apache/hadoop/hbase/ipc/package-tree.html  |    8 +-
 .../hbase/master/http/TestMasterStatusPage.html    |    6 +-
 .../org/apache/hadoop/hbase/package-summary.html   |   38 +-
 .../org/apache/hadoop/hbase/package-tree.html      |    1 +
 .../regionserver/MajorCompactionTestBase.html      |  445 ++
 .../hbase/regionserver/TestMajorCompaction.html    |  451 +-
 .../TestMajorCompactionDataBlockEncoding.html      |  155 +-
 .../regionserver/TestMajorCompactionRequest.html   |  113 +-
 .../TestMajorCompactionWithDeletes.html            |  168 +-
 .../regionserver/TestTimeBasedMajorCompaction.html |   65 +-
 .../class-use/MajorCompactionTestBase.html         |   34 +-
 .../TestMajorCompactionDataBlockEncoding.html      |   10 +-
 .../class-use/TestMajorCompactionRequest.html      |   10 +-
 .../class-use/TestMajorCompactionWithDeletes.html  |   10 +-
 .../class-use/TestTimeBasedMajorCompaction.html    |   10 +-
 .../hadoop/hbase/regionserver/package-summary.html |  546 +-
 .../hadoop/hbase/regionserver/package-tree.html    |   10 +-
 .../hadoop/hbase/regionserver/package-use.html     |  116 +-
 .../hbase/replication/SyncReplicationTestBase.html |    2 +-
 .../SyncReplicationTestBaseNoBeforeAll.html        |    2 +-
 ...SyncReplicationStandbyKillMaster.TransitCP.html |  220 +
 .../TestSyncReplicationStandbyKillMaster.html      |   87 +-
 .../class-use/SyncReplicationTestBase.html         |    5 +-
 ...SyncReplicationStandbyKillMaster.TransitCP.html |   10 +-
 .../hadoop/hbase/replication/package-summary.html  |   38 +-
 .../hadoop/hbase/replication/package-tree.html     |    3 +-
 testdevapidocs/overview-tree.html                  |   22 +-
 .../hadoop/hbase/TestUserMetricsBuilder.html       |  132 +
 .../org/apache/hadoop/hbase/hbtop/TestUtils.html   |  815 +--
 .../hbase/master/http/TestMasterStatusPage.html    |   81 +-
 .../regionserver/MajorCompactionTestBase.html      |  326 +
 .../hbase/regionserver/TestMajorCompaction.html    |  557 +-
 .../TestMajorCompactionDataBlockEncoding.html      |  146 +
 .../regionserver/TestMajorCompactionRequest.html   |  156 +
 .../TestMajorCompactionWithDeletes.html            |  180 +
 .../regionserver/TestTimeBasedMajorCompaction.html |  168 +
 ...SyncReplicationStandbyKillMaster.TransitCP.html |  192 +
 .../TestSyncReplicationStandbyKillMaster.html      |  157 +-
 testdevapidocs/type-search-index.js                |    2 +-
 220 files changed, 34828 insertions(+), 31333 deletions(-)

diff --git a/apidocs/allclasses-index.html b/apidocs/allclasses-index.html
index 705e2c92af4..736c855fc8b 100644
--- a/apidocs/allclasses-index.html
+++ b/apidocs/allclasses-index.html
@@ -6742,6 +6742,12 @@ loadScripts(document, 'script');</script>
 <div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Similar to <code>RegionReplicaUtil</code> but for the server side</div>
 </div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2">org.apache.hadoop.hbase.ipc.ServerRpcConnection</div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="block">Reads calls from a connection and queues them for handling.</div>
+</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab3">org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab3">&nbsp;</div>
 <div class="col-first even-row-color all-classes-table all-classes-table-tab2">org.apache.hadoop.hbase.ipc.ServerRpcController</div>
 <div class="col-last even-row-color all-classes-table all-classes-table-tab2">
 <div class="block">Used for server-side protobuf RPC service invocations.</div>
diff --git a/apidocs/index-all.html b/apidocs/index-all.html
index 559a3be5ed6..e0d33341bf3 100644
--- a/apidocs/index-all.html
+++ b/apidocs/index-all.html
@@ -1115,6 +1115,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>addr - Variable in class org.apache.hadoop.hbase.ipc.AbstractRpcClient.RpcChannelImplementation</dt>
 <dd>&nbsp;</dd>
+<dt>addr - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>addReaderThreads(int) - Method in class org.apache.hadoop.hbase.util.MultiThreadedReader</dt>
 <dd>&nbsp;</dd>
 <dt>addReaderThreads(int) - Method in class org.apache.hadoop.hbase.util.MultiThreadedReaderWithACL</dt>
@@ -2506,6 +2508,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>AUTH_SUCCESSFUL_FOR - Static variable in class org.apache.hadoop.hbase.ipc.RpcServer</dt>
 <dd>&nbsp;</dd>
+<dt>authenticatedWithFallback - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>AUTHENTICATION - Enum constant in enum class org.apache.hadoop.hbase.security.SaslUtil.QualityOfProtection</dt>
 <dd>&nbsp;</dd>
 <dt>AUTHENTICATION - Static variable in class org.apache.hadoop.hbase.HBaseInterfaceAudience</dt>
@@ -5322,6 +5326,10 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>CallCancelledException(String) - Constructor for exception org.apache.hadoop.hbase.ipc.CallCancelledException</dt>
 <dd>&nbsp;</dd>
+<dt>callCleanup - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
+<dt>callCleanupIfNeeded() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>callDroppedException() - Method in interface org.apache.hadoop.hbase.metrics.ExceptionTrackingSource</dt>
 <dd>&nbsp;</dd>
 <dt>callDroppedException() - Method in class org.apache.hadoop.hbase.metrics.ExceptionTrackingSourceImpl</dt>
@@ -7175,6 +7183,8 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Set this key to <code>true</code> to enable table metrics collection of client requests.</div>
 </dd>
+<dt>CLIENT_VERSION - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
+<dd>&nbsp;</dd>
 <dt>CLIENT_ZOOKEEPER_CLIENT_PORT - Static variable in class org.apache.hadoop.hbase.HConstants</dt>
 <dd>
 <div class="block">Client port of ZooKeeper for client to locate meta</div>
@@ -7202,6 +7212,8 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>clientCertificateChain - Variable in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
 <dd>&nbsp;</dd>
+<dt>clientCertificateChain - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>clientChannelClass() - Method in class org.apache.hadoop.hbase.util.NettyEventLoopGroupConfig</dt>
 <dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.client.ClientCoprocessorRpcController - Class in <a href="org/apache/hadoop/hbase/client/package-summary.html">org.apache.hadoop.hbase.client</a></dt>
@@ -7245,7 +7257,7 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Implementations 'visit' a catalog table row.</div>
 </dd>
-<dt>ClientMetricsImpl(String, long, long, long) - Constructor for class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dt>ClientMetricsImpl(String, long, long, long, String, String, String, String) - Constructor for class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
 <dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.hbtop.mode.ClientModeStrategy - Class in <a href="org/apache/hadoop/hbase/hbtop/mode/package-summary.html">org.apache.hadoop.hbase.hbtop.mode</a></dt>
 <dd>
@@ -7718,6 +7730,8 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Closes the writer, in this case flush table commits.</div>
 </dd>
+<dt>CLOSE - Enum constant in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd>&nbsp;</dd>
 <dt>CLOSE_METRIC_PREFIX - Static variable in interface org.apache.hadoop.hbase.master.MetricsAssignmentManagerSource</dt>
 <dd>&nbsp;</dd>
 <dt>CLOSE_WAIT_ABORT - Static variable in class org.apache.hadoop.hbase.regionserver.HRegion</dt>
@@ -8039,6 +8053,10 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>codec - Variable in class org.apache.hadoop.hbase.ipc.AbstractRpcClient</dt>
 <dd>&nbsp;</dd>
+<dt>codec - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>
+<div class="block">Codec the client asked use.</div>
+</dd>
 <dt>org.apache.hadoop.hbase.codec.Codec - Interface in <a href="org/apache/hadoop/hbase/codec/package-summary.html">org.apache.hadoop.hbase.codec</a></dt>
 <dd>
 <div class="block">Encoder/Decoder for Cell.</div>
@@ -9245,6 +9263,10 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>compressionByName(String) - Static method in class org.apache.hadoop.hbase.io.hfile.HFileWriterImpl</dt>
 <dd>&nbsp;</dd>
+<dt>compressionCodec - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>
+<div class="block">Compression codec the client asked us use.</div>
+</dd>
 <dt>compressionContext - Variable in class org.apache.hadoop.hbase.regionserver.wal.AbstractProtobufLogWriter</dt>
 <dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.regionserver.wal.CompressionContext - Class in <a href="org/apache/hadoop/hbase/regionserver/wal/package-summary.html">org.apache.hadoop.hbase.regionserver.wal</a></dt>
@@ -9677,6 +9699,8 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>connectionAttributes - Variable in class org.apache.hadoop.hbase.ipc.AbstractRpcClient</dt>
 <dd>&nbsp;</dd>
+<dt>connectionAttributes - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>connectionCache - Variable in class org.apache.hadoop.hbase.thrift.HBaseServiceHandler</dt>
 <dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.util.ConnectionCache - Class in <a href="org/apache/hadoop/hbase/util/package-summary.html">org.apache.hadoop.hbase.util</a></dt>
@@ -9722,6 +9746,10 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">No public c.tors</div>
 </dd>
+<dt>connectionHeader - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
+<dt>connectionHeaderRead - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.client.ConnectionRegistry - Interface in <a href="org/apache/hadoop/hbase/client/package-summary.html">org.apache.hadoop.hbase.client</a></dt>
 <dd>
 <div class="block">Registry for meta information needed for connection setup to a HBase cluster.</div>
@@ -9979,6 +10007,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>CONTEXT - Static variable in interface org.apache.hadoop.hbase.rest.MetricsRESTSource</dt>
 <dd>&nbsp;</dd>
+<dt>CONTINUE - Enum constant in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd>&nbsp;</dd>
 <dt>control(String, long) - Method in class org.apache.hadoop.hbase.regionserver.throttle.NoLimitThroughputController</dt>
 <dd>&nbsp;</dd>
 <dt>control(String, long) - Method in class org.apache.hadoop.hbase.regionserver.throttle.PressureAwareThroughputController</dt>
@@ -11023,6 +11053,8 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Creates the cache config.</div>
 </dd>
+<dt>createCall(int, BlockingService, Descriptors.MethodDescriptor, RPCProtos.RequestHeader, Message, ExtendedCellScanner, long, InetAddress, int, RpcServer.CallCleanup) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>createCell(byte[], int, int) - Method in class org.apache.hadoop.hbase.codec.KeyValueCodec.ByteBuffKeyValueDecoder</dt>
 <dd>&nbsp;</dd>
 <dt>createCell(byte[], int, int) - Method in class org.apache.hadoop.hbase.codec.KeyValueCodecWithTags.ByteBuffKeyValueDecoder</dt>
@@ -15546,6 +15578,8 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>dispose(T) - Method in class org.apache.hadoop.hbase.http.jersey.SupplierFactoryAdapter</dt>
 <dd>&nbsp;</dd>
+<dt>disposeSasl() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>divideForAvg(S, Long) - Method in class org.apache.hadoop.hbase.coprocessor.ColumnInterpreter</dt>
 <dd>
 <div class="block">used for computing average of &lt;S&gt; data values.</div>
@@ -15771,6 +15805,10 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>doPost(HttpServletRequest, HttpServletResponse) - Method in class org.apache.hadoop.hbase.thrift.ThriftHttpServlet</dt>
 <dd>&nbsp;</dd>
+<dt>doRawSaslReply(SaslStatus, Writable, String, String) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>
+<div class="block">No protobuf encoding of raw sasl messages</div>
+</dd>
 <dt>doRealSeek(KeyValueScanner, ExtendedCell, boolean) - Static method in class org.apache.hadoop.hbase.regionserver.NonLazyKeyValueScanner</dt>
 <dd>&nbsp;</dd>
 <dt>doRegionCompactionPrep() - Method in class org.apache.hadoop.hbase.regionserver.HRegion</dt>
@@ -15792,6 +15830,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>doResizeIfNecessary() - Method in interface org.apache.hadoop.hbase.hbtop.terminal.Terminal</dt>
 <dd>&nbsp;</dd>
+<dt>doRespond(RpcResponse) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>doSetup(Mapper.Context) - Method in class org.apache.hadoop.hbase.mapreduce.TsvImporterMapper</dt>
 <dd>
 <div class="block">Handles common parameter initialization that a subclass might want to leverage.</div>
@@ -22350,6 +22390,12 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Get the list of client ports.</div>
 </dd>
+<dt>getClientVersion() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</dt>
+<dd>&nbsp;</dd>
+<dt>getClientVersion() - Method in interface org.apache.hadoop.hbase.UserMetrics.ClientMetrics</dt>
+<dd>&nbsp;</dd>
+<dt>getClientVersion() - Method in class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dd>&nbsp;</dd>
 <dt>getClientVersionInfo() - Method in interface org.apache.hadoop.hbase.ipc.RpcCallContext</dt>
 <dd>
 <div class="block">Returns the client version info, or null if the information is not present</div>
@@ -23117,6 +23163,10 @@ loadScripts(document, 'script');</script>
 <div class="deprecation-block"><span class="deprecated-label">Deprecated.</span></div>
 <div class="block">Get a shared Connection to the cluster.</div>
 </dd>
+<dt>getConnection() - Method in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
+<dd>
+<div class="block">Get the ServerRpcConnection associated with this call.</div>
+</dd>
 <dt>getConnection() - Method in class org.apache.hadoop.hbase.MockRegionServerServices</dt>
 <dd>&nbsp;</dd>
 <dt>getConnection() - Method in interface org.apache.hadoop.hbase.Server</dt>
@@ -23159,6 +23209,8 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">For test only.</div>
 </dd>
+<dt>getConnectionHeader() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>getConnectionRegistry() - Method in class org.apache.hadoop.hbase.client.AsyncConnectionImpl</dt>
 <dd>&nbsp;</dd>
 <dt>getConnectionString() - Method in interface org.apache.hadoop.hbase.client.ConnectionRegistry</dt>
@@ -23459,6 +23511,11 @@ loadScripts(document, 'script');</script>
 <div class="block">Just return the current rpc call if it is a <code>ServerCall</code> and also has <code>CellScanner</code>
  attached.</div>
 </dd>
+<dt>getCurrentServerRpcConnection() - Static method in class org.apache.hadoop.hbase.ipc.RpcServer</dt>
+<dd>
+<div class="block">Returns the ServerRpcConnection for the current RPC request or not present if no connection is
+ available.</div>
+</dd>
 <dt>getCurrentSize() - Method in interface org.apache.hadoop.hbase.io.hfile.BlockCache</dt>
 <dd>
 <div class="block">Returns the occupied size of the block cache, in bytes.</div>
@@ -24384,6 +24441,8 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Returns the Bloom filter error rate in the given configuration</div>
 </dd>
+<dt>getErrorResponse(String, Exception) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>getErrors() - Method in class org.apache.hadoop.hbase.util.HBaseFsck</dt>
 <dd>
 <div class="deprecation-block"><span class="deprecated-label">Deprecated.</span></div>
@@ -25779,10 +25838,20 @@ loadScripts(document, 'script');</script>
 <dd>
 <div class="block">Returns the host name</div>
 </dd>
+<dt>getHostAddress() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
+<dt>getHostAddress() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</dt>
+<dd>&nbsp;</dd>
+<dt>getHostAddress() - Method in interface org.apache.hadoop.hbase.UserMetrics.ClientMetrics</dt>
+<dd>&nbsp;</dd>
+<dt>getHostAddress() - Method in class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dd>&nbsp;</dd>
 <dt>getHostAndWeights() - Method in class org.apache.hadoop.hbase.HDFSBlocksDistribution</dt>
 <dd>
 <div class="block">Returns the hosts and their weights</div>
 </dd>
+<dt>getHostInetAddress() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>getHostname() - Method in exception org.apache.hadoop.hbase.exceptions.RegionMovedException</dt>
 <dd>&nbsp;</dd>
 <dt>getHostname() - Method in class org.apache.hadoop.hbase.HRegionLocation</dt>
@@ -29598,11 +29667,11 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>getOrCreate(PoolMap.PoolResourceSupplier&lt;R&gt;) - Method in interface org.apache.hadoop.hbase.util.PoolMap.Pool</dt>
 <dd>&nbsp;</dd>
-<dt>getOrCreateMetricsClient(String) - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource</dt>
+<dt>getOrCreateMetricsClient(String, String, String, String, String) - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource</dt>
 <dd>
 <div class="block">Create a instance of ClientMetrics if not present otherwise return the previous one</div>
 </dd>
-<dt>getOrCreateMetricsClient(String) - Method in class org.apache.hadoop.hbase.regionserver.MetricsUserSourceImpl</dt>
+<dt>getOrCreateMetricsClient(String, String, String, String, String) - Method in class org.apache.hadoop.hbase.regionserver.MetricsUserSourceImpl</dt>
 <dd>&nbsp;</dd>
 <dt>getOrCreateMetricsUser(String) - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserAggregateSource</dt>
 <dd>
@@ -31643,6 +31712,8 @@ loadScripts(document, 'script');</script>
 </dd>
 <dt>getRemotePort() - Method in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
 <dd>&nbsp;</dd>
+<dt>getRemotePort() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>getRemoteWALDir() - Method in class org.apache.hadoop.hbase.replication.ReplicationPeerConfig</dt>
 <dd>&nbsp;</dd>
 <dt>getRemoteWALFileSystem(Configuration, String) - Static method in class org.apache.hadoop.hbase.replication.ReplicationUtils</dt>
@@ -33102,6 +33173,12 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>getServiceInterface(List&lt;RpcServer.BlockingServiceAndInterface&gt;, String) - Static method in class org.apache.hadoop.hbase.ipc.RpcServer</dt>
 <dd>&nbsp;</dd>
+<dt>getServiceName() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</dt>
+<dd>&nbsp;</dd>
+<dt>getServiceName() - Method in interface org.apache.hadoop.hbase.UserMetrics.ClientMetrics</dt>
+<dd>&nbsp;</dd>
+<dt>getServiceName() - Method in class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dd>&nbsp;</dd>
 <dt>getServiceName(Descriptors.ServiceDescriptor) - Static method in class org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils</dt>
 <dd>
 <div class="block">Returns the name to use for coprocessor service calls.</div>
@@ -35564,10 +35641,16 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>getUserName() - Method in class org.apache.hadoop.hbase.quotas.QuotaSettings</dt>
 <dd>&nbsp;</dd>
+<dt>getUserName() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</dt>
+<dd>&nbsp;</dd>
+<dt>getUserName() - Method in interface org.apache.hadoop.hbase.UserMetrics.ClientMetrics</dt>
+<dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/UserMetrics.html#getUserName()" class="member-name-link">getUserName()</a> - Method in interface org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/UserMetrics.html" title="interface in org.apache.hadoop.hbase">UserMetrics</a></dt>
 <dd>
 <div class="block">Returns the user name</div>
 </dd>
+<dt>getUserName() - Method in class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dd>&nbsp;</dd>
 <dt>getUserPermissions(GetUserPermissionsRequest) - Method in interface org.apache.hadoop.hbase.client.Admin</dt>
 <dd>
 <div class="block">Get the global/namespace/table permissions for user</div>
@@ -35892,6 +35975,8 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>getVersionedTail() - Method in class org.apache.hadoop.hbase.regionserver.CompactionPipeline</dt>
 <dd>&nbsp;</dd>
+<dt>getVersionInfo() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>getVersionInfo() - Static method in class org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil</dt>
 <dd>
 <div class="block">Get a protocol buffer VersionInfo</div>
@@ -38979,6 +39064,10 @@ loadScripts(document, 'script');</script>
 <dd>&nbsp;</dd>
 <dt>HOST - Static variable in class org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster</dt>
 <dd>&nbsp;</dd>
+<dt>HOST_ADDRESS - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
+<dd>&nbsp;</dd>
+<dt>hostAddress - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>HostAndWeight(String, long, long) - Constructor for class org.apache.hadoop.hbase.HDFSBlocksDistribution.HostAndWeight</dt>
 <dd>
 <div class="block">Constructor</div>
@@ -42004,6 +42093,8 @@ loadScripts(document, 'script');</script>
 <div class="block">Check if the exception is something that indicates that we cannot contact/communicate with the
  server.</div>
 </dd>
+<dt>isConnectionOpen() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>isCorrectEncoder(DataBlockEncoder, short) - Static method in enum class org.apache.hadoop.hbase.io.encoding.DataBlockEncoding</dt>
 <dd>
 <div class="block">Check if given encoder has this id.</div>
@@ -56378,6 +56469,8 @@ service.</div>
 <dd>
 <div class="block">For backward compatibility.</div>
 </dd>
+<dt>processOneRpc(ByteBuff) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>processOptions(String[]) - Method in class org.apache.hadoop.hbase.thrift.ThriftServer</dt>
 <dd>
 <div class="block">Parse the command line options to set parameters the conf.</div>
@@ -56412,6 +56505,13 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt><a href="org/apache/hadoop/hbase/io/crypto/KeyStoreKeyProvider.html#processParameters(java.net.URI)" class="member-name-link">processParameters(URI)</a> - Method in class org.apache.hadoop.hbase.io.crypto.<a href="org/apache/hadoop/hbase/io/crypto/KeyStoreKeyProvider.html" title="class in org.apache.hadoop.hbase.io.crypto">KeyStoreKeyProvider</a></dt>
 <dd>&nbsp;</dd>
+<dt>processPreamble(ByteBuffer) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
+<dt>processRequest(ByteBuff) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>
+<div class="block">Has the request header and the request param and optionally encoded data buffer all in this one
+ array.</div>
+</dd>
 <dt>processResult(int, String, Object) - Method in class org.apache.hadoop.hbase.coordination.ZKSplitLogManagerCoordination.DeleteAsyncCallback</dt>
 <dd>&nbsp;</dd>
 <dt>processResult(int, String, Object, byte[], Stat) - Method in class org.apache.hadoop.hbase.coordination.ZKSplitLogManagerCoordination.GetDataAsyncCallback</dt>
@@ -56509,6 +56609,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>provideHint - Variable in class org.apache.hadoop.hbase.filter.PrefixFilter</dt>
 <dd>&nbsp;</dd>
+<dt>provider - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>providerId - Variable in class org.apache.hadoop.hbase.wal.AbstractWALProvider</dt>
 <dd>&nbsp;</dd>
 <dt>providers - Variable in class org.apache.hadoop.hbase.ipc.AbstractRpcClient</dt>
@@ -59507,6 +59609,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>remoteAddress - Variable in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
 <dd>&nbsp;</dd>
+<dt>remotePort - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>remoteProcedureComplete(long, long, Throwable, byte[]) - Method in class org.apache.hadoop.hbase.regionserver.HRegionServer</dt>
 <dd>&nbsp;</dd>
 <dt>remoteProcedureCompleted(long, byte[]) - Method in class org.apache.hadoop.hbase.master.HMaster</dt>
@@ -61401,6 +61505,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>RetryImmediatelyException(String) - Constructor for exception org.apache.hadoop.hbase.RetryImmediatelyException</dt>
 <dd>&nbsp;</dd>
+<dt>retryImmediatelySupported - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>returnByteBuffDecompressor(ByteBuffDecompressor) - Static method in class org.apache.hadoop.hbase.io.compress.CodecPool</dt>
 <dd>&nbsp;</dd>
 <dt>returnByteBuffDecompressor(ByteBuffDecompressor) - Method in enum class org.apache.hadoop.hbase.io.compress.Compression.Algorithm</dt>
@@ -62043,6 +62149,8 @@ service.</div>
 </dd>
 <dt>rpcServer - Variable in class org.apache.hadoop.hbase.HBaseRpcServicesBase</dt>
 <dd>&nbsp;</dd>
+<dt>rpcServer - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.ipc.RpcServer - Class in <a href="org/apache/hadoop/hbase/ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></dt>
 <dd>
 <div class="block">An RPC server that hosts protobuf described Services.</div>
@@ -62535,6 +62643,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>saslProviders - Variable in class org.apache.hadoop.hbase.ipc.RpcServer</dt>
 <dd>&nbsp;</dd>
+<dt>saslServer - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.security.SaslStatus - Enum Class in <a href="org/apache/hadoop/hbase/security/package-summary.html">org.apache.hadoop.hbase.security</a></dt>
 <dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.security.SaslUnwrapHandler - Class in <a href="org/apache/hadoop/hbase/security/package-summary.html">org.apache.hadoop.hbase.security</a></dt>
@@ -63468,6 +63578,14 @@ service.</div>
 <dd>
 <div class="block">The server was removed from the cluster.</div>
 </dd>
+<dt>org.apache.hadoop.hbase.ipc.ServerRpcConnection - Class in <a href="org/apache/hadoop/hbase/ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></dt>
+<dd>
+<div class="block">Reads calls from a connection and queues them for handling.</div>
+</dd>
+<dt>ServerRpcConnection(RpcServer) - Constructor for class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
+<dt>org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse - Enum Class in <a href="org/apache/hadoop/hbase/ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></dt>
+<dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.ipc.ServerRpcController - Class in <a href="org/apache/hadoop/hbase/ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></dt>
 <dd>
 <div class="block">Used for server-side protobuf RPC service invocations.</div>
@@ -63526,12 +63644,16 @@ service.</div>
 </dd>
 <dt>service - Variable in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
 <dd>&nbsp;</dd>
+<dt>service - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>service(HttpServletRequest, HttpServletResponse) - Method in class org.apache.hadoop.hbase.rest.RESTServletContainer</dt>
 <dd>
 <div class="block">This container is used only if authentication and impersonation is enabled.</div>
 </dd>
 <dt>SERVICE_KEY - Static variable in class org.apache.hadoop.hbase.util.JSONMetricUtil</dt>
 <dd>&nbsp;</dd>
+<dt>SERVICE_NAME - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
+<dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.client.ServiceCaller&lt;S,<wbr>R&gt; - Interface in <a href="org/apache/hadoop/hbase/client/package-summary.html">org.apache.hadoop.hbase.client</a></dt>
 <dd>
 <div class="block">Delegate to a protobuf rpc call.</div>
@@ -67988,6 +68110,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>SKIPFLUSH - Enum constant in enum class org.apache.hadoop.hbase.client.SnapshotType</dt>
 <dd>&nbsp;</dd>
+<dt>skipInitialSaslHandshake - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>skipKVsNewerThanReadpoint() - Method in class org.apache.hadoop.hbase.regionserver.StoreFileScanner</dt>
 <dd>&nbsp;</dd>
 <dt>skipRegionManagementAction(String) - Method in class org.apache.hadoop.hbase.master.HMaster</dt>
@@ -70570,6 +70694,8 @@ service.</div>
 </dd>
 <dt>SUBSYSTEM_KEY - Static variable in class org.apache.hadoop.hbase.util.JSONMetricUtil</dt>
 <dd>&nbsp;</dd>
+<dt>SUCCEED - Enum constant in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd>&nbsp;</dd>
 <dt>SUCCESS - Enum constant in enum class org.apache.hadoop.hbase.HConstants.OperationStatusCode</dt>
 <dd>&nbsp;</dd>
 <dt>SUCCESS - Enum constant in enum class org.apache.hadoop.hbase.master.SplitLogManager.TerminationStatus</dt>
@@ -73458,6 +73584,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>toString() - Method in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
 <dd>&nbsp;</dd>
+<dt>toString() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>toString() - Method in class org.apache.hadoop.hbase.KeyValue.KeyOnlyKeyValue</dt>
 <dd>&nbsp;</dd>
 <dt>toString() - Method in class org.apache.hadoop.hbase.KeyValue</dt>
@@ -74489,6 +74617,8 @@ service.</div>
 </dl>
 <h2 class="title" id="I:U">U</h2>
 <dl class="index">
+<dt>ugi - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>ugi - Variable in class org.apache.hadoop.hbase.security.User</dt>
 <dd>&nbsp;</dd>
 <dt>unackedAppends - Variable in class org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL</dt>
@@ -76108,6 +76238,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>user - Variable in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
 <dd>&nbsp;</dd>
+<dt>user - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>org.apache.hadoop.hbase.security.User - Class in <a href="org/apache/hadoop/hbase/security/package-summary.html">org.apache.hadoop.hbase.security</a></dt>
 <dd>
 <div class="block">Wrapper to abstract out usage of user and group information in HBase.</div>
@@ -76122,6 +76254,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>USER_COUNT - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
 <dd>&nbsp;</dd>
+<dt>USER_NAME - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
+<dd>&nbsp;</dd>
 <dt>USER_REGION_COPROCESSOR_CONF_KEY - Static variable in class org.apache.hadoop.hbase.coprocessor.CoprocessorHost</dt>
 <dd>&nbsp;</dd>
 <dt>USER_SCAN - Enum constant in enum class org.apache.hadoop.hbase.regionserver.ScanType</dt>
@@ -76182,6 +76316,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>UserTableDirFilter(FileSystem) - Constructor for class org.apache.hadoop.hbase.util.FSUtils.UserTableDirFilter</dt>
 <dd>&nbsp;</dd>
+<dt>useSasl - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>&nbsp;</dd>
 <dt>useThisHostnameInstead - Variable in class org.apache.hadoop.hbase.HBaseServerBase</dt>
 <dd>
 <div class="block">hostname specified by hostname config</div>
@@ -76451,6 +76587,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>valueOf(String) - Static method in enum class org.apache.hadoop.hbase.io.Reference.Range</dt>
 <dd>&nbsp;</dd>
+<dt>valueOf(String) - Static method in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd>&nbsp;</dd>
 <dt>valueOf(String) - Static method in enum class org.apache.hadoop.hbase.KeepDeletedCells</dt>
 <dd>&nbsp;</dd>
 <dt>valueOf(String) - Static method in enum class org.apache.hadoop.hbase.KeyValue.Type</dt>
@@ -76725,6 +76863,8 @@ service.</div>
 <dd>&nbsp;</dd>
 <dt>values() - Static method in enum class org.apache.hadoop.hbase.io.Reference.Range</dt>
 <dd>&nbsp;</dd>
+<dt>values() - Static method in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd>&nbsp;</dd>
 <dt>values() - Static method in enum class org.apache.hadoop.hbase.KeepDeletedCells</dt>
 <dd>&nbsp;</dd>
 <dt>values() - Static method in enum class org.apache.hadoop.hbase.KeyValue.Type</dt>
diff --git a/apidocs/member-search-index.js b/apidocs/member-search-index.js
index 464f1b60cba..520422e2f60 100644
--- a/apidocs/member-search-index.js
+++ b/apidocs/member-search-index.js
@@ -1 +1 @@
-memberSearchIndex = [{"p":"org.apache.hadoop.hbase.filter","c":"ParseConstants","l":"A"},{"p":"org.apache.hadoop.hbase.master","c":"RegionState.State","l":"ABNORMALLY_CLOSED"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"CoprocessorHost","l":"ABORT_ON_ERROR_KEY"},{"p":"org.apache.hadoop.hdfs","c":"DummyDFSOutputStream","l":"abort()"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abort(String)","u":"abort(java.lang.String)"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abo [...]
\ No newline at end of file
+memberSearchIndex = [{"p":"org.apache.hadoop.hbase.filter","c":"ParseConstants","l":"A"},{"p":"org.apache.hadoop.hbase.master","c":"RegionState.State","l":"ABNORMALLY_CLOSED"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"CoprocessorHost","l":"ABORT_ON_ERROR_KEY"},{"p":"org.apache.hadoop.hdfs","c":"DummyDFSOutputStream","l":"abort()"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abort(String)","u":"abort(java.lang.String)"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abo [...]
\ No newline at end of file
diff --git a/apidocs/org/apache/hadoop/hbase/UserMetrics.html b/apidocs/org/apache/hadoop/hbase/UserMetrics.html
index 6c1d94d6bc5..0b97dacf5cc 100644
--- a/apidocs/org/apache/hadoop/hbase/UserMetrics.html
+++ b/apidocs/org/apache/hadoop/hbase/UserMetrics.html
@@ -160,28 +160,28 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="getUserName()">
 <h3>getUserName</h3>
-<div class="member-signature"><span class="return-type">byte[]</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-44">getUserName</a></span>()</div>
+<div class="member-signature"><span class="return-type">byte[]</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-52">getUserName</a></span>()</div>
 <div class="block">Returns the user name</div>
 </section>
 </li>
 <li>
 <section class="detail" id="getReadRequestCount()">
 <h3>getReadRequestCount</h3>
-<div class="member-signature"><span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-47">getReadRequestCount</a></span>()</div>
+<div class="member-signature"><span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-55">getReadRequestCount</a></span>()</div>
 <div class="block">Returns the number of read requests made by user</div>
 </section>
 </li>
 <li>
 <section class="detail" id="getWriteRequestCount()">
 <h3>getWriteRequestCount</h3>
-<div class="member-signature"><span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-50">getWriteRequestCount</a></span>()</div>
+<div class="member-signature"><span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-58">getWriteRequestCount</a></span>()</div>
 <div class="block">Returns the number of write requests made by user</div>
 </section>
 </li>
 <li>
 <section class="detail" id="getRequestCount()">
 <h3>getRequestCount</h3>
-<div class="member-signature"><span class="modifiers">default</span>&nbsp;<span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-56">getRequestCount</a></span>()</div>
+<div class="member-signature"><span class="modifiers">default</span>&nbsp;<span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-64">getRequestCount</a></span>()</div>
 <div class="block">Returns the number of write requests and read requests and coprocessor service requests made by
  the user</div>
 </section>
@@ -189,21 +189,21 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="getNameAsString()">
 <h3>getNameAsString</h3>
-<div class="member-signature"><span class="modifiers">default</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/UserMetrics.html#line-61">getNameAsString</a></span>()</div>
+<div class="member-signature"><span class="modifiers">default</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/UserMetrics.html#line-69">getNameAsString</a></span>()</div>
 <div class="block">Returns the user name as a string</div>
 </section>
 </li>
 <li>
 <section class="detail" id="getClientMetrics()">
 <h3>getClientMetrics</h3>
-<div class="member-signature"><span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;<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>,<wbr>org.apache.hadoop.hbase.UserMetrics.ClientMetrics&gt;</span>&nbsp;<span class="element-name"><a href=" [...]
+<div class="member-signature"><span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a>&lt;<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>,<wbr>org.apache.hadoop.hbase.UserMetrics.ClientMetrics&gt;</span>&nbsp;<span class="element-name"><a href=" [...]
 <div class="block">Returns metrics per client(hostname)</div>
 </section>
 </li>
 <li>
 <section class="detail" id="getFilteredReadRequests()">
 <h3>getFilteredReadRequests</h3>
-<div class="member-signature"><span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-69">getFilteredReadRequests</a></span>()</div>
+<div class="member-signature"><span class="return-type">long</span>&nbsp;<span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-77">getFilteredReadRequests</a></span>()</div>
 <div class="block">Returns count of filtered read requests for a user</div>
 </section>
 </li>
diff --git a/apidocs/org/apache/hadoop/hbase/class-use/ExtendedCellScanner.html b/apidocs/org/apache/hadoop/hbase/class-use/ExtendedCellScanner.html
index e2d76ee1780..668e1020d91 100644
--- a/apidocs/org/apache/hadoop/hbase/class-use/ExtendedCellScanner.html
+++ b/apidocs/org/apache/hadoop/hbase/class-use/ExtendedCellScanner.html
@@ -282,51 +282,63 @@ loadScripts(document, 'script');</script>
 <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"><code>org.apache.hadoop.hbase.ipc.HBaseRpcController</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RpcControllerFactory.</span><code>newController<wbr>(org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo,
- org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-first even-row-color"><code>abstract org.apache.hadoop.hbase.ipc.ServerCall&lt;?&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>createCall<wbr>(int&nbsp;id,
+ org.apache.hbase.thirdparty.com.google.protobuf.BlockingService&nbsp;service,
+ org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor&nbsp;md,
+ org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader&nbsp;header,
+ org.apache.hbase.thirdparty.com.google.protobuf.Message&nbsp;param,
+ org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner,
+ long&nbsp;size,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/InetAddress.html" title="class or interface in java.net" class="external-link">InetAddress</a>&nbsp;remoteAddress,
+ int&nbsp;timeout,
+ org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup&nbsp;reqCleanup)</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
 <div class="col-first odd-row-color"><code>org.apache.hadoop.hbase.ipc.HBaseRpcController</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RpcControllerFactory.</span><code>newController<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RpcControllerFactory.</span><code>newController<wbr>(org.apache.hadoop.hbase.client.RegionInfo&nbsp;regionInfo,
+ org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">DelegatingHBaseRpcController.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.ipc.HBaseRpcController</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RpcControllerFactory.</span><code>newController<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
 <div class="col-first odd-row-color"><code>void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">HBaseRpcController.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-second odd-row-color"><span class="type-name-label">DelegatingHBaseRpcController.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-last odd-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><code>void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcController.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-last even-row-color">
 <div class="block">Only used to send cells to rpc server, the returned cells should be set by
  <code>HBaseRpcController.setDone(ExtendedCellScanner)</code>.</div>
 </div>
-<div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcControllerImpl.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
-<div class="col-last even-row-color">&nbsp;</div>
 <div class="col-first odd-row-color"><code>void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">DelegatingHBaseRpcController.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">HBaseRpcControllerImpl.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
 <div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcController.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
-<div class="col-last even-row-color">
+<div class="col-second even-row-color"><span class="type-name-label">DelegatingHBaseRpcController.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">HBaseRpcController.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-last odd-row-color">
 <div class="block"><b>IMPORTANT:</b> always call this method if the call finished without any exception to tell
  the <code>HBaseRpcController</code> that we are done.</div>
 </div>
-<div class="col-first odd-row-color"><code>void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">HBaseRpcControllerImpl.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
-<div class="col-last odd-row-color">&nbsp;</div>
 <div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RpcCall.</span><code>setResponse<wbr>(org.apache.hbase.thirdparty.com.google.protobuf.Message&nbsp;param,
+<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcControllerImpl.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RpcCall.</span><code>setResponse<wbr>(org.apache.hbase.thirdparty.com.google.protobuf.Message&nbsp;param,
  org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cells,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Throwable.html" title="class or interface in java.lang" class="external-link">Throwable</a>&nbsp;errorThrowable,
  <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>&nbsp;error)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
 <div class="block">Set the response resulting from this RPC call.</div>
 </div>
-<div class="col-first odd-row-color"><code>void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">ServerCall.</span><code>setResponse<wbr>(org.apache.hbase.thirdparty.com.google.protobuf.Message&nbsp;m,
+<div class="col-first even-row-color"><code>void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerCall.</span><code>setResponse<wbr>(org.apache.hbase.thirdparty.com.google.protobuf.Message&nbsp;m,
  org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cells,
  <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Throwable.html" title="class or interface in java.lang" class="external-link">Throwable</a>&nbsp;t,
  <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>&nbsp;errorMsg)</code></div>
-<div class="col-last odd-row-color">&nbsp;</div>
+<div class="col-last even-row-color">&nbsp;</div>
 </div>
 <div class="caption"><span>Constructors in <a href="../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.ExtendedCellScanner in  in </span></div>
 <div class="summary-table three-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/codec/class-use/Codec.html b/apidocs/org/apache/hadoop/hbase/codec/class-use/Codec.html
index 0727ec0dee8..18a37eecd51 100644
--- a/apidocs/org/apache/hadoop/hbase/codec/class-use/Codec.html
+++ b/apidocs/org/apache/hadoop/hbase/codec/class-use/Codec.html
@@ -113,6 +113,11 @@ loadScripts(document, 'script');</script>
 <div class="col-first even-row-color"><code>protected final org.apache.hadoop.hbase.codec.Codec</code></div>
 <div class="col-second even-row-color"><span class="type-name-label">AbstractRpcClient.</span><code>codec</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>protected org.apache.hadoop.hbase.codec.Codec</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>codec</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Codec the client asked use.</div>
+</div>
 </div>
 <div class="caption"><span>Methods in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> that return org.apache.hadoop.hbase.codec.Codec in  in </span></div>
 <div class="summary-table three-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.CallCleanup.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.CallCleanup.html
index b8a159236b6..c7c11c0b978 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.CallCleanup.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.CallCleanup.html
@@ -71,7 +71,28 @@ loadScripts(document, 'script');</script>
 <div class="table-header col-second">Field</div>
 <div class="table-header col-last">Description</div>
 <div class="col-first even-row-color"><code>protected org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">ServerCall.</span><code>reqCleanup</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>callCleanup</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>protected org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerCall.</span><code>reqCleanup</code></div>
+<div class="col-last odd-row-color">&nbsp;</div>
+</div>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup in  in </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">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>abstract org.apache.hadoop.hbase.ipc.ServerCall&lt;?&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>createCall<wbr>(int&nbsp;id,
+ org.apache.hbase.thirdparty.com.google.protobuf.BlockingService&nbsp;service,
+ org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor&nbsp;md,
+ org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader&nbsp;header,
+ org.apache.hbase.thirdparty.com.google.protobuf.Message&nbsp;param,
+ org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner,
+ long&nbsp;size,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/InetAddress.html" title="class or interface in java.net" class="external-link">InetAddress</a>&nbsp;remoteAddress,
+ int&nbsp;timeout,
+ org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup&nbsp;reqCleanup)</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
 </div>
 </section>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.html
index b8c6a4768d5..9c1fb2cdb35 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.html
@@ -99,6 +99,15 @@ loadScripts(document, 'script');</script>
 </div>
 </div>
 </div>
+<div class="caption"><span>Fields in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> declared as org.apache.hadoop.hbase.ipc.RpcServer in  in </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>protected final org.apache.hadoop.hbase.ipc.RpcServer</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>rpcServer</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
 <div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return org.apache.hadoop.hbase.ipc.RpcServer in  in </span></div>
 <div class="summary-table three-column-summary">
 <div class="table-header col-first">Modifier and Type</div>
@@ -122,6 +131,15 @@ loadScripts(document, 'script');</script>
  boolean&nbsp;reservoirEnabled)</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
 </div>
+<div class="caption"><span>Constructors in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.ipc.RpcServer in  in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier</div>
+<div class="table-header col-second">Constructor</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>&nbsp;</code></div>
+<div class="col-second even-row-color"><code>ServerRpcConnection<wbr>(org.apache.hadoop.hbase.ipc.RpcServer&nbsp;rpcServer)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
 </section>
 </li>
 </ul>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
index 9c40e0aa68f..051c81b7775 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
@@ -67,6 +67,24 @@ loadScripts(document, 'script');</script>
 <li>
 <section class="detail" id="org.apache.hadoop.hbase.ipc">
 <h2>Uses of org.apache.hadoop.hbase.ipc.ServerCall in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return org.apache.hadoop.hbase.ipc.ServerCall in  in </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">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>abstract org.apache.hadoop.hbase.ipc.ServerCall&lt;?&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>createCall<wbr>(int&nbsp;id,
+ org.apache.hbase.thirdparty.com.google.protobuf.BlockingService&nbsp;service,
+ org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor&nbsp;md,
+ org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader&nbsp;header,
+ org.apache.hbase.thirdparty.com.google.protobuf.Message&nbsp;param,
+ org.apache.hadoop.hbase.ExtendedCellScanner&nbsp;cellScanner,
+ long&nbsp;size,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/InetAddress.html" title="class or interface in java.net" class="external-link">InetAddress</a>&nbsp;remoteAddress,
+ int&nbsp;timeout,
+ org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup&nbsp;reqCleanup)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
 <div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return types with arguments of type org.apache.hadoop.hbase.ipc.ServerCall in  in </span></div>
 <div class="summary-table three-column-summary">
 <div class="table-header col-first">Modifier and Type</div>
diff --git a/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.PreambleResponse.html
similarity index 65%
copy from apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
copy to apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.PreambleResponse.html
index 4779e416cf7..1f0e3797f3f 100644
--- a/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.PreambleResponse.html
@@ -2,10 +2,10 @@
 <html lang="en">
 <head>
 <!-- Generated by javadoc (17) -->
-<title>Uses of Enum Class org.apache.hadoop.hbase.security.SaslStatus (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
+<title>Uses of Enum Class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta name="description" content="use: package: org.apache.hadoop.hbase.security, enum: SaslStatus">
+<meta name="description" content="use: package: org.apache.hadoop.hbase.ipc, class: ServerRpcConnection, enum: PreambleResponse">
 <meta name="generator" content="javadoc/ClassUseWriter">
 <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
 <link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
@@ -49,31 +49,36 @@ loadScripts(document, 'script');</script>
 <div class="flex-content">
 <main role="main">
 <div class="header">
-<h1 title="Uses of Enum Class org.apache.hadoop.hbase.security.SaslStatus" class="title">Uses of Enum Class<br>org.apache.hadoop.hbase.security.SaslStatus</h1>
+<h1 title="Uses of Enum Class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse" class="title">Uses of Enum Class<br>org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</h1>
 </div>
-<div class="caption"><span>Packages that use org.apache.hadoop.hbase.security.SaslStatus</span></div>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</span></div>
 <div class="summary-table two-column-summary">
 <div class="table-header col-first">Package</div>
 <div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.security">org.apache.hadoop.hbase.security</a></div>
-<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
 </div>
 <section class="class-uses">
 <ul class="block-list">
 <li>
-<section class="detail" id="org.apache.hadoop.hbase.security">
-<h2>Uses of org.apache.hadoop.hbase.security.SaslStatus in <a href="../package-summary.html">org.apache.hadoop.hbase.security</a></h2>
-<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.security</a> that return org.apache.hadoop.hbase.security.SaslStatus in  in </span></div>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<h2>Uses of org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse in  in </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">Method</div>
 <div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><code>static org.apache.hadoop.hbase.security.SaslStatus</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">SaslStatus.</span><code>valueOf<wbr>(<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>&nbsp;name)</code></div>
+<div class="col-first even-row-color"><code>protected final org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>processPreamble<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/ByteBuffer.html" title="class or interface in java.nio" class="external-link">ByteBuffer</a>&nbsp;preambleBuffer)</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
-<div class="col-first odd-row-color"><code>static org.apache.hadoop.hbase.security.SaslStatus[]</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">SaslStatus.</span><code>values()</code></div>
+<div class="col-first odd-row-color"><code>static org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerRpcConnection.PreambleResponse.</span><code>valueOf<wbr>(<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>&nbsp;name)</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><code>static org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse[]</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.PreambleResponse.</span><code>values()</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
 </div>
 </section>
 </li>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.html
similarity index 67%
copy from apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
copy to apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.html
index 9c40e0aa68f..5233941c537 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.html
@@ -2,10 +2,10 @@
 <html lang="en">
 <head>
 <!-- Generated by javadoc (17) -->
-<title>Uses of Class org.apache.hadoop.hbase.ipc.ServerCall (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
+<title>Uses of Class org.apache.hadoop.hbase.ipc.ServerRpcConnection (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta name="description" content="use: package: org.apache.hadoop.hbase.ipc, class: ServerCall">
+<meta name="description" content="use: package: org.apache.hadoop.hbase.ipc, class: ServerRpcConnection">
 <meta name="generator" content="javadoc/ClassUseWriter">
 <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
 <link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
@@ -49,9 +49,9 @@ loadScripts(document, 'script');</script>
 <div class="flex-content">
 <main role="main">
 <div class="header">
-<h1 title="Uses of Class org.apache.hadoop.hbase.ipc.ServerCall" class="title">Uses of Class<br>org.apache.hadoop.hbase.ipc.ServerCall</h1>
+<h1 title="Uses of Class org.apache.hadoop.hbase.ipc.ServerRpcConnection" class="title">Uses of Class<br>org.apache.hadoop.hbase.ipc.ServerRpcConnection</h1>
 </div>
-<div class="caption"><span>Packages that use org.apache.hadoop.hbase.ipc.ServerCall</span></div>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.ipc.ServerRpcConnection</span></div>
 <div class="summary-table two-column-summary">
 <div class="table-header col-first">Package</div>
 <div class="table-header col-last">Description</div>
@@ -59,42 +59,43 @@ loadScripts(document, 'script');</script>
 <div class="col-last even-row-color">
 <div class="block">Tools to help define network clients and servers.</div>
 </div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver.regionreplication">org.apache.hadoop.hbase.regionserver.regionreplication</a></div>
-<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <section class="class-uses">
 <ul class="block-list">
 <li>
 <section class="detail" id="org.apache.hadoop.hbase.ipc">
-<h2>Uses of org.apache.hadoop.hbase.ipc.ServerCall in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
-<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return types with arguments of type org.apache.hadoop.hbase.ipc.ServerCall in  in </span></div>
+<h2>Uses of org.apache.hadoop.hbase.ipc.ServerRpcConnection in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Classes in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> with type parameters of type org.apache.hadoop.hbase.ipc.ServerRpcConnection in  in </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">Method</div>
+<div class="table-header col-second">Class</div>
 <div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><code>static <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Optional.html" title="class or interface in java.util" class="external-link">Optional</a>&lt;org.apache.hadoop.hbase.ipc.ServerCall&lt;?&gt;&gt;</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RpcServer.</span><code>getCurrentServerCallWithCellScanner()</code></div>
+<div class="col-first even-row-color"><code>class&nbsp;</code></div>
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.ipc.ServerCall&lt;T extends org.apache.hadoop.hbase.ipc.ServerRpcConnection&gt;</code></div>
 <div class="col-last even-row-color">
-<div class="block">Just return the current rpc call if it is a <code>ServerCall</code> and also has <code>CellScanner</code>
- attached.</div>
+<div class="block">Datastructure that holds all necessary to a method invocation and then afterward, carries the
+ result.</div>
 </div>
 </div>
-</section>
-</li>
-<li>
-<section class="detail" id="org.apache.hadoop.hbase.regionserver.regionreplication">
-<h2>Uses of org.apache.hadoop.hbase.ipc.ServerCall in <a href="../../regionserver/regionreplication/package-summary.html">org.apache.hadoop.hbase.regionserver.regionreplication</a></h2>
-<div class="caption"><span>Methods in <a href="../../regionserver/regionreplication/package-summary.html">org.apache.hadoop.hbase.regionserver.regionreplication</a> with parameters of type org.apache.hadoop.hbase.ipc.ServerCall in  in </span></div>
+<div class="caption"><span>Fields in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> declared as org.apache.hadoop.hbase.ipc.ServerRpcConnection in  in </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>protected final T</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerCall.</span><code>connection</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return types with arguments of type org.apache.hadoop.hbase.ipc.ServerRpcConnection in  in </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">Method</div>
 <div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionReplicationSink.</span><code>add<wbr>(org.apache.hadoop.hbase.wal.WALKeyImpl&nbsp;key,
- org.apache.hadoop.hbase.wal.WALEdit&nbsp;edit,
- org.apache.hadoop.hbase.ipc.ServerCall&lt;?&gt;&nbsp;rpcCall)</code></div>
+<div class="col-first even-row-color"><code>static <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Optional.html" title="class or interface in java.util" class="external-link">Optional</a>&lt;org.apache.hadoop.hbase.ipc.ServerRpcConnection&gt;</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RpcServer.</span><code>getCurrentServerRpcConnection()</code></div>
 <div class="col-last even-row-color">
-<div class="block">Add this edit to replication queue.</div>
+<div class="block">Returns the ServerRpcConnection for the current RPC request or not present if no connection is
+ available.</div>
 </div>
 </div>
 </section>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/package-summary.html b/apidocs/org/apache/hadoop/hbase/ipc/package-summary.html
index 217901eac57..a07724c96c2 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/package-summary.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/package-summary.html
@@ -84,7 +84,7 @@ This is the hadoop copied local so can fix bugs and make hbase-specific optimiza
 </li>
 <li>
 <div id="class-summary">
-<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="class-summary-tab0" role="tab" aria-selected="true" aria-controls="class-summary.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary', 2)" class="active-table-tab">All Classes and Interfaces</button><button id="class-summary-tab1" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('clas [...]
+<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="class-summary-tab0" role="tab" aria-selected="true" aria-controls="class-summary.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary', 2)" class="active-table-tab">All Classes and Interfaces</button><button id="class-summary-tab1" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('clas [...]
 <div id="class-summary.tabpanel" role="tabpanel">
 <div class="summary-table two-column-summary" aria-labelledby="class-summary-tab0">
 <div class="table-header col-first">Class</div>
@@ -378,6 +378,12 @@ This is the hadoop copied local so can fix bugs and make hbase-specific optimiza
 </div>
 <div class="col-first odd-row-color class-summary class-summary-tab5">org.apache.hadoop.hbase.ipc.ServerNotRunningYetException</div>
 <div class="col-last odd-row-color class-summary class-summary-tab5">&nbsp;</div>
+<div class="col-first even-row-color class-summary class-summary-tab2">org.apache.hadoop.hbase.ipc.ServerRpcConnection</div>
+<div class="col-last even-row-color class-summary class-summary-tab2">
+<div class="block">Reads calls from a connection and queues them for handling.</div>
+</div>
+<div class="col-first odd-row-color class-summary class-summary-tab3">org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</div>
+<div class="col-last odd-row-color class-summary class-summary-tab3">&nbsp;</div>
 <div class="col-first even-row-color class-summary class-summary-tab2">org.apache.hadoop.hbase.ipc.ServerRpcController</div>
 <div class="col-last even-row-color class-summary class-summary-tab2">
 <div class="block">Used for server-side protobuf RPC service invocations.</div>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/package-tree.html b/apidocs/org/apache/hadoop/hbase/ipc/package-tree.html
index 2fe25122157..e97a21fda2c 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/package-tree.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/package-tree.html
@@ -159,6 +159,7 @@ loadScripts(document, 'script');</script>
 <li class="circle">org.apache.hadoop.hbase.ipc.RpcServer.BlockingServiceAndInterface</li>
 <li class="circle">org.apache.hadoop.hbase.ipc.RpcServerFactory</li>
 <li class="circle">org.apache.hadoop.hbase.ipc.ServerCall&lt;T&gt; (implements org.apache.hadoop.hbase.ipc.RpcCall)</li>
+<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcConnection (implements java.io.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Closeable.html" title="class or interface in java.io" class="external-link">Closeable</a>)</li>
 <li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcController (implements org.apache.hbase.thirdparty.com.google.protobuf.RpcController)</li>
 <li class="circle">java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Thread.html" class="type-name-link external-link" title="class or interface in java.lang">Thread</a> (implements java.lang.<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>)
 <ul>
@@ -291,6 +292,20 @@ loadScripts(document, 'script');</script>
 <li class="circle">org.apache.hadoop.hbase.ipc.QosPriority (implements java.lang.annotation.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/Annotation.html" title="class or interface in java.lang.annotation" class="external-link">Annotation</a>)</li>
 </ul>
 </section>
+<section class="hierarchy">
+<h2 title="Enum Class Hierarchy">Enum Class Hierarchy</h2>
+<ul>
+<li class="circle">java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" class="type-name-link external-link" title="class or interface in java.lang">Object</a>
+<ul>
+<li class="circle">java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Enum.html" class="type-name-link external-link" title="class or interface in java.lang">Enum</a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Comparable.html" title="class or interface in java.lang" class="external-link">Comparable</a>&lt;T&gt;, java.lang.constant.<a href="https://docs.oracle.com/en/java/javase/17/d [...]
+<ul>
+<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</section>
 </main>
 <footer role="contentinfo">
 <hr>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/package-use.html b/apidocs/org/apache/hadoop/hbase/ipc/package-use.html
index 4beb2f7e75a..684926c8f53 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/package-use.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/package-use.html
@@ -265,6 +265,12 @@ loadScripts(document, 'script');</script>
 <div class="block">Datastructure that holds all necessary to a method invocation and then afterward, carries the
  result.</div>
 </div>
+<div class="col-first odd-row-color"><a href="class-use/ServerRpcConnection.html#org.apache.hadoop.hbase.ipc">ServerRpcConnection</a></div>
+<div class="col-last odd-row-color">
+<div class="block">Reads calls from a connection and queues them for handling.</div>
+</div>
+<div class="col-first even-row-color"><a href="class-use/ServerRpcConnection.PreambleResponse.html#org.apache.hadoop.hbase.ipc">ServerRpcConnection.PreambleResponse</a></div>
+<div class="col-last even-row-color">&nbsp;</div>
 </div>
 </section>
 </li>
diff --git a/apidocs/org/apache/hadoop/hbase/nio/class-use/ByteBuff.html b/apidocs/org/apache/hadoop/hbase/nio/class-use/ByteBuff.html
index 771d46cb3e3..76682d0d262 100644
--- a/apidocs/org/apache/hadoop/hbase/nio/class-use/ByteBuff.html
+++ b/apidocs/org/apache/hadoop/hbase/nio/class-use/ByteBuff.html
@@ -70,12 +70,16 @@ loadScripts(document, 'script');</script>
 </div>
 <div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.io.util">org.apache.hadoop.hbase.io.util</a></div>
 <div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.nio">org.apache.hadoop.hbase.nio</a></div>
-<div class="col-last even-row-color">&nbsp;</div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.nio">org.apache.hadoop.hbase.nio</a></div>
 <div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.util">org.apache.hadoop.hbase.util</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
 <div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.util">org.apache.hadoop.hbase.util</a></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <section class="class-uses">
 <ul class="block-list">
@@ -403,6 +407,26 @@ loadScripts(document, 'script');</script>
 </section>
 </li>
 <li>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<h2>Uses of org.apache.hadoop.hbase.nio.ByteBuff in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Methods in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.nio.ByteBuff in  in </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">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>processOneRpc<wbr>(org.apache.hadoop.hbase.nio.ByteBuff&nbsp;buf)</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>protected void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>processRequest<wbr>(org.apache.hadoop.hbase.nio.ByteBuff&nbsp;buf)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Has the request header and the request param and optionally encoded data buffer all in this one
+ array.</div>
+</div>
+</div>
+</section>
+</li>
+<li>
 <section class="detail" id="org.apache.hadoop.hbase.nio">
 <h2>Uses of org.apache.hadoop.hbase.nio.ByteBuff in <a href="../package-summary.html">org.apache.hadoop.hbase.nio</a></h2>
 <div class="caption"><span>Subclasses of org.apache.hadoop.hbase.nio.ByteBuff in  in <a href="../package-summary.html">org.apache.hadoop.hbase.nio</a></span></div>
diff --git a/apidocs/org/apache/hadoop/hbase/nio/package-use.html b/apidocs/org/apache/hadoop/hbase/nio/package-use.html
index 39f053d2c64..eb62a6f282a 100644
--- a/apidocs/org/apache/hadoop/hbase/nio/package-use.html
+++ b/apidocs/org/apache/hadoop/hbase/nio/package-use.html
@@ -70,12 +70,16 @@ loadScripts(document, 'script');</script>
 </div>
 <div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.io.util">org.apache.hadoop.hbase.io.util</a></div>
 <div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.nio">org.apache.hadoop.hbase.nio</a></div>
-<div class="col-last even-row-color">&nbsp;</div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.nio">org.apache.hadoop.hbase.nio</a></div>
 <div class="col-last odd-row-color">&nbsp;</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.util">org.apache.hadoop.hbase.util</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
 <div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.util">org.apache.hadoop.hbase.util</a></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <section class="package-uses">
 <ul class="block-list">
@@ -173,6 +177,20 @@ loadScripts(document, 'script');</script>
 </section>
 </li>
 <li>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<div class="caption"><span>Classes in <a href="package-summary.html">org.apache.hadoop.hbase.nio</a> used by <a href="../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></span></div>
+<div class="summary-table two-column-summary">
+<div class="table-header col-first">Class</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="class-use/ByteBuff.html#org.apache.hadoop.hbase.ipc">ByteBuff</a></div>
+<div class="col-last even-row-color">
+<div class="block">An abstract class that abstracts out as to how the byte buffers are used, either single or
+ multiple.</div>
+</div>
+</div>
+</section>
+</li>
+<li>
 <section class="detail" id="org.apache.hadoop.hbase.nio">
 <div class="caption"><span>Classes in <a href="package-summary.html">org.apache.hadoop.hbase.nio</a> used by <a href="package-summary.html">org.apache.hadoop.hbase.nio</a></span></div>
 <div class="summary-table two-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/regionserver/class-use/MetricsUserSource.ClientMetrics.html b/apidocs/org/apache/hadoop/hbase/regionserver/class-use/MetricsUserSource.ClientMetrics.html
index c45da0daf63..64a9d25160e 100644
--- a/apidocs/org/apache/hadoop/hbase/regionserver/class-use/MetricsUserSource.ClientMetrics.html
+++ b/apidocs/org/apache/hadoop/hbase/regionserver/class-use/MetricsUserSource.ClientMetrics.html
@@ -69,12 +69,20 @@ loadScripts(document, 'script');</script>
 <div class="table-header col-second">Method</div>
 <div class="table-header col-last">Description</div>
 <div class="col-first even-row-color"><code>org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MetricsUserSource.</span><code>getOrCreateMetricsClient<wbr>(<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>&nbsp;hostName)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MetricsUserSource.</span><code>getOrCreateMetricsClient<wbr>(<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>&nbsp;hostName,
+ <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>&nbsp;hostAddress,
+ <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>&nbsp;userName,
+ <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>&nbsp;clientVersion,
+ <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>&nbsp;serviceName)</code></div>
 <div class="col-last even-row-color">
 <div class="block">Create a instance of ClientMetrics if not present otherwise return the previous one</div>
 </div>
 <div class="col-first odd-row-color"><code>org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MetricsUserSourceImpl.</span><code>getOrCreateMetricsClient<wbr>(<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>&nbsp;client)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MetricsUserSourceImpl.</span><code>getOrCreateMetricsClient<wbr>(<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>&nbsp;client,
+ <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>&nbsp;hostAddress,
+ <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>&nbsp;userName,
+ <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>&nbsp;clientVersion,
+ <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>&nbsp;serviceName)</code></div>
 <div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.regionserver</a> that return types with arguments of type org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics in  in </span></div>
diff --git a/apidocs/org/apache/hadoop/hbase/security/class-use/HBaseSaslRpcServer.html b/apidocs/org/apache/hadoop/hbase/security/class-use/HBaseSaslRpcServer.html
index 41f667e236c..cc838cdc98a 100644
--- a/apidocs/org/apache/hadoop/hbase/security/class-use/HBaseSaslRpcServer.html
+++ b/apidocs/org/apache/hadoop/hbase/security/class-use/HBaseSaslRpcServer.html
@@ -51,7 +51,34 @@ loadScripts(document, 'script');</script>
 <div class="header">
 <h1 title="Uses of Class org.apache.hadoop.hbase.security.HBaseSaslRpcServer" class="title">Uses of Class<br>org.apache.hadoop.hbase.security.HBaseSaslRpcServer</h1>
 </div>
-No usage of org.apache.hadoop.hbase.security.HBaseSaslRpcServer</main>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.security.HBaseSaslRpcServer</span></div>
+<div class="summary-table two-column-summary">
+<div class="table-header col-first">Package</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
+</div>
+<section class="class-uses">
+<ul class="block-list">
+<li>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<h2>Uses of org.apache.hadoop.hbase.security.HBaseSaslRpcServer in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Fields in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> declared as org.apache.hadoop.hbase.security.HBaseSaslRpcServer in  in </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>protected org.apache.hadoop.hbase.security.HBaseSaslRpcServer</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>saslServer</code></div>
+<div class="col-last even-row-color">&nbsp;</div>
+</div>
+</section>
+</li>
+</ul>
+</section>
+</main>
 <footer role="contentinfo">
 <hr>
 <p class="legal-copy"><small>Copyright &#169; 2007&#x2013;2020 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
diff --git a/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html b/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
index 4779e416cf7..e7f0f839969 100644
--- a/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
+++ b/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
@@ -55,12 +55,35 @@ loadScripts(document, 'script');</script>
 <div class="summary-table two-column-summary">
 <div class="table-header col-first">Package</div>
 <div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.security">org.apache.hadoop.hbase.security</a></div>
-<div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.security">org.apache.hadoop.hbase.security</a></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <section class="class-uses">
 <ul class="block-list">
 <li>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<h2>Uses of org.apache.hadoop.hbase.security.SaslStatus in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Methods in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.security.SaslStatus in  in </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">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>protected final void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>doRawSaslReply<wbr>(org.apache.hadoop.hbase.security.SaslStatus&nbsp;status,
+ org.apache.hadoop.io.Writable&nbsp;rv,
+ <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>&nbsp;errorClass,
+ <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>&nbsp;error)</code></div>
+<div class="col-last even-row-color">
+<div class="block">No protobuf encoding of raw sasl messages</div>
+</div>
+</div>
+</section>
+</li>
+<li>
 <section class="detail" id="org.apache.hadoop.hbase.security">
 <h2>Uses of org.apache.hadoop.hbase.security.SaslStatus in <a href="../package-summary.html">org.apache.hadoop.hbase.security</a></h2>
 <div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.security</a> that return org.apache.hadoop.hbase.security.SaslStatus in  in </span></div>
diff --git a/apidocs/org/apache/hadoop/hbase/security/class-use/User.html b/apidocs/org/apache/hadoop/hbase/security/class-use/User.html
index b4d552a33f2..fc282bb8901 100644
--- a/apidocs/org/apache/hadoop/hbase/security/class-use/User.html
+++ b/apidocs/org/apache/hadoop/hbase/security/class-use/User.html
@@ -386,6 +386,9 @@ loadScripts(document, 'script');</script>
 <div class="col-first even-row-color"><code>protected final org.apache.hadoop.hbase.security.User</code></div>
 <div class="col-second even-row-color"><span class="type-name-label">ServerCall.</span><code>user</code></div>
 <div class="col-last even-row-color">&nbsp;</div>
+<div class="col-first odd-row-color"><code>protected org.apache.hadoop.hbase.security.User</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>user</code></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 </div>
 <div class="caption"><span>Methods in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> that return types with arguments of type org.apache.hadoop.hbase.security.User in  in </span></div>
 <div class="summary-table three-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/security/package-use.html b/apidocs/org/apache/hadoop/hbase/security/package-use.html
index 6a133d883fa..c5de1f8ba32 100644
--- a/apidocs/org/apache/hadoop/hbase/security/package-use.html
+++ b/apidocs/org/apache/hadoop/hbase/security/package-use.html
@@ -142,6 +142,12 @@ service.</div>
 <div class="summary-table two-column-summary">
 <div class="table-header col-first">Class</div>
 <div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="class-use/HBaseSaslRpcServer.html#org.apache.hadoop.hbase.ipc">HBaseSaslRpcServer</a></div>
+<div class="col-last even-row-color">
+<div class="block">A utility class that encapsulates SASL logic for RPC server.</div>
+</div>
+<div class="col-first odd-row-color"><a href="class-use/SaslStatus.html#org.apache.hadoop.hbase.ipc">SaslStatus</a></div>
+<div class="col-last odd-row-color">&nbsp;</div>
 <div class="col-first even-row-color"><a href="class-use/User.html#org.apache.hadoop.hbase.ipc">User</a></div>
 <div class="col-last even-row-color">
 <div class="block">Wrapper to abstract out usage of user and group information in HBase.</div>
diff --git a/apidocs/overview-tree.html b/apidocs/overview-tree.html
index 99456612ad6..5173c825e41 100644
--- a/apidocs/overview-tree.html
+++ b/apidocs/overview-tree.html
@@ -2214,6 +2214,7 @@ loadScripts(document, 'script');</script>
 <li class="circle">org.apache.hadoop.hbase.ServerMetricsBuilder</li>
 <li class="circle">org.apache.hadoop.hbase.ServerName (implements java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Comparable.html" title="class or interface in java.lang" class="external-link">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Serializable.html" title="class or interface in java.io" class="external-link">Serializable</a>)</li>
 <li class="circle">org.apache.hadoop.hbase.regionserver.ServerNonceManager</li>
+<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcConnection (implements java.io.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Closeable.html" title="class or interface in java.io" class="external-link">Closeable</a>)</li>
 <li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcController (implements org.apache.hbase.thirdparty.com.google.protobuf.RpcController)</li>
 <li class="circle">org.apache.hadoop.hbase.client.backoff.ServerStatistics</li>
 <li class="circle">org.apache.hadoop.hbase.client.backoff.ServerStatistics.RegionStatistics</li>
@@ -3636,6 +3637,7 @@ loadScripts(document, 'script');</script>
 <li class="circle">org.apache.hadoop.hbase.regionserver.ScanType</li>
 <li class="circle">org.apache.hadoop.hbase.client.security.SecurityCapability</li>
 <li class="circle">org.apache.hadoop.hbase.master.ServerManager.ServerLiveState</li>
+<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</li>
 <li class="circle">org.apache.hadoop.hbase.ServerTask.State</li>
 <li class="circle">org.apache.hadoop.hbase.client.ServerType</li>
 <li class="circle">org.apache.hadoop.hbase.Size.Unit</li>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.ClientMetrics.html b/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.ClientMetrics.html
index ed1ef6640b0..b25b281fcd0 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.ClientMetrics.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.ClientMetrics.html
@@ -51,36 +51,44 @@
 <span class="source-line-no">038</span><span id="line-38">    long getWriteRequestsCount();</span>
 <span class="source-line-no">039</span><span id="line-39"></span>
 <span class="source-line-no">040</span><span id="line-40">    long getFilteredReadRequestsCount();</span>
-<span class="source-line-no">041</span><span id="line-41">  }</span>
-<span class="source-line-no">042</span><span id="line-42"></span>
-<span class="source-line-no">043</span><span id="line-43">  /** Returns the user name */</span>
-<span class="source-line-no">044</span><span id="line-44">  byte[] getUserName();</span>
+<span class="source-line-no">041</span><span id="line-41"></span>
+<span class="source-line-no">042</span><span id="line-42">    String getHostAddress();</span>
+<span class="source-line-no">043</span><span id="line-43"></span>
+<span class="source-line-no">044</span><span id="line-44">    String getUserName();</span>
 <span class="source-line-no">045</span><span id="line-45"></span>
-<span class="source-line-no">046</span><span id="line-46">  /** Returns the number of read requests made by user */</span>
-<span class="source-line-no">047</span><span id="line-47">  long getReadRequestCount();</span>
-<span class="source-line-no">048</span><span id="line-48"></span>
-<span class="source-line-no">049</span><span id="line-49">  /** Returns the number of write requests made by user */</span>
-<span class="source-line-no">050</span><span id="line-50">  long getWriteRequestCount();</span>
-<span class="source-line-no">051</span><span id="line-51"></span>
-<span class="source-line-no">052</span><span id="line-52">  /**</span>
-<span class="source-line-no">053</span><span id="line-53">   * Returns the number of write requests and read requests and coprocessor service requests made by</span>
-<span class="source-line-no">054</span><span id="line-54">   * the user</span>
-<span class="source-line-no">055</span><span id="line-55">   */</span>
-<span class="source-line-no">056</span><span id="line-56">  default long getRequestCount() {</span>
-<span class="source-line-no">057</span><span id="line-57">    return getReadRequestCount() + getWriteRequestCount();</span>
-<span class="source-line-no">058</span><span id="line-58">  }</span>
+<span class="source-line-no">046</span><span id="line-46">    String getClientVersion();</span>
+<span class="source-line-no">047</span><span id="line-47"></span>
+<span class="source-line-no">048</span><span id="line-48">    String getServiceName();</span>
+<span class="source-line-no">049</span><span id="line-49">  }</span>
+<span class="source-line-no">050</span><span id="line-50"></span>
+<span class="source-line-no">051</span><span id="line-51">  /** Returns the user name */</span>
+<span class="source-line-no">052</span><span id="line-52">  byte[] getUserName();</span>
+<span class="source-line-no">053</span><span id="line-53"></span>
+<span class="source-line-no">054</span><span id="line-54">  /** Returns the number of read requests made by user */</span>
+<span class="source-line-no">055</span><span id="line-55">  long getReadRequestCount();</span>
+<span class="source-line-no">056</span><span id="line-56"></span>
+<span class="source-line-no">057</span><span id="line-57">  /** Returns the number of write requests made by user */</span>
+<span class="source-line-no">058</span><span id="line-58">  long getWriteRequestCount();</span>
 <span class="source-line-no">059</span><span id="line-59"></span>
-<span class="source-line-no">060</span><span id="line-60">  /** Returns the user name as a string */</span>
-<span class="source-line-no">061</span><span id="line-61">  default String getNameAsString() {</span>
-<span class="source-line-no">062</span><span id="line-62">    return Bytes.toStringBinary(getUserName());</span>
-<span class="source-line-no">063</span><span id="line-63">  }</span>
-<span class="source-line-no">064</span><span id="line-64"></span>
-<span class="source-line-no">065</span><span id="line-65">  /** Returns metrics per client(hostname) */</span>
-<span class="source-line-no">066</span><span id="line-66">  Map&lt;String, ClientMetrics&gt; getClientMetrics();</span>
+<span class="source-line-no">060</span><span id="line-60">  /**</span>
+<span class="source-line-no">061</span><span id="line-61">   * Returns the number of write requests and read requests and coprocessor service requests made by</span>
+<span class="source-line-no">062</span><span id="line-62">   * the user</span>
+<span class="source-line-no">063</span><span id="line-63">   */</span>
+<span class="source-line-no">064</span><span id="line-64">  default long getRequestCount() {</span>
+<span class="source-line-no">065</span><span id="line-65">    return getReadRequestCount() + getWriteRequestCount();</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">  /** Returns count of filtered read requests for a user */</span>
-<span class="source-line-no">069</span><span id="line-69">  long getFilteredReadRequests();</span>
-<span class="source-line-no">070</span><span id="line-70">}</span>
+<span class="source-line-no">068</span><span id="line-68">  /** Returns the user name as a string */</span>
+<span class="source-line-no">069</span><span id="line-69">  default String getNameAsString() {</span>
+<span class="source-line-no">070</span><span id="line-70">    return Bytes.toStringBinary(getUserName());</span>
+<span class="source-line-no">071</span><span id="line-71">  }</span>
+<span class="source-line-no">072</span><span id="line-72"></span>
+<span class="source-line-no">073</span><span id="line-73">  /** Returns metrics per client(hostname) */</span>
+<span class="source-line-no">074</span><span id="line-74">  Map&lt;String, ClientMetrics&gt; getClientMetrics();</span>
+<span class="source-line-no">075</span><span id="line-75"></span>
+<span class="source-line-no">076</span><span id="line-76">  /** Returns count of filtered read requests for a user */</span>
+<span class="source-line-no">077</span><span id="line-77">  long getFilteredReadRequests();</span>
+<span class="source-line-no">078</span><span id="line-78">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.html b/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.html
index 9ce68d58f4b..073d3c1754b 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.html
@@ -51,36 +51,44 @@
 <span class="source-line-no">038</span><span id="line-38">    long getWriteRequestsCount();</span>
 <span class="source-line-no">039</span><span id="line-39"></span>
 <span class="source-line-no">040</span><span id="line-40">    long getFilteredReadRequestsCount();</span>
-<span class="source-line-no">041</span><span id="line-41">  }</span>
-<span class="source-line-no">042</span><span id="line-42"></span>
-<span class="source-line-no">043</span><span id="line-43">  /** Returns the user name */</span>
-<span class="source-line-no">044</span><span id="line-44">  byte[] getUserName();</span>
+<span class="source-line-no">041</span><span id="line-41"></span>
+<span class="source-line-no">042</span><span id="line-42">    String getHostAddress();</span>
+<span class="source-line-no">043</span><span id="line-43"></span>
+<span class="source-line-no">044</span><span id="line-44">    String getUserName();</span>
 <span class="source-line-no">045</span><span id="line-45"></span>
-<span class="source-line-no">046</span><span id="line-46">  /** Returns the number of read requests made by user */</span>
-<span class="source-line-no">047</span><span id="line-47">  long getReadRequestCount();</span>
-<span class="source-line-no">048</span><span id="line-48"></span>
-<span class="source-line-no">049</span><span id="line-49">  /** Returns the number of write requests made by user */</span>
-<span class="source-line-no">050</span><span id="line-50">  long getWriteRequestCount();</span>
-<span class="source-line-no">051</span><span id="line-51"></span>
-<span class="source-line-no">052</span><span id="line-52">  /**</span>
-<span class="source-line-no">053</span><span id="line-53">   * Returns the number of write requests and read requests and coprocessor service requests made by</span>
-<span class="source-line-no">054</span><span id="line-54">   * the user</span>
-<span class="source-line-no">055</span><span id="line-55">   */</span>
-<span class="source-line-no">056</span><span id="line-56">  default long getRequestCount() {</span>
-<span class="source-line-no">057</span><span id="line-57">    return getReadRequestCount() + getWriteRequestCount();</span>
-<span class="source-line-no">058</span><span id="line-58">  }</span>
+<span class="source-line-no">046</span><span id="line-46">    String getClientVersion();</span>
+<span class="source-line-no">047</span><span id="line-47"></span>
+<span class="source-line-no">048</span><span id="line-48">    String getServiceName();</span>
+<span class="source-line-no">049</span><span id="line-49">  }</span>
+<span class="source-line-no">050</span><span id="line-50"></span>
+<span class="source-line-no">051</span><span id="line-51">  /** Returns the user name */</span>
+<span class="source-line-no">052</span><span id="line-52">  byte[] getUserName();</span>
+<span class="source-line-no">053</span><span id="line-53"></span>
+<span class="source-line-no">054</span><span id="line-54">  /** Returns the number of read requests made by user */</span>
+<span class="source-line-no">055</span><span id="line-55">  long getReadRequestCount();</span>
+<span class="source-line-no">056</span><span id="line-56"></span>
+<span class="source-line-no">057</span><span id="line-57">  /** Returns the number of write requests made by user */</span>
+<span class="source-line-no">058</span><span id="line-58">  long getWriteRequestCount();</span>
 <span class="source-line-no">059</span><span id="line-59"></span>
-<span class="source-line-no">060</span><span id="line-60">  /** Returns the user name as a string */</span>
-<span class="source-line-no">061</span><span id="line-61">  default String getNameAsString() {</span>
-<span class="source-line-no">062</span><span id="line-62">    return Bytes.toStringBinary(getUserName());</span>
-<span class="source-line-no">063</span><span id="line-63">  }</span>
-<span class="source-line-no">064</span><span id="line-64"></span>
-<span class="source-line-no">065</span><span id="line-65">  /** Returns metrics per client(hostname) */</span>
-<span class="source-line-no">066</span><span id="line-66">  Map&lt;String, ClientMetrics&gt; getClientMetrics();</span>
+<span class="source-line-no">060</span><span id="line-60">  /**</span>
+<span class="source-line-no">061</span><span id="line-61">   * Returns the number of write requests and read requests and coprocessor service requests made by</span>
+<span class="source-line-no">062</span><span id="line-62">   * the user</span>
+<span class="source-line-no">063</span><span id="line-63">   */</span>
+<span class="source-line-no">064</span><span id="line-64">  default long getRequestCount() {</span>
+<span class="source-line-no">065</span><span id="line-65">    return getReadRequestCount() + getWriteRequestCount();</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">  /** Returns count of filtered read requests for a user */</span>
-<span class="source-line-no">069</span><span id="line-69">  long getFilteredReadRequests();</span>
-<span class="source-line-no">070</span><span id="line-70">}</span>
+<span class="source-line-no">068</span><span id="line-68">  /** Returns the user name as a string */</span>
+<span class="source-line-no">069</span><span id="line-69">  default String getNameAsString() {</span>
+<span class="source-line-no">070</span><span id="line-70">    return Bytes.toStringBinary(getUserName());</span>
+<span class="source-line-no">071</span><span id="line-71">  }</span>
+<span class="source-line-no">072</span><span id="line-72"></span>
+<span class="source-line-no">073</span><span id="line-73">  /** Returns metrics per client(hostname) */</span>
+<span class="source-line-no">074</span><span id="line-74">  Map&lt;String, ClientMetrics&gt; getClientMetrics();</span>
+<span class="source-line-no">075</span><span id="line-75"></span>
+<span class="source-line-no">076</span><span id="line-76">  /** Returns count of filtered read requests for a user */</span>
+<span class="source-line-no">077</span><span id="line-77">  long getFilteredReadRequests();</span>
+<span class="source-line-no">078</span><span id="line-78">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.ClientMetricsImpl.html b/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.ClientMetricsImpl.html
index b59fada355a..b1e06be87d8 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.ClientMetricsImpl.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.ClientMetricsImpl.html
@@ -49,127 +49,161 @@
 <span class="source-line-no">036</span><span id="line-36">    userLoad.getClientMetricsList().stream()</span>
 <span class="source-line-no">037</span><span id="line-37">      .map(clientMetrics -&gt; new ClientMetricsImpl(clientMetrics.getHostName(),</span>
 <span class="source-line-no">038</span><span id="line-38">        clientMetrics.getReadRequestsCount(), clientMetrics.getWriteRequestsCount(),</span>
-<span class="source-line-no">039</span><span id="line-39">        clientMetrics.getFilteredRequestsCount()))</span>
-<span class="source-line-no">040</span><span id="line-40">      .forEach(builder::addClientMetris);</span>
-<span class="source-line-no">041</span><span id="line-41">    return builder.build();</span>
-<span class="source-line-no">042</span><span id="line-42">  }</span>
-<span class="source-line-no">043</span><span id="line-43"></span>
-<span class="source-line-no">044</span><span id="line-44">  public static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics) {</span>
-<span class="source-line-no">045</span><span id="line-45">    ClusterStatusProtos.UserLoad.Builder builder =</span>
-<span class="source-line-no">046</span><span id="line-46">      ClusterStatusProtos.UserLoad.newBuilder().setUserName(userMetrics.getNameAsString());</span>
-<span class="source-line-no">047</span><span id="line-47">    userMetrics.getClientMetrics().values().stream()</span>
-<span class="source-line-no">048</span><span id="line-48">      .map(clientMetrics -&gt; ClusterStatusProtos.ClientMetrics.newBuilder()</span>
-<span class="source-line-no">049</span><span id="line-49">        .setHostName(clientMetrics.getHostName())</span>
-<span class="source-line-no">050</span><span id="line-50">        .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
-<span class="source-line-no">051</span><span id="line-51">        .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
-<span class="source-line-no">052</span><span id="line-52">        .setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount()).build())</span>
-<span class="source-line-no">053</span><span id="line-53">      .forEach(builder::addClientMetrics);</span>
-<span class="source-line-no">054</span><span id="line-54">    return builder.build();</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">  public static UserMetricsBuilder newBuilder(byte[] name) {</span>
-<span class="source-line-no">058</span><span id="line-58">    return new UserMetricsBuilder(name);</span>
-<span class="source-line-no">059</span><span id="line-59">  }</span>
-<span class="source-line-no">060</span><span id="line-60"></span>
-<span class="source-line-no">061</span><span id="line-61">  private final byte[] name;</span>
-<span class="source-line-no">062</span><span id="line-62">  private Map&lt;String, UserMetrics.ClientMetrics&gt; clientMetricsMap = new HashMap&lt;&gt;();</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 UserMetricsBuilder(byte[] name) {</span>
-<span class="source-line-no">065</span><span id="line-65">    this.name = name;</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">  public UserMetricsBuilder addClientMetris(UserMetrics.ClientMetrics clientMetrics) {</span>
-<span class="source-line-no">069</span><span id="line-69">    clientMetricsMap.put(clientMetrics.getHostName(), clientMetrics);</span>
-<span class="source-line-no">070</span><span id="line-70">    return this;</span>
+<span class="source-line-no">039</span><span id="line-39">        clientMetrics.getFilteredRequestsCount(), clientMetrics.getHostAddress(),</span>
+<span class="source-line-no">040</span><span id="line-40">        clientMetrics.getUserName(), clientMetrics.getServiceName(),</span>
+<span class="source-line-no">041</span><span id="line-41">        clientMetrics.getClientVersion()))</span>
+<span class="source-line-no">042</span><span id="line-42">      .forEach(builder::addClientMetris);</span>
+<span class="source-line-no">043</span><span id="line-43">    return builder.build();</span>
+<span class="source-line-no">044</span><span id="line-44">  }</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 static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics) {</span>
+<span class="source-line-no">047</span><span id="line-47">    ClusterStatusProtos.UserLoad.Builder builder =</span>
+<span class="source-line-no">048</span><span id="line-48">      ClusterStatusProtos.UserLoad.newBuilder().setUserName(userMetrics.getNameAsString());</span>
+<span class="source-line-no">049</span><span id="line-49">    userMetrics.getClientMetrics().values().stream()</span>
+<span class="source-line-no">050</span><span id="line-50">      .map(clientMetrics -&gt; ClusterStatusProtos.ClientMetrics.newBuilder()</span>
+<span class="source-line-no">051</span><span id="line-51">        .setHostName(clientMetrics.getHostName())</span>
+<span class="source-line-no">052</span><span id="line-52">        .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
+<span class="source-line-no">053</span><span id="line-53">        .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
+<span class="source-line-no">054</span><span id="line-54">        .setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount())</span>
+<span class="source-line-no">055</span><span id="line-55">        .setHostAddress(clientMetrics.getHostAddress()).setUserName(clientMetrics.getUserName())</span>
+<span class="source-line-no">056</span><span id="line-56">        .setServiceName(clientMetrics.getServiceName())</span>
+<span class="source-line-no">057</span><span id="line-57">        .setClientVersion(clientMetrics.getClientVersion()).build())</span>
+<span class="source-line-no">058</span><span id="line-58">      .forEach(builder::addClientMetrics);</span>
+<span class="source-line-no">059</span><span id="line-59">    return builder.build();</span>
+<span class="source-line-no">060</span><span id="line-60">  }</span>
+<span class="source-line-no">061</span><span id="line-61"></span>
+<span class="source-line-no">062</span><span id="line-62">  public static UserMetricsBuilder newBuilder(byte[] name) {</span>
+<span class="source-line-no">063</span><span id="line-63">    return new UserMetricsBuilder(name);</span>
+<span class="source-line-no">064</span><span id="line-64">  }</span>
+<span class="source-line-no">065</span><span id="line-65"></span>
+<span class="source-line-no">066</span><span id="line-66">  private final byte[] name;</span>
+<span class="source-line-no">067</span><span id="line-67">  private Map&lt;String, UserMetrics.ClientMetrics&gt; clientMetricsMap = new HashMap&lt;&gt;();</span>
+<span class="source-line-no">068</span><span id="line-68"></span>
+<span class="source-line-no">069</span><span id="line-69">  private UserMetricsBuilder(byte[] name) {</span>
+<span class="source-line-no">070</span><span id="line-70">    this.name = name;</span>
 <span class="source-line-no">071</span><span id="line-71">  }</span>
 <span class="source-line-no">072</span><span id="line-72"></span>
-<span class="source-line-no">073</span><span id="line-73">  public UserMetrics build() {</span>
-<span class="source-line-no">074</span><span id="line-74">    return new UserMetricsImpl(name, clientMetricsMap);</span>
-<span class="source-line-no">075</span><span id="line-75">  }</span>
-<span class="source-line-no">076</span><span id="line-76"></span>
-<span class="source-line-no">077</span><span id="line-77">  public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {</span>
-<span class="source-line-no">078</span><span id="line-78">    private final long filteredReadRequestsCount;</span>
-<span class="source-line-no">079</span><span id="line-79">    private final String hostName;</span>
-<span class="source-line-no">080</span><span id="line-80">    private final long readRequestCount;</span>
-<span class="source-line-no">081</span><span id="line-81">    private final long writeRequestCount;</span>
-<span class="source-line-no">082</span><span id="line-82"></span>
-<span class="source-line-no">083</span><span id="line-83">    public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,</span>
-<span class="source-line-no">084</span><span id="line-84">      long filteredReadRequestsCount) {</span>
-<span class="source-line-no">085</span><span id="line-85">      this.hostName = hostName;</span>
-<span class="source-line-no">086</span><span id="line-86">      this.readRequestCount = readRequest;</span>
-<span class="source-line-no">087</span><span id="line-87">      this.writeRequestCount = writeRequest;</span>
-<span class="source-line-no">088</span><span id="line-88">      this.filteredReadRequestsCount = filteredReadRequestsCount;</span>
-<span class="source-line-no">089</span><span id="line-89">    }</span>
-<span class="source-line-no">090</span><span id="line-90"></span>
-<span class="source-line-no">091</span><span id="line-91">    @Override</span>
-<span class="source-line-no">092</span><span id="line-92">    public String getHostName() {</span>
-<span class="source-line-no">093</span><span id="line-93">      return hostName;</span>
-<span class="source-line-no">094</span><span id="line-94">    }</span>
-<span class="source-line-no">095</span><span id="line-95"></span>
-<span class="source-line-no">096</span><span id="line-96">    @Override</span>
-<span class="source-line-no">097</span><span id="line-97">    public long getReadRequestsCount() {</span>
-<span class="source-line-no">098</span><span id="line-98">      return readRequestCount;</span>
-<span class="source-line-no">099</span><span id="line-99">    }</span>
-<span class="source-line-no">100</span><span id="line-100"></span>
-<span class="source-line-no">101</span><span id="line-101">    @Override</span>
-<span class="source-line-no">102</span><span id="line-102">    public long getWriteRequestsCount() {</span>
-<span class="source-line-no">103</span><span id="line-103">      return writeRequestCount;</span>
-<span class="source-line-no">104</span><span id="line-104">    }</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106">    @Override</span>
-<span class="source-line-no">107</span><span id="line-107">    public long getFilteredReadRequestsCount() {</span>
-<span class="source-line-no">108</span><span id="line-108">      return filteredReadRequestsCount;</span>
-<span class="source-line-no">109</span><span id="line-109">    }</span>
-<span class="source-line-no">110</span><span id="line-110">  }</span>
-<span class="source-line-no">111</span><span id="line-111"></span>
-<span class="source-line-no">112</span><span id="line-112">  private static class UserMetricsImpl implements UserMetrics {</span>
-<span class="source-line-no">113</span><span id="line-113">    private final byte[] name;</span>
-<span class="source-line-no">114</span><span id="line-114">    private final Map&lt;String, ClientMetrics&gt; clientMetricsMap;</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116">    UserMetricsImpl(byte[] name, Map&lt;String, ClientMetrics&gt; clientMetricsMap) {</span>
-<span class="source-line-no">117</span><span id="line-117">      this.name = Preconditions.checkNotNull(name);</span>
-<span class="source-line-no">118</span><span id="line-118">      this.clientMetricsMap = clientMetricsMap;</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">    @Override</span>
-<span class="source-line-no">122</span><span id="line-122">    public byte[] getUserName() {</span>
-<span class="source-line-no">123</span><span id="line-123">      return name;</span>
-<span class="source-line-no">124</span><span id="line-124">    }</span>
-<span class="source-line-no">125</span><span id="line-125"></span>
-<span class="source-line-no">126</span><span id="line-126">    @Override</span>
-<span class="source-line-no">127</span><span id="line-127">    public long getReadRequestCount() {</span>
-<span class="source-line-no">128</span><span id="line-128">      return clientMetricsMap.values().stream().map(c -&gt; c.getReadRequestsCount()).reduce(0L,</span>
-<span class="source-line-no">129</span><span id="line-129">        Long::sum);</span>
-<span class="source-line-no">130</span><span id="line-130">    }</span>
-<span class="source-line-no">131</span><span id="line-131"></span>
-<span class="source-line-no">132</span><span id="line-132">    @Override</span>
-<span class="source-line-no">133</span><span id="line-133">    public long getWriteRequestCount() {</span>
-<span class="source-line-no">134</span><span id="line-134">      return clientMetricsMap.values().stream().map(c -&gt; c.getWriteRequestsCount()).reduce(0L,</span>
-<span class="source-line-no">135</span><span id="line-135">        Long::sum);</span>
-<span class="source-line-no">136</span><span id="line-136">    }</span>
-<span class="source-line-no">137</span><span id="line-137"></span>
-<span class="source-line-no">138</span><span id="line-138">    @Override</span>
-<span class="source-line-no">139</span><span id="line-139">    public Map&lt;String, ClientMetrics&gt; getClientMetrics() {</span>
-<span class="source-line-no">140</span><span id="line-140">      return this.clientMetricsMap;</span>
-<span class="source-line-no">141</span><span id="line-141">    }</span>
-<span class="source-line-no">142</span><span id="line-142"></span>
-<span class="source-line-no">143</span><span id="line-143">    @Override</span>
-<span class="source-line-no">144</span><span id="line-144">    public long getFilteredReadRequests() {</span>
-<span class="source-line-no">145</span><span id="line-145">      return clientMetricsMap.values().stream().map(c -&gt; c.getFilteredReadRequestsCount())</span>
-<span class="source-line-no">146</span><span id="line-146">        .reduce(0L, Long::sum);</span>
-<span class="source-line-no">147</span><span id="line-147">    }</span>
-<span class="source-line-no">148</span><span id="line-148"></span>
-<span class="source-line-no">149</span><span id="line-149">    @Override</span>
-<span class="source-line-no">150</span><span id="line-150">    public String toString() {</span>
-<span class="source-line-no">151</span><span id="line-151">      StringBuilder sb =</span>
-<span class="source-line-no">152</span><span id="line-152">        Strings.appendKeyValue(new StringBuilder(), "readRequestCount", this.getReadRequestCount());</span>
-<span class="source-line-no">153</span><span id="line-153">      Strings.appendKeyValue(sb, "writeRequestCount", this.getWriteRequestCount());</span>
-<span class="source-line-no">154</span><span id="line-154">      Strings.appendKeyValue(sb, "filteredReadRequestCount", this.getFilteredReadRequests());</span>
-<span class="source-line-no">155</span><span id="line-155">      return sb.toString();</span>
-<span class="source-line-no">156</span><span id="line-156">    }</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">}</span>
+<span class="source-line-no">073</span><span id="line-73">  public UserMetricsBuilder addClientMetris(UserMetrics.ClientMetrics clientMetrics) {</span>
+<span class="source-line-no">074</span><span id="line-74">    clientMetricsMap.put(clientMetrics.getHostName(), clientMetrics);</span>
+<span class="source-line-no">075</span><span id="line-75">    return this;</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">  public UserMetrics build() {</span>
+<span class="source-line-no">079</span><span id="line-79">    return new UserMetricsImpl(name, clientMetricsMap);</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">  public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {</span>
+<span class="source-line-no">083</span><span id="line-83">    private final long filteredReadRequestsCount;</span>
+<span class="source-line-no">084</span><span id="line-84">    private final String hostName;</span>
+<span class="source-line-no">085</span><span id="line-85">    private final long readRequestCount;</span>
+<span class="source-line-no">086</span><span id="line-86">    private final long writeRequestCount;</span>
+<span class="source-line-no">087</span><span id="line-87">    private final String hostAddress;</span>
+<span class="source-line-no">088</span><span id="line-88">    private final String userName;</span>
+<span class="source-line-no">089</span><span id="line-89">    private final String serviceName;</span>
+<span class="source-line-no">090</span><span id="line-90">    private final String clientVersion;</span>
+<span class="source-line-no">091</span><span id="line-91"></span>
+<span class="source-line-no">092</span><span id="line-92">    public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,</span>
+<span class="source-line-no">093</span><span id="line-93">      long filteredReadRequestsCount, String hostAddress, String userName, String serviceName,</span>
+<span class="source-line-no">094</span><span id="line-94">      String clientVersion) {</span>
+<span class="source-line-no">095</span><span id="line-95">      this.hostName = hostName;</span>
+<span class="source-line-no">096</span><span id="line-96">      this.readRequestCount = readRequest;</span>
+<span class="source-line-no">097</span><span id="line-97">      this.writeRequestCount = writeRequest;</span>
+<span class="source-line-no">098</span><span id="line-98">      this.filteredReadRequestsCount = filteredReadRequestsCount;</span>
+<span class="source-line-no">099</span><span id="line-99">      this.hostAddress = hostAddress != null ? hostAddress : "Unknown";</span>
+<span class="source-line-no">100</span><span id="line-100">      this.userName = userName != null ? userName : "Unknown";</span>
+<span class="source-line-no">101</span><span id="line-101">      this.serviceName = serviceName != null ? serviceName : "Unknown";</span>
+<span class="source-line-no">102</span><span id="line-102">      this.clientVersion = clientVersion != null ? clientVersion : "Unknown";</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">    @Override</span>
+<span class="source-line-no">106</span><span id="line-106">    public String getHostName() {</span>
+<span class="source-line-no">107</span><span id="line-107">      return hostName;</span>
+<span class="source-line-no">108</span><span id="line-108">    }</span>
+<span class="source-line-no">109</span><span id="line-109"></span>
+<span class="source-line-no">110</span><span id="line-110">    @Override</span>
+<span class="source-line-no">111</span><span id="line-111">    public long getReadRequestsCount() {</span>
+<span class="source-line-no">112</span><span id="line-112">      return readRequestCount;</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">    @Override</span>
+<span class="source-line-no">116</span><span id="line-116">    public long getWriteRequestsCount() {</span>
+<span class="source-line-no">117</span><span id="line-117">      return writeRequestCount;</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">    @Override</span>
+<span class="source-line-no">121</span><span id="line-121">    public long getFilteredReadRequestsCount() {</span>
+<span class="source-line-no">122</span><span id="line-122">      return filteredReadRequestsCount;</span>
+<span class="source-line-no">123</span><span id="line-123">    }</span>
+<span class="source-line-no">124</span><span id="line-124"></span>
+<span class="source-line-no">125</span><span id="line-125">    @Override</span>
+<span class="source-line-no">126</span><span id="line-126">    public String getHostAddress() {</span>
+<span class="source-line-no">127</span><span id="line-127">      return hostAddress;</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">    @Override</span>
+<span class="source-line-no">131</span><span id="line-131">    public String getUserName() {</span>
+<span class="source-line-no">132</span><span id="line-132">      return userName;</span>
+<span class="source-line-no">133</span><span id="line-133">    }</span>
+<span class="source-line-no">134</span><span id="line-134"></span>
+<span class="source-line-no">135</span><span id="line-135">    @Override</span>
+<span class="source-line-no">136</span><span id="line-136">    public String getServiceName() {</span>
+<span class="source-line-no">137</span><span id="line-137">      return serviceName;</span>
+<span class="source-line-no">138</span><span id="line-138">    }</span>
+<span class="source-line-no">139</span><span id="line-139"></span>
+<span class="source-line-no">140</span><span id="line-140">    @Override</span>
+<span class="source-line-no">141</span><span id="line-141">    public String getClientVersion() {</span>
+<span class="source-line-no">142</span><span id="line-142">      return clientVersion;</span>
+<span class="source-line-no">143</span><span id="line-143">    }</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">  private static class UserMetricsImpl implements UserMetrics {</span>
+<span class="source-line-no">147</span><span id="line-147">    private final byte[] name;</span>
+<span class="source-line-no">148</span><span id="line-148">    private final Map&lt;String, ClientMetrics&gt; clientMetricsMap;</span>
+<span class="source-line-no">149</span><span id="line-149"></span>
+<span class="source-line-no">150</span><span id="line-150">    UserMetricsImpl(byte[] name, Map&lt;String, ClientMetrics&gt; clientMetricsMap) {</span>
+<span class="source-line-no">151</span><span id="line-151">      this.name = Preconditions.checkNotNull(name);</span>
+<span class="source-line-no">152</span><span id="line-152">      this.clientMetricsMap = clientMetricsMap;</span>
+<span class="source-line-no">153</span><span id="line-153">    }</span>
+<span class="source-line-no">154</span><span id="line-154"></span>
+<span class="source-line-no">155</span><span id="line-155">    @Override</span>
+<span class="source-line-no">156</span><span id="line-156">    public byte[] getUserName() {</span>
+<span class="source-line-no">157</span><span id="line-157">      return name;</span>
+<span class="source-line-no">158</span><span id="line-158">    }</span>
+<span class="source-line-no">159</span><span id="line-159"></span>
+<span class="source-line-no">160</span><span id="line-160">    @Override</span>
+<span class="source-line-no">161</span><span id="line-161">    public long getReadRequestCount() {</span>
+<span class="source-line-no">162</span><span id="line-162">      return clientMetricsMap.values().stream().map(c -&gt; c.getReadRequestsCount()).reduce(0L,</span>
+<span class="source-line-no">163</span><span id="line-163">        Long::sum);</span>
+<span class="source-line-no">164</span><span id="line-164">    }</span>
+<span class="source-line-no">165</span><span id="line-165"></span>
+<span class="source-line-no">166</span><span id="line-166">    @Override</span>
+<span class="source-line-no">167</span><span id="line-167">    public long getWriteRequestCount() {</span>
+<span class="source-line-no">168</span><span id="line-168">      return clientMetricsMap.values().stream().map(c -&gt; c.getWriteRequestsCount()).reduce(0L,</span>
+<span class="source-line-no">169</span><span id="line-169">        Long::sum);</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">    @Override</span>
+<span class="source-line-no">173</span><span id="line-173">    public Map&lt;String, ClientMetrics&gt; getClientMetrics() {</span>
+<span class="source-line-no">174</span><span id="line-174">      return this.clientMetricsMap;</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>
+<span class="source-line-no">177</span><span id="line-177">    @Override</span>
+<span class="source-line-no">178</span><span id="line-178">    public long getFilteredReadRequests() {</span>
+<span class="source-line-no">179</span><span id="line-179">      return clientMetricsMap.values().stream().map(c -&gt; c.getFilteredReadRequestsCount())</span>
+<span class="source-line-no">180</span><span id="line-180">        .reduce(0L, Long::sum);</span>
+<span class="source-line-no">181</span><span id="line-181">    }</span>
+<span class="source-line-no">182</span><span id="line-182"></span>
+<span class="source-line-no">183</span><span id="line-183">    @Override</span>
+<span class="source-line-no">184</span><span id="line-184">    public String toString() {</span>
+<span class="source-line-no">185</span><span id="line-185">      StringBuilder sb =</span>
+<span class="source-line-no">186</span><span id="line-186">        Strings.appendKeyValue(new StringBuilder(), "readRequestCount", this.getReadRequestCount());</span>
+<span class="source-line-no">187</span><span id="line-187">      Strings.appendKeyValue(sb, "writeRequestCount", this.getWriteRequestCount());</span>
+<span class="source-line-no">188</span><span id="line-188">      Strings.appendKeyValue(sb, "filteredReadRequestCount", this.getFilteredReadRequests());</span>
+<span class="source-line-no">189</span><span id="line-189">      return sb.toString();</span>
+<span class="source-line-no">190</span><span id="line-190">    }</span>
+<span class="source-line-no">191</span><span id="line-191">  }</span>
+<span class="source-line-no">192</span><span id="line-192"></span>
+<span class="source-line-no">193</span><span id="line-193">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.html b/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.html
index 3188086f344..a40dd4aea92 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.html
@@ -49,127 +49,161 @@
 <span class="source-line-no">036</span><span id="line-36">    userLoad.getClientMetricsList().stream()</span>
 <span class="source-line-no">037</span><span id="line-37">      .map(clientMetrics -&gt; new ClientMetricsImpl(clientMetrics.getHostName(),</span>
 <span class="source-line-no">038</span><span id="line-38">        clientMetrics.getReadRequestsCount(), clientMetrics.getWriteRequestsCount(),</span>
-<span class="source-line-no">039</span><span id="line-39">        clientMetrics.getFilteredRequestsCount()))</span>
-<span class="source-line-no">040</span><span id="line-40">      .forEach(builder::addClientMetris);</span>
-<span class="source-line-no">041</span><span id="line-41">    return builder.build();</span>
-<span class="source-line-no">042</span><span id="line-42">  }</span>
-<span class="source-line-no">043</span><span id="line-43"></span>
-<span class="source-line-no">044</span><span id="line-44">  public static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics) {</span>
-<span class="source-line-no">045</span><span id="line-45">    ClusterStatusProtos.UserLoad.Builder builder =</span>
-<span class="source-line-no">046</span><span id="line-46">      ClusterStatusProtos.UserLoad.newBuilder().setUserName(userMetrics.getNameAsString());</span>
-<span class="source-line-no">047</span><span id="line-47">    userMetrics.getClientMetrics().values().stream()</span>
-<span class="source-line-no">048</span><span id="line-48">      .map(clientMetrics -&gt; ClusterStatusProtos.ClientMetrics.newBuilder()</span>
-<span class="source-line-no">049</span><span id="line-49">        .setHostName(clientMetrics.getHostName())</span>
-<span class="source-line-no">050</span><span id="line-50">        .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
-<span class="source-line-no">051</span><span id="line-51">        .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
-<span class="source-line-no">052</span><span id="line-52">        .setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount()).build())</span>
-<span class="source-line-no">053</span><span id="line-53">      .forEach(builder::addClientMetrics);</span>
-<span class="source-line-no">054</span><span id="line-54">    return builder.build();</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">  public static UserMetricsBuilder newBuilder(byte[] name) {</span>
-<span class="source-line-no">058</span><span id="line-58">    return new UserMetricsBuilder(name);</span>
-<span class="source-line-no">059</span><span id="line-59">  }</span>
-<span class="source-line-no">060</span><span id="line-60"></span>
-<span class="source-line-no">061</span><span id="line-61">  private final byte[] name;</span>
-<span class="source-line-no">062</span><span id="line-62">  private Map&lt;String, UserMetrics.ClientMetrics&gt; clientMetricsMap = new HashMap&lt;&gt;();</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 UserMetricsBuilder(byte[] name) {</span>
-<span class="source-line-no">065</span><span id="line-65">    this.name = name;</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">  public UserMetricsBuilder addClientMetris(UserMetrics.ClientMetrics clientMetrics) {</span>
-<span class="source-line-no">069</span><span id="line-69">    clientMetricsMap.put(clientMetrics.getHostName(), clientMetrics);</span>
-<span class="source-line-no">070</span><span id="line-70">    return this;</span>
+<span class="source-line-no">039</span><span id="line-39">        clientMetrics.getFilteredRequestsCount(), clientMetrics.getHostAddress(),</span>
+<span class="source-line-no">040</span><span id="line-40">        clientMetrics.getUserName(), clientMetrics.getServiceName(),</span>
+<span class="source-line-no">041</span><span id="line-41">        clientMetrics.getClientVersion()))</span>
+<span class="source-line-no">042</span><span id="line-42">      .forEach(builder::addClientMetris);</span>
+<span class="source-line-no">043</span><span id="line-43">    return builder.build();</span>
+<span class="source-line-no">044</span><span id="line-44">  }</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 static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics) {</span>
+<span class="source-line-no">047</span><span id="line-47">    ClusterStatusProtos.UserLoad.Builder builder =</span>
+<span class="source-line-no">048</span><span id="line-48">      ClusterStatusProtos.UserLoad.newBuilder().setUserName(userMetrics.getNameAsString());</span>
+<span class="source-line-no">049</span><span id="line-49">    userMetrics.getClientMetrics().values().stream()</span>
+<span class="source-line-no">050</span><span id="line-50">      .map(clientMetrics -&gt; ClusterStatusProtos.ClientMetrics.newBuilder()</span>
+<span class="source-line-no">051</span><span id="line-51">        .setHostName(clientMetrics.getHostName())</span>
+<span class="source-line-no">052</span><span id="line-52">        .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
+<span class="source-line-no">053</span><span id="line-53">        .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
+<span class="source-line-no">054</span><span id="line-54">        .setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount())</span>
+<span class="source-line-no">055</span><span id="line-55">        .setHostAddress(clientMetrics.getHostAddress()).setUserName(clientMetrics.getUserName())</span>
+<span class="source-line-no">056</span><span id="line-56">        .setServiceName(clientMetrics.getServiceName())</span>
+<span class="source-line-no">057</span><span id="line-57">        .setClientVersion(clientMetrics.getClientVersion()).build())</span>
+<span class="source-line-no">058</span><span id="line-58">      .forEach(builder::addClientMetrics);</span>
+<span class="source-line-no">059</span><span id="line-59">    return builder.build();</span>
+<span class="source-line-no">060</span><span id="line-60">  }</span>
+<span class="source-line-no">061</span><span id="line-61"></span>
+<span class="source-line-no">062</span><span id="line-62">  public static UserMetricsBuilder newBuilder(byte[] name) {</span>
+<span class="source-line-no">063</span><span id="line-63">    return new UserMetricsBuilder(name);</span>
+<span class="source-line-no">064</span><span id="line-64">  }</span>
+<span class="source-line-no">065</span><span id="line-65"></span>
+<span class="source-line-no">066</span><span id="line-66">  private final byte[] name;</span>
+<span class="source-line-no">067</span><span id="line-67">  private Map&lt;String, UserMetrics.ClientMetrics&gt; clientMetricsMap = new HashMap&lt;&gt;();</span>
+<span class="source-line-no">068</span><span id="line-68"></span>
+<span class="source-line-no">069</span><span id="line-69">  private UserMetricsBuilder(byte[] name) {</span>
+<span class="source-line-no">070</span><span id="line-70">    this.name = name;</span>
 <span class="source-line-no">071</span><span id="line-71">  }</span>
 <span class="source-line-no">072</span><span id="line-72"></span>
-<span class="source-line-no">073</span><span id="line-73">  public UserMetrics build() {</span>
-<span class="source-line-no">074</span><span id="line-74">    return new UserMetricsImpl(name, clientMetricsMap);</span>
-<span class="source-line-no">075</span><span id="line-75">  }</span>
-<span class="source-line-no">076</span><span id="line-76"></span>
-<span class="source-line-no">077</span><span id="line-77">  public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {</span>
-<span class="source-line-no">078</span><span id="line-78">    private final long filteredReadRequestsCount;</span>
-<span class="source-line-no">079</span><span id="line-79">    private final String hostName;</span>
-<span class="source-line-no">080</span><span id="line-80">    private final long readRequestCount;</span>
-<span class="source-line-no">081</span><span id="line-81">    private final long writeRequestCount;</span>
-<span class="source-line-no">082</span><span id="line-82"></span>
-<span class="source-line-no">083</span><span id="line-83">    public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,</span>
-<span class="source-line-no">084</span><span id="line-84">      long filteredReadRequestsCount) {</span>
-<span class="source-line-no">085</span><span id="line-85">      this.hostName = hostName;</span>
-<span class="source-line-no">086</span><span id="line-86">      this.readRequestCount = readRequest;</span>
-<span class="source-line-no">087</span><span id="line-87">      this.writeRequestCount = writeRequest;</span>
-<span class="source-line-no">088</span><span id="line-88">      this.filteredReadRequestsCount = filteredReadRequestsCount;</span>
-<span class="source-line-no">089</span><span id="line-89">    }</span>
-<span class="source-line-no">090</span><span id="line-90"></span>
-<span class="source-line-no">091</span><span id="line-91">    @Override</span>
-<span class="source-line-no">092</span><span id="line-92">    public String getHostName() {</span>
-<span class="source-line-no">093</span><span id="line-93">      return hostName;</span>
-<span class="source-line-no">094</span><span id="line-94">    }</span>
-<span class="source-line-no">095</span><span id="line-95"></span>
-<span class="source-line-no">096</span><span id="line-96">    @Override</span>
-<span class="source-line-no">097</span><span id="line-97">    public long getReadRequestsCount() {</span>
-<span class="source-line-no">098</span><span id="line-98">      return readRequestCount;</span>
-<span class="source-line-no">099</span><span id="line-99">    }</span>
-<span class="source-line-no">100</span><span id="line-100"></span>
-<span class="source-line-no">101</span><span id="line-101">    @Override</span>
-<span class="source-line-no">102</span><span id="line-102">    public long getWriteRequestsCount() {</span>
-<span class="source-line-no">103</span><span id="line-103">      return writeRequestCount;</span>
-<span class="source-line-no">104</span><span id="line-104">    }</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106">    @Override</span>
-<span class="source-line-no">107</span><span id="line-107">    public long getFilteredReadRequestsCount() {</span>
-<span class="source-line-no">108</span><span id="line-108">      return filteredReadRequestsCount;</span>
-<span class="source-line-no">109</span><span id="line-109">    }</span>
-<span class="source-line-no">110</span><span id="line-110">  }</span>
-<span class="source-line-no">111</span><span id="line-111"></span>
-<span class="source-line-no">112</span><span id="line-112">  private static class UserMetricsImpl implements UserMetrics {</span>
-<span class="source-line-no">113</span><span id="line-113">    private final byte[] name;</span>
-<span class="source-line-no">114</span><span id="line-114">    private final Map&lt;String, ClientMetrics&gt; clientMetricsMap;</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116">    UserMetricsImpl(byte[] name, Map&lt;String, ClientMetrics&gt; clientMetricsMap) {</span>
-<span class="source-line-no">117</span><span id="line-117">      this.name = Preconditions.checkNotNull(name);</span>
-<span class="source-line-no">118</span><span id="line-118">      this.clientMetricsMap = clientMetricsMap;</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">    @Override</span>
-<span class="source-line-no">122</span><span id="line-122">    public byte[] getUserName() {</span>
-<span class="source-line-no">123</span><span id="line-123">      return name;</span>
-<span class="source-line-no">124</span><span id="line-124">    }</span>
-<span class="source-line-no">125</span><span id="line-125"></span>
-<span class="source-line-no">126</span><span id="line-126">    @Override</span>
-<span class="source-line-no">127</span><span id="line-127">    public long getReadRequestCount() {</span>
-<span class="source-line-no">128</span><span id="line-128">      return clientMetricsMap.values().stream().map(c -&gt; c.getReadRequestsCount()).reduce(0L,</span>
-<span class="source-line-no">129</span><span id="line-129">        Long::sum);</span>
-<span class="source-line-no">130</span><span id="line-130">    }</span>
-<span class="source-line-no">131</span><span id="line-131"></span>
-<span class="source-line-no">132</span><span id="line-132">    @Override</span>
-<span class="source-line-no">133</span><span id="line-133">    public long getWriteRequestCount() {</span>
-<span class="source-line-no">134</span><span id="line-134">      return clientMetricsMap.values().stream().map(c -&gt; c.getWriteRequestsCount()).reduce(0L,</span>
-<span class="source-line-no">135</span><span id="line-135">        Long::sum);</span>
-<span class="source-line-no">136</span><span id="line-136">    }</span>
-<span class="source-line-no">137</span><span id="line-137"></span>
-<span class="source-line-no">138</span><span id="line-138">    @Override</span>
-<span class="source-line-no">139</span><span id="line-139">    public Map&lt;String, ClientMetrics&gt; getClientMetrics() {</span>
-<span class="source-line-no">140</span><span id="line-140">      return this.clientMetricsMap;</span>
-<span class="source-line-no">141</span><span id="line-141">    }</span>
-<span class="source-line-no">142</span><span id="line-142"></span>
-<span class="source-line-no">143</span><span id="line-143">    @Override</span>
-<span class="source-line-no">144</span><span id="line-144">    public long getFilteredReadRequests() {</span>
-<span class="source-line-no">145</span><span id="line-145">      return clientMetricsMap.values().stream().map(c -&gt; c.getFilteredReadRequestsCount())</span>
-<span class="source-line-no">146</span><span id="line-146">        .reduce(0L, Long::sum);</span>
-<span class="source-line-no">147</span><span id="line-147">    }</span>
-<span class="source-line-no">148</span><span id="line-148"></span>
-<span class="source-line-no">149</span><span id="line-149">    @Override</span>
-<span class="source-line-no">150</span><span id="line-150">    public String toString() {</span>
-<span class="source-line-no">151</span><span id="line-151">      StringBuilder sb =</span>
-<span class="source-line-no">152</span><span id="line-152">        Strings.appendKeyValue(new StringBuilder(), "readRequestCount", this.getReadRequestCount());</span>
-<span class="source-line-no">153</span><span id="line-153">      Strings.appendKeyValue(sb, "writeRequestCount", this.getWriteRequestCount());</span>
-<span class="source-line-no">154</span><span id="line-154">      Strings.appendKeyValue(sb, "filteredReadRequestCount", this.getFilteredReadRequests());</span>
-<span class="source-line-no">155</span><span id="line-155">      return sb.toString();</span>
-<span class="source-line-no">156</span><span id="line-156">    }</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">}</span>
+<span class="source-line-no">073</span><span id="line-73">  public UserMetricsBuilder addClientMetris(UserMetrics.ClientMetrics clientMetrics) {</span>
+<span class="source-line-no">074</span><span id="line-74">    clientMetricsMap.put(clientMetrics.getHostName(), clientMetrics);</span>
+<span class="source-line-no">075</span><span id="line-75">    return this;</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">  public UserMetrics build() {</span>
+<span class="source-line-no">079</span><span id="line-79">    return new UserMetricsImpl(name, clientMetricsMap);</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">  public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {</span>
+<span class="source-line-no">083</span><span id="line-83">    private final long filteredReadRequestsCount;</span>
+<span class="source-line-no">084</span><span id="line-84">    private final String hostName;</span>
+<span class="source-line-no">085</span><span id="line-85">    private final long readRequestCount;</span>
+<span class="source-line-no">086</span><span id="line-86">    private final long writeRequestCount;</span>
+<span class="source-line-no">087</span><span id="line-87">    private final String hostAddress;</span>
+<span class="source-line-no">088</span><span id="line-88">    private final String userName;</span>
+<span class="source-line-no">089</span><span id="line-89">    private final String serviceName;</span>
+<span class="source-line-no">090</span><span id="line-90">    private final String clientVersion;</span>
+<span class="source-line-no">091</span><span id="line-91"></span>
+<span class="source-line-no">092</span><span id="line-92">    public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,</span>
+<span class="source-line-no">093</span><span id="line-93">      long filteredReadRequestsCount, String hostAddress, String userName, String serviceName,</span>
+<span class="source-line-no">094</span><span id="line-94">      String clientVersion) {</span>
+<span class="source-line-no">095</span><span id="line-95">      this.hostName = hostName;</span>
+<span class="source-line-no">096</span><span id="line-96">      this.readRequestCount = readRequest;</span>
+<span class="source-line-no">097</span><span id="line-97">      this.writeRequestCount = writeRequest;</span>
+<span class="source-line-no">098</span><span id="line-98">      this.filteredReadRequestsCount = filteredReadRequestsCount;</span>
+<span class="source-line-no">099</span><span id="line-99">      this.hostAddress = hostAddress != null ? hostAddress : "Unknown";</span>
+<span class="source-line-no">100</span><span id="line-100">      this.userName = userName != null ? userName : "Unknown";</span>
+<span class="source-line-no">101</span><span id="line-101">      this.serviceName = serviceName != null ? serviceName : "Unknown";</span>
+<span class="source-line-no">102</span><span id="line-102">      this.clientVersion = clientVersion != null ? clientVersion : "Unknown";</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">    @Override</span>
+<span class="source-line-no">106</span><span id="line-106">    public String getHostName() {</span>
+<span class="source-line-no">107</span><span id="line-107">      return hostName;</span>
+<span class="source-line-no">108</span><span id="line-108">    }</span>
+<span class="source-line-no">109</span><span id="line-109"></span>
+<span class="source-line-no">110</span><span id="line-110">    @Override</span>
+<span class="source-line-no">111</span><span id="line-111">    public long getReadRequestsCount() {</span>
+<span class="source-line-no">112</span><span id="line-112">      return readRequestCount;</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">    @Override</span>
+<span class="source-line-no">116</span><span id="line-116">    public long getWriteRequestsCount() {</span>
+<span class="source-line-no">117</span><span id="line-117">      return writeRequestCount;</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">    @Override</span>
+<span class="source-line-no">121</span><span id="line-121">    public long getFilteredReadRequestsCount() {</span>
+<span class="source-line-no">122</span><span id="line-122">      return filteredReadRequestsCount;</span>
+<span class="source-line-no">123</span><span id="line-123">    }</span>
+<span class="source-line-no">124</span><span id="line-124"></span>
+<span class="source-line-no">125</span><span id="line-125">    @Override</span>
+<span class="source-line-no">126</span><span id="line-126">    public String getHostAddress() {</span>
+<span class="source-line-no">127</span><span id="line-127">      return hostAddress;</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">    @Override</span>
+<span class="source-line-no">131</span><span id="line-131">    public String getUserName() {</span>
+<span class="source-line-no">132</span><span id="line-132">      return userName;</span>
+<span class="source-line-no">133</span><span id="line-133">    }</span>
+<span class="source-line-no">134</span><span id="line-134"></span>
+<span class="source-line-no">135</span><span id="line-135">    @Override</span>
+<span class="source-line-no">136</span><span id="line-136">    public String getServiceName() {</span>
+<span class="source-line-no">137</span><span id="line-137">      return serviceName;</span>
+<span class="source-line-no">138</span><span id="line-138">    }</span>
+<span class="source-line-no">139</span><span id="line-139"></span>
+<span class="source-line-no">140</span><span id="line-140">    @Override</span>
+<span class="source-line-no">141</span><span id="line-141">    public String getClientVersion() {</span>
+<span class="source-line-no">142</span><span id="line-142">      return clientVersion;</span>
+<span class="source-line-no">143</span><span id="line-143">    }</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">  private static class UserMetricsImpl implements UserMetrics {</span>
+<span class="source-line-no">147</span><span id="line-147">    private final byte[] name;</span>
+<span class="source-line-no">148</span><span id="line-148">    private final Map&lt;String, ClientMetrics&gt; clientMetricsMap;</span>
+<span class="source-line-no">149</span><span id="line-149"></span>
+<span class="source-line-no">150</span><span id="line-150">    UserMetricsImpl(byte[] name, Map&lt;String, ClientMetrics&gt; clientMetricsMap) {</span>
+<span class="source-line-no">151</span><span id="line-151">      this.name = Preconditions.checkNotNull(name);</span>
+<span class="source-line-no">152</span><span id="line-152">      this.clientMetricsMap = clientMetricsMap;</span>
+<span class="source-line-no">153</span><span id="line-153">    }</span>
+<span class="source-line-no">154</span><span id="line-154"></span>
+<span class="source-line-no">155</span><span id="line-155">    @Override</span>
+<span class="source-line-no">156</span><span id="line-156">    public byte[] getUserName() {</span>
+<span class="source-line-no">157</span><span id="line-157">      return name;</span>
+<span class="source-line-no">158</span><span id="line-158">    }</span>
+<span class="source-line-no">159</span><span id="line-159"></span>
+<span class="source-line-no">160</span><span id="line-160">    @Override</span>
+<span class="source-line-no">161</span><span id="line-161">    public long getReadRequestCount() {</span>
+<span class="source-line-no">162</span><span id="line-162">      return clientMetricsMap.values().stream().map(c -&gt; c.getReadRequestsCount()).reduce(0L,</span>
+<span class="source-line-no">163</span><span id="line-163">        Long::sum);</span>
+<span class="source-line-no">164</span><span id="line-164">    }</span>
+<span class="source-line-no">165</span><span id="line-165"></span>
+<span class="source-line-no">166</span><span id="line-166">    @Override</span>
+<span class="source-line-no">167</span><span id="line-167">    public long getWriteRequestCount() {</span>
+<span class="source-line-no">168</span><span id="line-168">      return clientMetricsMap.values().stream().map(c -&gt; c.getWriteRequestsCount()).reduce(0L,</span>
+<span class="source-line-no">169</span><span id="line-169">        Long::sum);</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">    @Override</span>
+<span class="source-line-no">173</span><span id="line-173">    public Map&lt;String, ClientMetrics&gt; getClientMetrics() {</span>
+<span class="source-line-no">174</span><span id="line-174">      return this.clientMetricsMap;</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>
+<span class="source-line-no">177</span><span id="line-177">    @Override</span>
+<span class="source-line-no">178</span><span id="line-178">    public long getFilteredReadRequests() {</span>
+<span class="source-line-no">179</span><span id="line-179">      return clientMetricsMap.values().stream().map(c -&gt; c.getFilteredReadRequestsCount())</span>
+<span class="source-line-no">180</span><span id="line-180">        .reduce(0L, Long::sum);</span>
+<span class="source-line-no">181</span><span id="line-181">    }</span>
+<span class="source-line-no">182</span><span id="line-182"></span>
+<span class="source-line-no">183</span><span id="line-183">    @Override</span>
+<span class="source-line-no">184</span><span id="line-184">    public String toString() {</span>
+<span class="source-line-no">185</span><span id="line-185">      StringBuilder sb =</span>
+<span class="source-line-no">186</span><span id="line-186">        Strings.appendKeyValue(new StringBuilder(), "readRequestCount", this.getReadRequestCount());</span>
+<span class="source-line-no">187</span><span id="line-187">      Strings.appendKeyValue(sb, "writeRequestCount", this.getWriteRequestCount());</span>
+<span class="source-line-no">188</span><span id="line-188">      Strings.appendKeyValue(sb, "filteredReadRequestCount", this.getFilteredReadRequests());</span>
+<span class="source-line-no">189</span><span id="line-189">      return sb.toString();</span>
+<span class="source-line-no">190</span><span id="line-190">    }</span>
+<span class="source-line-no">191</span><span id="line-191">  }</span>
+<span class="source-line-no">192</span><span id="line-192"></span>
+<span class="source-line-no">193</span><span id="line-193">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/hbtop/field/Field.html b/apidocs/src-html/org/apache/hadoop/hbase/hbtop/field/Field.html
index 3d4d2aeb3f0..b5f84327b71 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/hbtop/field/Field.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/hbtop/field/Field.html
@@ -71,47 +71,51 @@
 <span class="source-line-no">058</span><span id="line-58">  MAX_HEAP_SIZE("MHEAP", "Max Heap Size", false, false, FieldValueType.SIZE),</span>
 <span class="source-line-no">059</span><span id="line-59">  CLIENT_COUNT("#CLIENT", "Client Count", false, false, FieldValueType.INTEGER),</span>
 <span class="source-line-no">060</span><span id="line-60">  USER_COUNT("#USER", "User Count", false, false, FieldValueType.INTEGER),</span>
-<span class="source-line-no">061</span><span id="line-61">  CLIENT("CLIENT", "Client Hostname", true, true, FieldValueType.STRING);</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 final String header;</span>
-<span class="source-line-no">064</span><span id="line-64">  private final String description;</span>
-<span class="source-line-no">065</span><span id="line-65">  private final boolean autoAdjust;</span>
-<span class="source-line-no">066</span><span id="line-66">  private final boolean leftJustify;</span>
-<span class="source-line-no">067</span><span id="line-67">  private final FieldValueType fieldValueType;</span>
-<span class="source-line-no">068</span><span id="line-68"></span>
-<span class="source-line-no">069</span><span id="line-69">  Field(String header, String description, boolean autoAdjust, boolean leftJustify,</span>
-<span class="source-line-no">070</span><span id="line-70">    FieldValueType fieldValueType) {</span>
-<span class="source-line-no">071</span><span id="line-71">    this.header = Objects.requireNonNull(header);</span>
-<span class="source-line-no">072</span><span id="line-72">    this.description = Objects.requireNonNull(description);</span>
-<span class="source-line-no">073</span><span id="line-73">    this.autoAdjust = autoAdjust;</span>
-<span class="source-line-no">074</span><span id="line-74">    this.leftJustify = leftJustify;</span>
-<span class="source-line-no">075</span><span id="line-75">    this.fieldValueType = Objects.requireNonNull(fieldValueType);</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">  public FieldValue newValue(Object value) {</span>
-<span class="source-line-no">079</span><span id="line-79">    return new FieldValue(value, fieldValueType);</span>
+<span class="source-line-no">061</span><span id="line-61">  CLIENT("CLIENT", "Client Hostname", true, true, FieldValueType.STRING),</span>
+<span class="source-line-no">062</span><span id="line-62">  HOST_ADDRESS("HADDR", "Client Host Address", true, true, FieldValueType.STRING),</span>
+<span class="source-line-no">063</span><span id="line-63">  CLIENT_VERSION("CVER", "Client Version", true, true, FieldValueType.STRING),</span>
+<span class="source-line-no">064</span><span id="line-64">  USER_NAME("USER", "User Name", true, true, FieldValueType.STRING),</span>
+<span class="source-line-no">065</span><span id="line-65">  SERVICE_NAME("SVC", "Service Name", true, true, FieldValueType.STRING);</span>
+<span class="source-line-no">066</span><span id="line-66"></span>
+<span class="source-line-no">067</span><span id="line-67">  private final String header;</span>
+<span class="source-line-no">068</span><span id="line-68">  private final String description;</span>
+<span class="source-line-no">069</span><span id="line-69">  private final boolean autoAdjust;</span>
+<span class="source-line-no">070</span><span id="line-70">  private final boolean leftJustify;</span>
+<span class="source-line-no">071</span><span id="line-71">  private final FieldValueType fieldValueType;</span>
+<span class="source-line-no">072</span><span id="line-72"></span>
+<span class="source-line-no">073</span><span id="line-73">  Field(String header, String description, boolean autoAdjust, boolean leftJustify,</span>
+<span class="source-line-no">074</span><span id="line-74">    FieldValueType fieldValueType) {</span>
+<span class="source-line-no">075</span><span id="line-75">    this.header = Objects.requireNonNull(header);</span>
+<span class="source-line-no">076</span><span id="line-76">    this.description = Objects.requireNonNull(description);</span>
+<span class="source-line-no">077</span><span id="line-77">    this.autoAdjust = autoAdjust;</span>
+<span class="source-line-no">078</span><span id="line-78">    this.leftJustify = leftJustify;</span>
+<span class="source-line-no">079</span><span id="line-79">    this.fieldValueType = Objects.requireNonNull(fieldValueType);</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">  public String getHeader() {</span>
-<span class="source-line-no">083</span><span id="line-83">    return header;</span>
+<span class="source-line-no">082</span><span id="line-82">  public FieldValue newValue(Object value) {</span>
+<span class="source-line-no">083</span><span id="line-83">    return new FieldValue(value, fieldValueType);</span>
 <span class="source-line-no">084</span><span id="line-84">  }</span>
 <span class="source-line-no">085</span><span id="line-85"></span>
-<span class="source-line-no">086</span><span id="line-86">  public String getDescription() {</span>
-<span class="source-line-no">087</span><span id="line-87">    return description;</span>
+<span class="source-line-no">086</span><span id="line-86">  public String getHeader() {</span>
+<span class="source-line-no">087</span><span id="line-87">    return header;</span>
 <span class="source-line-no">088</span><span id="line-88">  }</span>
 <span class="source-line-no">089</span><span id="line-89"></span>
-<span class="source-line-no">090</span><span id="line-90">  public boolean isAutoAdjust() {</span>
-<span class="source-line-no">091</span><span id="line-91">    return autoAdjust;</span>
+<span class="source-line-no">090</span><span id="line-90">  public String getDescription() {</span>
+<span class="source-line-no">091</span><span id="line-91">    return description;</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">  public boolean isLeftJustify() {</span>
-<span class="source-line-no">095</span><span id="line-95">    return leftJustify;</span>
+<span class="source-line-no">094</span><span id="line-94">  public boolean isAutoAdjust() {</span>
+<span class="source-line-no">095</span><span id="line-95">    return autoAdjust;</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">  public FieldValueType getFieldValueType() {</span>
-<span class="source-line-no">099</span><span id="line-99">    return fieldValueType;</span>
+<span class="source-line-no">098</span><span id="line-98">  public boolean isLeftJustify() {</span>
+<span class="source-line-no">099</span><span id="line-99">    return leftJustify;</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">101</span><span id="line-101"></span>
+<span class="source-line-no">102</span><span id="line-102">  public FieldValueType getFieldValueType() {</span>
+<span class="source-line-no">103</span><span id="line-103">    return fieldValueType;</span>
+<span class="source-line-no">104</span><span id="line-104">  }</span>
+<span class="source-line-no">105</span><span id="line-105">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html b/apidocs/src-html/org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html
index 4a9aeb30032..c7111da2117 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html
@@ -61,114 +61,120 @@
 <span class="source-line-no">048</span><span id="line-48">      new FieldInfo(Field.REQUEST_COUNT_PER_SECOND, 10, true),</span>
 <span class="source-line-no">049</span><span id="line-49">      new FieldInfo(Field.READ_REQUEST_COUNT_PER_SECOND, 10, true),</span>
 <span class="source-line-no">050</span><span id="line-50">      new FieldInfo(Field.WRITE_REQUEST_COUNT_PER_SECOND, 10, true),</span>
-<span class="source-line-no">051</span><span id="line-51">      new FieldInfo(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND, 10, true));</span>
-<span class="source-line-no">052</span><span id="line-52">  private final Map&lt;String, RequestCountPerSecond&gt; requestCountPerSecondMap = new HashMap&lt;&gt;();</span>
-<span class="source-line-no">053</span><span id="line-53"></span>
-<span class="source-line-no">054</span><span id="line-54">  ClientModeStrategy() {</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">  @Override</span>
-<span class="source-line-no">058</span><span id="line-58">  public List&lt;FieldInfo&gt; getFieldInfos() {</span>
-<span class="source-line-no">059</span><span id="line-59">    return fieldInfos;</span>
-<span class="source-line-no">060</span><span id="line-60">  }</span>
-<span class="source-line-no">061</span><span id="line-61"></span>
-<span class="source-line-no">062</span><span id="line-62">  @Override</span>
-<span class="source-line-no">063</span><span id="line-63">  public Field getDefaultSortField() {</span>
-<span class="source-line-no">064</span><span id="line-64">    return Field.REQUEST_COUNT_PER_SECOND;</span>
-<span class="source-line-no">065</span><span id="line-65">  }</span>
-<span class="source-line-no">066</span><span id="line-66"></span>
-<span class="source-line-no">067</span><span id="line-67">  @Override</span>
-<span class="source-line-no">068</span><span id="line-68">  public List&lt;Record&gt; getRecords(ClusterMetrics clusterMetrics,</span>
-<span class="source-line-no">069</span><span id="line-69">    List&lt;RecordFilter&gt; pushDownFilters) {</span>
-<span class="source-line-no">070</span><span id="line-70">    List&lt;Record&gt; records = createRecords(clusterMetrics);</span>
-<span class="source-line-no">071</span><span id="line-71">    return aggregateRecordsAndAddDistinct(</span>
-<span class="source-line-no">072</span><span id="line-72">      ModeStrategyUtils.applyFilterAndGet(records, pushDownFilters), Field.CLIENT, Field.USER,</span>
-<span class="source-line-no">073</span><span id="line-73">      Field.USER_COUNT);</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">  List&lt;Record&gt; createRecords(ClusterMetrics clusterMetrics) {</span>
-<span class="source-line-no">077</span><span id="line-77">    List&lt;Record&gt; ret = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">078</span><span id="line-78">    for (ServerMetrics serverMetrics : clusterMetrics.getLiveServerMetrics().values()) {</span>
-<span class="source-line-no">079</span><span id="line-79">      long lastReportTimestamp = serverMetrics.getLastReportTimestamp();</span>
-<span class="source-line-no">080</span><span id="line-80">      serverMetrics.getUserMetrics().values()</span>
-<span class="source-line-no">081</span><span id="line-81">        .forEach(um -&gt; um.getClientMetrics().values()</span>
-<span class="source-line-no">082</span><span id="line-82">          .forEach(clientMetrics -&gt; ret.add(createRecord(um.getNameAsString(), clientMetrics,</span>
-<span class="source-line-no">083</span><span id="line-83">            lastReportTimestamp, serverMetrics.getServerName().getServerName()))));</span>
-<span class="source-line-no">084</span><span id="line-84">    }</span>
-<span class="source-line-no">085</span><span id="line-85">    return ret;</span>
-<span class="source-line-no">086</span><span id="line-86">  }</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">   * Aggregate the records and count the unique values for the given distinctField</span>
-<span class="source-line-no">090</span><span id="line-90">   * @param records               records to be processed</span>
-<span class="source-line-no">091</span><span id="line-91">   * @param groupBy               Field on which group by needs to be done</span>
-<span class="source-line-no">092</span><span id="line-92">   * @param distinctField         Field whose unique values needs to be counted</span>
-<span class="source-line-no">093</span><span id="line-93">   * @param uniqueCountAssignedTo a target field to which the unique count is assigned to</span>
-<span class="source-line-no">094</span><span id="line-94">   * @return aggregated records</span>
-<span class="source-line-no">095</span><span id="line-95">   */</span>
-<span class="source-line-no">096</span><span id="line-96">  List&lt;Record&gt; aggregateRecordsAndAddDistinct(List&lt;Record&gt; records, Field groupBy,</span>
-<span class="source-line-no">097</span><span id="line-97">    Field distinctField, Field uniqueCountAssignedTo) {</span>
-<span class="source-line-no">098</span><span id="line-98">    List&lt;Record&gt; result = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">099</span><span id="line-99">    records.stream().collect(Collectors.groupingBy(r -&gt; r.get(groupBy))).values().forEach(val -&gt; {</span>
-<span class="source-line-no">100</span><span id="line-100">      Set&lt;FieldValue&gt; distinctValues = new HashSet&lt;&gt;();</span>
-<span class="source-line-no">101</span><span id="line-101">      Map&lt;Field, FieldValue&gt; map = new HashMap&lt;&gt;();</span>
-<span class="source-line-no">102</span><span id="line-102">      for (Record record : val) {</span>
-<span class="source-line-no">103</span><span id="line-103">        for (Map.Entry&lt;Field, FieldValue&gt; field : record.entrySet()) {</span>
-<span class="source-line-no">104</span><span id="line-104">          if (distinctField.equals(field.getKey())) {</span>
-<span class="source-line-no">105</span><span id="line-105">            // We will not be adding the field in the new record whose distinct count is required</span>
-<span class="source-line-no">106</span><span id="line-106">            distinctValues.add(record.get(distinctField));</span>
-<span class="source-line-no">107</span><span id="line-107">          } else {</span>
-<span class="source-line-no">108</span><span id="line-108">            if (field.getKey().getFieldValueType() == FieldValueType.STRING) {</span>
-<span class="source-line-no">109</span><span id="line-109">              map.put(field.getKey(), field.getValue());</span>
-<span class="source-line-no">110</span><span id="line-110">            } else {</span>
-<span class="source-line-no">111</span><span id="line-111">              if (map.get(field.getKey()) == null) {</span>
-<span class="source-line-no">112</span><span id="line-112">                map.put(field.getKey(), field.getValue());</span>
-<span class="source-line-no">113</span><span id="line-113">              } else {</span>
-<span class="source-line-no">114</span><span id="line-114">                map.put(field.getKey(), map.get(field.getKey()).plus(field.getValue()));</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">117</span><span id="line-117">          }</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">      // Add unique count field</span>
-<span class="source-line-no">121</span><span id="line-121">      map.put(uniqueCountAssignedTo, uniqueCountAssignedTo.newValue(distinctValues.size()));</span>
-<span class="source-line-no">122</span><span id="line-122">      result.add(</span>
-<span class="source-line-no">123</span><span id="line-123">        Record.ofEntries(map.entrySet().stream().map(k -&gt; Record.entry(k.getKey(), k.getValue()))));</span>
-<span class="source-line-no">124</span><span id="line-124">    });</span>
-<span class="source-line-no">125</span><span id="line-125">    return result;</span>
-<span class="source-line-no">126</span><span id="line-126">  }</span>
-<span class="source-line-no">127</span><span id="line-127"></span>
-<span class="source-line-no">128</span><span id="line-128">  Record createRecord(String user, UserMetrics.ClientMetrics clientMetrics,</span>
-<span class="source-line-no">129</span><span id="line-129">    long lastReportTimestamp, String server) {</span>
-<span class="source-line-no">130</span><span id="line-130">    Record.Builder builder = Record.builder();</span>
-<span class="source-line-no">131</span><span id="line-131">    String client = clientMetrics.getHostName();</span>
-<span class="source-line-no">132</span><span id="line-132">    builder.put(Field.CLIENT, clientMetrics.getHostName());</span>
-<span class="source-line-no">133</span><span id="line-133">    String mapKey = client + "$" + user + "$" + server;</span>
-<span class="source-line-no">134</span><span id="line-134">    RequestCountPerSecond requestCountPerSecond = requestCountPerSecondMap.get(mapKey);</span>
-<span class="source-line-no">135</span><span id="line-135">    if (requestCountPerSecond == null) {</span>
-<span class="source-line-no">136</span><span id="line-136">      requestCountPerSecond = new RequestCountPerSecond();</span>
-<span class="source-line-no">137</span><span id="line-137">      requestCountPerSecondMap.put(mapKey, requestCountPerSecond);</span>
-<span class="source-line-no">138</span><span id="line-138">    }</span>
-<span class="source-line-no">139</span><span id="line-139">    requestCountPerSecond.refresh(lastReportTimestamp, clientMetrics.getReadRequestsCount(),</span>
-<span class="source-line-no">140</span><span id="line-140">      clientMetrics.getFilteredReadRequestsCount(), clientMetrics.getWriteRequestsCount());</span>
-<span class="source-line-no">141</span><span id="line-141">    builder.put(Field.REQUEST_COUNT_PER_SECOND, requestCountPerSecond.getRequestCountPerSecond());</span>
-<span class="source-line-no">142</span><span id="line-142">    builder.put(Field.READ_REQUEST_COUNT_PER_SECOND,</span>
-<span class="source-line-no">143</span><span id="line-143">      requestCountPerSecond.getReadRequestCountPerSecond());</span>
-<span class="source-line-no">144</span><span id="line-144">    builder.put(Field.WRITE_REQUEST_COUNT_PER_SECOND,</span>
-<span class="source-line-no">145</span><span id="line-145">      requestCountPerSecond.getWriteRequestCountPerSecond());</span>
-<span class="source-line-no">146</span><span id="line-146">    builder.put(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND,</span>
-<span class="source-line-no">147</span><span id="line-147">      requestCountPerSecond.getFilteredReadRequestCountPerSecond());</span>
-<span class="source-line-no">148</span><span id="line-148">    builder.put(Field.USER, user);</span>
-<span class="source-line-no">149</span><span id="line-149">    return builder.build();</span>
-<span class="source-line-no">150</span><span id="line-150">  }</span>
-<span class="source-line-no">151</span><span id="line-151"></span>
-<span class="source-line-no">152</span><span id="line-152">  @Override</span>
-<span class="source-line-no">153</span><span id="line-153">  public DrillDownInfo drillDown(Record selectedRecord) {</span>
-<span class="source-line-no">154</span><span id="line-154">    List&lt;RecordFilter&gt; initialFilters = Collections.singletonList(</span>
-<span class="source-line-no">155</span><span id="line-155">      RecordFilter.newBuilder(Field.CLIENT).doubleEquals(selectedRecord.get(Field.CLIENT)));</span>
-<span class="source-line-no">156</span><span id="line-156">    return new DrillDownInfo(Mode.USER, initialFilters);</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">051</span><span id="line-51">      new FieldInfo(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND, 10, true),</span>
+<span class="source-line-no">052</span><span id="line-52">      new FieldInfo(Field.HOST_ADDRESS, 0, true), new FieldInfo(Field.USER_NAME, 0, true),</span>
+<span class="source-line-no">053</span><span id="line-53">      new FieldInfo(Field.CLIENT_VERSION, 0, true), new FieldInfo(Field.SERVICE_NAME, 0, true));</span>
+<span class="source-line-no">054</span><span id="line-54">  private final Map&lt;String, RequestCountPerSecond&gt; requestCountPerSecondMap = new HashMap&lt;&gt;();</span>
+<span class="source-line-no">055</span><span id="line-55"></span>
+<span class="source-line-no">056</span><span id="line-56">  ClientModeStrategy() {</span>
+<span class="source-line-no">057</span><span id="line-57">  }</span>
+<span class="source-line-no">058</span><span id="line-58"></span>
+<span class="source-line-no">059</span><span id="line-59">  @Override</span>
+<span class="source-line-no">060</span><span id="line-60">  public List&lt;FieldInfo&gt; getFieldInfos() {</span>
+<span class="source-line-no">061</span><span id="line-61">    return fieldInfos;</span>
+<span class="source-line-no">062</span><span id="line-62">  }</span>
+<span class="source-line-no">063</span><span id="line-63"></span>
+<span class="source-line-no">064</span><span id="line-64">  @Override</span>
+<span class="source-line-no">065</span><span id="line-65">  public Field getDefaultSortField() {</span>
+<span class="source-line-no">066</span><span id="line-66">    return Field.REQUEST_COUNT_PER_SECOND;</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">  @Override</span>
+<span class="source-line-no">070</span><span id="line-70">  public List&lt;Record&gt; getRecords(ClusterMetrics clusterMetrics,</span>
+<span class="source-line-no">071</span><span id="line-71">    List&lt;RecordFilter&gt; pushDownFilters) {</span>
+<span class="source-line-no">072</span><span id="line-72">    List&lt;Record&gt; records = createRecords(clusterMetrics);</span>
+<span class="source-line-no">073</span><span id="line-73">    return aggregateRecordsAndAddDistinct(</span>
+<span class="source-line-no">074</span><span id="line-74">      ModeStrategyUtils.applyFilterAndGet(records, pushDownFilters), Field.CLIENT, Field.USER,</span>
+<span class="source-line-no">075</span><span id="line-75">      Field.USER_COUNT);</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">  List&lt;Record&gt; createRecords(ClusterMetrics clusterMetrics) {</span>
+<span class="source-line-no">079</span><span id="line-79">    List&lt;Record&gt; ret = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">080</span><span id="line-80">    for (ServerMetrics serverMetrics : clusterMetrics.getLiveServerMetrics().values()) {</span>
+<span class="source-line-no">081</span><span id="line-81">      long lastReportTimestamp = serverMetrics.getLastReportTimestamp();</span>
+<span class="source-line-no">082</span><span id="line-82">      serverMetrics.getUserMetrics().values()</span>
+<span class="source-line-no">083</span><span id="line-83">        .forEach(um -&gt; um.getClientMetrics().values()</span>
+<span class="source-line-no">084</span><span id="line-84">          .forEach(clientMetrics -&gt; ret.add(createRecord(um.getNameAsString(), clientMetrics,</span>
+<span class="source-line-no">085</span><span id="line-85">            lastReportTimestamp, serverMetrics.getServerName().getServerName()))));</span>
+<span class="source-line-no">086</span><span id="line-86">    }</span>
+<span class="source-line-no">087</span><span id="line-87">    return ret;</span>
+<span class="source-line-no">088</span><span id="line-88">  }</span>
+<span class="source-line-no">089</span><span id="line-89"></span>
+<span class="source-line-no">090</span><span id="line-90">  /**</span>
+<span class="source-line-no">091</span><span id="line-91">   * Aggregate the records and count the unique values for the given distinctField</span>
+<span class="source-line-no">092</span><span id="line-92">   * @param records               records to be processed</span>
+<span class="source-line-no">093</span><span id="line-93">   * @param groupBy               Field on which group by needs to be done</span>
+<span class="source-line-no">094</span><span id="line-94">   * @param distinctField         Field whose unique values needs to be counted</span>
+<span class="source-line-no">095</span><span id="line-95">   * @param uniqueCountAssignedTo a target field to which the unique count is assigned to</span>
+<span class="source-line-no">096</span><span id="line-96">   * @return aggregated records</span>
+<span class="source-line-no">097</span><span id="line-97">   */</span>
+<span class="source-line-no">098</span><span id="line-98">  List&lt;Record&gt; aggregateRecordsAndAddDistinct(List&lt;Record&gt; records, Field groupBy,</span>
+<span class="source-line-no">099</span><span id="line-99">    Field distinctField, Field uniqueCountAssignedTo) {</span>
+<span class="source-line-no">100</span><span id="line-100">    List&lt;Record&gt; result = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">101</span><span id="line-101">    records.stream().collect(Collectors.groupingBy(r -&gt; r.get(groupBy))).values().forEach(val -&gt; {</span>
+<span class="source-line-no">102</span><span id="line-102">      Set&lt;FieldValue&gt; distinctValues = new HashSet&lt;&gt;();</span>
+<span class="source-line-no">103</span><span id="line-103">      Map&lt;Field, FieldValue&gt; map = new HashMap&lt;&gt;();</span>
+<span class="source-line-no">104</span><span id="line-104">      for (Record record : val) {</span>
+<span class="source-line-no">105</span><span id="line-105">        for (Map.Entry&lt;Field, FieldValue&gt; field : record.entrySet()) {</span>
+<span class="source-line-no">106</span><span id="line-106">          if (distinctField.equals(field.getKey())) {</span>
+<span class="source-line-no">107</span><span id="line-107">            // We will not be adding the field in the new record whose distinct count is required</span>
+<span class="source-line-no">108</span><span id="line-108">            distinctValues.add(record.get(distinctField));</span>
+<span class="source-line-no">109</span><span id="line-109">          } else {</span>
+<span class="source-line-no">110</span><span id="line-110">            if (field.getKey().getFieldValueType() == FieldValueType.STRING) {</span>
+<span class="source-line-no">111</span><span id="line-111">              map.put(field.getKey(), field.getValue());</span>
+<span class="source-line-no">112</span><span id="line-112">            } else {</span>
+<span class="source-line-no">113</span><span id="line-113">              if (map.get(field.getKey()) == null) {</span>
+<span class="source-line-no">114</span><span id="line-114">                map.put(field.getKey(), field.getValue());</span>
+<span class="source-line-no">115</span><span id="line-115">              } else {</span>
+<span class="source-line-no">116</span><span id="line-116">                map.put(field.getKey(), map.get(field.getKey()).plus(field.getValue()));</span>
+<span class="source-line-no">117</span><span id="line-117">              }</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">      }</span>
+<span class="source-line-no">122</span><span id="line-122">      // Add unique count field</span>
+<span class="source-line-no">123</span><span id="line-123">      map.put(uniqueCountAssignedTo, uniqueCountAssignedTo.newValue(distinctValues.size()));</span>
+<span class="source-line-no">124</span><span id="line-124">      result.add(</span>
+<span class="source-line-no">125</span><span id="line-125">        Record.ofEntries(map.entrySet().stream().map(k -&gt; Record.entry(k.getKey(), k.getValue()))));</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 result;</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">  Record createRecord(String user, UserMetrics.ClientMetrics clientMetrics,</span>
+<span class="source-line-no">131</span><span id="line-131">    long lastReportTimestamp, String server) {</span>
+<span class="source-line-no">132</span><span id="line-132">    Record.Builder builder = Record.builder();</span>
+<span class="source-line-no">133</span><span id="line-133">    String client = clientMetrics.getHostName();</span>
+<span class="source-line-no">134</span><span id="line-134">    builder.put(Field.CLIENT, clientMetrics.getHostName());</span>
+<span class="source-line-no">135</span><span id="line-135">    String mapKey = client + "$" + user + "$" + server;</span>
+<span class="source-line-no">136</span><span id="line-136">    RequestCountPerSecond requestCountPerSecond = requestCountPerSecondMap.get(mapKey);</span>
+<span class="source-line-no">137</span><span id="line-137">    if (requestCountPerSecond == null) {</span>
+<span class="source-line-no">138</span><span id="line-138">      requestCountPerSecond = new RequestCountPerSecond();</span>
+<span class="source-line-no">139</span><span id="line-139">      requestCountPerSecondMap.put(mapKey, requestCountPerSecond);</span>
+<span class="source-line-no">140</span><span id="line-140">    }</span>
+<span class="source-line-no">141</span><span id="line-141">    requestCountPerSecond.refresh(lastReportTimestamp, clientMetrics.getReadRequestsCount(),</span>
+<span class="source-line-no">142</span><span id="line-142">      clientMetrics.getFilteredReadRequestsCount(), clientMetrics.getWriteRequestsCount());</span>
+<span class="source-line-no">143</span><span id="line-143">    builder.put(Field.REQUEST_COUNT_PER_SECOND, requestCountPerSecond.getRequestCountPerSecond());</span>
+<span class="source-line-no">144</span><span id="line-144">    builder.put(Field.READ_REQUEST_COUNT_PER_SECOND,</span>
+<span class="source-line-no">145</span><span id="line-145">      requestCountPerSecond.getReadRequestCountPerSecond());</span>
+<span class="source-line-no">146</span><span id="line-146">    builder.put(Field.WRITE_REQUEST_COUNT_PER_SECOND,</span>
+<span class="source-line-no">147</span><span id="line-147">      requestCountPerSecond.getWriteRequestCountPerSecond());</span>
+<span class="source-line-no">148</span><span id="line-148">    builder.put(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND,</span>
+<span class="source-line-no">149</span><span id="line-149">      requestCountPerSecond.getFilteredReadRequestCountPerSecond());</span>
+<span class="source-line-no">150</span><span id="line-150">    builder.put(Field.HOST_ADDRESS, clientMetrics.getHostAddress());</span>
+<span class="source-line-no">151</span><span id="line-151">    builder.put(Field.USER_NAME, clientMetrics.getUserName());</span>
+<span class="source-line-no">152</span><span id="line-152">    builder.put(Field.CLIENT_VERSION, clientMetrics.getClientVersion());</span>
+<span class="source-line-no">153</span><span id="line-153">    builder.put(Field.SERVICE_NAME, clientMetrics.getServiceName());</span>
+<span class="source-line-no">154</span><span id="line-154">    builder.put(Field.USER, user);</span>
+<span class="source-line-no">155</span><span id="line-155">    return builder.build();</span>
+<span class="source-line-no">156</span><span id="line-156">  }</span>
+<span class="source-line-no">157</span><span id="line-157"></span>
+<span class="source-line-no">158</span><span id="line-158">  @Override</span>
+<span class="source-line-no">159</span><span id="line-159">  public DrillDownInfo drillDown(Record selectedRecord) {</span>
+<span class="source-line-no">160</span><span id="line-160">    List&lt;RecordFilter&gt; initialFilters = Collections.singletonList(</span>
+<span class="source-line-no">161</span><span id="line-161">      RecordFilter.newBuilder(Field.CLIENT).doubleEquals(selectedRecord.get(Field.CLIENT)));</span>
+<span class="source-line-no">162</span><span id="line-162">    return new DrillDownInfo(Mode.USER, initialFilters);</span>
+<span class="source-line-no">163</span><span id="line-163">  }</span>
+<span class="source-line-no">164</span><span id="line-164">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.BlockingServiceAndInterface.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.BlockingServiceAndInterface.html
index 7c4dcefa514..f9fff7aeeca 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.BlockingServiceAndInterface.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.BlockingServiceAndInterface.html
@@ -848,104 +848,122 @@
 <span class="source-line-no">835</span><span id="line-835">  }</span>
 <span class="source-line-no">836</span><span id="line-836"></span>
 <span class="source-line-no">837</span><span id="line-837">  /**</span>
-<span class="source-line-no">838</span><span id="line-838">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">839</span><span id="line-839">   * @param services    Available service instances</span>
-<span class="source-line-no">840</span><span id="line-840">   * @return Matching BlockingServiceAndInterface pair</span>
-<span class="source-line-no">841</span><span id="line-841">   */</span>
-<span class="source-line-no">842</span><span id="line-842">  protected static BlockingServiceAndInterface getServiceAndInterface(</span>
-<span class="source-line-no">843</span><span id="line-843">    final List&lt;BlockingServiceAndInterface&gt; services, final String serviceName) {</span>
-<span class="source-line-no">844</span><span id="line-844">    for (BlockingServiceAndInterface bs : services) {</span>
-<span class="source-line-no">845</span><span id="line-845">      if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
-<span class="source-line-no">846</span><span id="line-846">        return bs;</span>
-<span class="source-line-no">847</span><span id="line-847">      }</span>
-<span class="source-line-no">848</span><span id="line-848">    }</span>
-<span class="source-line-no">849</span><span id="line-849">    return null;</span>
-<span class="source-line-no">850</span><span id="line-850">  }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852">  /**</span>
-<span class="source-line-no">853</span><span id="line-853">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">854</span><span id="line-854">   * @param services    Available services and their service interfaces.</span>
-<span class="source-line-no">855</span><span id="line-855">   * @return Service interface class for &lt;code&gt;serviceName&lt;/code&gt;</span>
-<span class="source-line-no">856</span><span id="line-856">   */</span>
-<span class="source-line-no">857</span><span id="line-857">  protected static Class&lt;?&gt; getServiceInterface(final List&lt;BlockingServiceAndInterface&gt; services,</span>
-<span class="source-line-no">858</span><span id="line-858">    final String serviceName) {</span>
-<span class="source-line-no">859</span><span id="line-859">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">860</span><span id="line-860">    return bsasi == null ? null : bsasi.getServiceInterface();</span>
-<span class="source-line-no">861</span><span id="line-861">  }</span>
-<span class="source-line-no">862</span><span id="line-862"></span>
-<span class="source-line-no">863</span><span id="line-863">  /**</span>
-<span class="source-line-no">864</span><span id="line-864">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">865</span><span id="line-865">   * @param services    Available services and their service interfaces.</span>
-<span class="source-line-no">866</span><span id="line-866">   * @return BlockingService that goes with the passed &lt;code&gt;serviceName&lt;/code&gt;</span>
-<span class="source-line-no">867</span><span id="line-867">   */</span>
-<span class="source-line-no">868</span><span id="line-868">  protected static BlockingService getService(final List&lt;BlockingServiceAndInterface&gt; services,</span>
-<span class="source-line-no">869</span><span id="line-869">    final String serviceName) {</span>
-<span class="source-line-no">870</span><span id="line-870">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">871</span><span id="line-871">    return bsasi == null ? null : bsasi.getBlockingService();</span>
-<span class="source-line-no">872</span><span id="line-872">  }</span>
-<span class="source-line-no">873</span><span id="line-873"></span>
-<span class="source-line-no">874</span><span id="line-874">  protected static MonitoredRPCHandler getStatus() {</span>
-<span class="source-line-no">875</span><span id="line-875">    // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
-<span class="source-line-no">876</span><span id="line-876">    MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
-<span class="source-line-no">877</span><span id="line-877">    if (status != null) {</span>
-<span class="source-line-no">878</span><span id="line-878">      return status;</span>
-<span class="source-line-no">879</span><span id="line-879">    }</span>
-<span class="source-line-no">880</span><span id="line-880">    status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
-<span class="source-line-no">881</span><span id="line-881">    status.pause("Waiting for a call");</span>
-<span class="source-line-no">882</span><span id="line-882">    RpcServer.MONITORED_RPC.set(status);</span>
-<span class="source-line-no">883</span><span id="line-883">    return status;</span>
-<span class="source-line-no">884</span><span id="line-884">  }</span>
-<span class="source-line-no">885</span><span id="line-885"></span>
-<span class="source-line-no">886</span><span id="line-886">  /**</span>
-<span class="source-line-no">887</span><span id="line-887">   * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
-<span class="source-line-no">888</span><span id="line-888">   */</span>
-<span class="source-line-no">889</span><span id="line-889">  public static InetAddress getRemoteIp() {</span>
-<span class="source-line-no">890</span><span id="line-890">    RpcCall call = CurCall.get();</span>
-<span class="source-line-no">891</span><span id="line-891">    if (call != null) {</span>
-<span class="source-line-no">892</span><span id="line-892">      return call.getRemoteAddress();</span>
-<span class="source-line-no">893</span><span id="line-893">    }</span>
-<span class="source-line-no">894</span><span id="line-894">    return null;</span>
-<span class="source-line-no">895</span><span id="line-895">  }</span>
-<span class="source-line-no">896</span><span id="line-896"></span>
-<span class="source-line-no">897</span><span id="line-897">  @Override</span>
-<span class="source-line-no">898</span><span id="line-898">  public RpcScheduler getScheduler() {</span>
-<span class="source-line-no">899</span><span id="line-899">    return scheduler;</span>
-<span class="source-line-no">900</span><span id="line-900">  }</span>
-<span class="source-line-no">901</span><span id="line-901"></span>
-<span class="source-line-no">902</span><span id="line-902">  @Override</span>
-<span class="source-line-no">903</span><span id="line-903">  public ByteBuffAllocator getByteBuffAllocator() {</span>
-<span class="source-line-no">904</span><span id="line-904">    return this.bbAllocator;</span>
-<span class="source-line-no">905</span><span id="line-905">  }</span>
-<span class="source-line-no">906</span><span id="line-906"></span>
-<span class="source-line-no">907</span><span id="line-907">  @Override</span>
-<span class="source-line-no">908</span><span id="line-908">  public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
-<span class="source-line-no">909</span><span id="line-909">    this.rsRpcServices = rsRpcServices;</span>
-<span class="source-line-no">910</span><span id="line-910">  }</span>
-<span class="source-line-no">911</span><span id="line-911"></span>
-<span class="source-line-no">912</span><span id="line-912">  @Override</span>
-<span class="source-line-no">913</span><span id="line-913">  public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
-<span class="source-line-no">914</span><span id="line-914">    this.namedQueueRecorder = namedQueueRecorder;</span>
-<span class="source-line-no">915</span><span id="line-915">  }</span>
-<span class="source-line-no">916</span><span id="line-916"></span>
-<span class="source-line-no">917</span><span id="line-917">  protected boolean needAuthorization() {</span>
-<span class="source-line-no">918</span><span id="line-918">    return authorize;</span>
-<span class="source-line-no">919</span><span id="line-919">  }</span>
-<span class="source-line-no">920</span><span id="line-920"></span>
-<span class="source-line-no">921</span><span id="line-921">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">922</span><span id="line-922">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">923</span><span id="line-923">  public List&lt;BlockingServiceAndInterface&gt; getServices() {</span>
-<span class="source-line-no">924</span><span id="line-924">    return services;</span>
-<span class="source-line-no">925</span><span id="line-925">  }</span>
-<span class="source-line-no">926</span><span id="line-926"></span>
-<span class="source-line-no">927</span><span id="line-927">  private void initializeCoprocessorHost(Configuration conf) {</span>
-<span class="source-line-no">928</span><span id="line-928">    this.cpHost = new RpcCoprocessorHost(conf);</span>
-<span class="source-line-no">929</span><span id="line-929">  }</span>
-<span class="source-line-no">930</span><span id="line-930"></span>
-<span class="source-line-no">931</span><span id="line-931">  @Override</span>
-<span class="source-line-no">932</span><span id="line-932">  public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
-<span class="source-line-no">933</span><span id="line-933">    return cpHost;</span>
-<span class="source-line-no">934</span><span id="line-934">  }</span>
-<span class="source-line-no">935</span><span id="line-935">}</span>
+<span class="source-line-no">838</span><span id="line-838">   * Returns the ServerRpcConnection for the current RPC request or not present if no connection is</span>
+<span class="source-line-no">839</span><span id="line-839">   * available. This allows access to connection-level information such as the client's IP address,</span>
+<span class="source-line-no">840</span><span id="line-840">   * authentication details, codec configuration, etc.</span>
+<span class="source-line-no">841</span><span id="line-841">   * &lt;p&gt;</span>
+<span class="source-line-no">842</span><span id="line-842">   * This method should only be called from within an RPC handler thread context.</span>
+<span class="source-line-no">843</span><span id="line-843">   * @return the current ServerRpcConnection, or Optional.empty() if called outside of an RPC</span>
+<span class="source-line-no">844</span><span id="line-844">   *         context</span>
+<span class="source-line-no">845</span><span id="line-845">   */</span>
+<span class="source-line-no">846</span><span id="line-846">  public static Optional&lt;ServerRpcConnection&gt; getCurrentServerRpcConnection() {</span>
+<span class="source-line-no">847</span><span id="line-847">    Optional&lt;RpcCall&gt; call = getCurrentCall();</span>
+<span class="source-line-no">848</span><span id="line-848">    if (call.isPresent() &amp;&amp; call.get() instanceof ServerCall) {</span>
+<span class="source-line-no">849</span><span id="line-849">      ServerCall&lt;?&gt; serverCall = (ServerCall&lt;?&gt;) call.get();</span>
+<span class="source-line-no">850</span><span id="line-850">      return Optional.ofNullable(serverCall.getConnection());</span>
+<span class="source-line-no">851</span><span id="line-851">    }</span>
+<span class="source-line-no">852</span><span id="line-852">    return Optional.empty();</span>
+<span class="source-line-no">853</span><span id="line-853">  }</span>
+<span class="source-line-no">854</span><span id="line-854"></span>
+<span class="source-line-no">855</span><span id="line-855">  /**</span>
+<span class="source-line-no">856</span><span id="line-856">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">857</span><span id="line-857">   * @param services    Available service instances</span>
+<span class="source-line-no">858</span><span id="line-858">   * @return Matching BlockingServiceAndInterface pair</span>
+<span class="source-line-no">859</span><span id="line-859">   */</span>
+<span class="source-line-no">860</span><span id="line-860">  protected static BlockingServiceAndInterface getServiceAndInterface(</span>
+<span class="source-line-no">861</span><span id="line-861">    final List&lt;BlockingServiceAndInterface&gt; services, final String serviceName) {</span>
+<span class="source-line-no">862</span><span id="line-862">    for (BlockingServiceAndInterface bs : services) {</span>
+<span class="source-line-no">863</span><span id="line-863">      if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
+<span class="source-line-no">864</span><span id="line-864">        return bs;</span>
+<span class="source-line-no">865</span><span id="line-865">      }</span>
+<span class="source-line-no">866</span><span id="line-866">    }</span>
+<span class="source-line-no">867</span><span id="line-867">    return null;</span>
+<span class="source-line-no">868</span><span id="line-868">  }</span>
+<span class="source-line-no">869</span><span id="line-869"></span>
+<span class="source-line-no">870</span><span id="line-870">  /**</span>
+<span class="source-line-no">871</span><span id="line-871">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">872</span><span id="line-872">   * @param services    Available services and their service interfaces.</span>
+<span class="source-line-no">873</span><span id="line-873">   * @return Service interface class for &lt;code&gt;serviceName&lt;/code&gt;</span>
+<span class="source-line-no">874</span><span id="line-874">   */</span>
+<span class="source-line-no">875</span><span id="line-875">  protected static Class&lt;?&gt; getServiceInterface(final List&lt;BlockingServiceAndInterface&gt; services,</span>
+<span class="source-line-no">876</span><span id="line-876">    final String serviceName) {</span>
+<span class="source-line-no">877</span><span id="line-877">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">878</span><span id="line-878">    return bsasi == null ? null : bsasi.getServiceInterface();</span>
+<span class="source-line-no">879</span><span id="line-879">  }</span>
+<span class="source-line-no">880</span><span id="line-880"></span>
+<span class="source-line-no">881</span><span id="line-881">  /**</span>
+<span class="source-line-no">882</span><span id="line-882">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">883</span><span id="line-883">   * @param services    Available services and their service interfaces.</span>
+<span class="source-line-no">884</span><span id="line-884">   * @return BlockingService that goes with the passed &lt;code&gt;serviceName&lt;/code&gt;</span>
+<span class="source-line-no">885</span><span id="line-885">   */</span>
+<span class="source-line-no">886</span><span id="line-886">  protected static BlockingService getService(final List&lt;BlockingServiceAndInterface&gt; services,</span>
+<span class="source-line-no">887</span><span id="line-887">    final String serviceName) {</span>
+<span class="source-line-no">888</span><span id="line-888">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">889</span><span id="line-889">    return bsasi == null ? null : bsasi.getBlockingService();</span>
+<span class="source-line-no">890</span><span id="line-890">  }</span>
+<span class="source-line-no">891</span><span id="line-891"></span>
+<span class="source-line-no">892</span><span id="line-892">  protected static MonitoredRPCHandler getStatus() {</span>
+<span class="source-line-no">893</span><span id="line-893">    // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
+<span class="source-line-no">894</span><span id="line-894">    MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
+<span class="source-line-no">895</span><span id="line-895">    if (status != null) {</span>
+<span class="source-line-no">896</span><span id="line-896">      return status;</span>
+<span class="source-line-no">897</span><span id="line-897">    }</span>
+<span class="source-line-no">898</span><span id="line-898">    status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
+<span class="source-line-no">899</span><span id="line-899">    status.pause("Waiting for a call");</span>
+<span class="source-line-no">900</span><span id="line-900">    RpcServer.MONITORED_RPC.set(status);</span>
+<span class="source-line-no">901</span><span id="line-901">    return status;</span>
+<span class="source-line-no">902</span><span id="line-902">  }</span>
+<span class="source-line-no">903</span><span id="line-903"></span>
+<span class="source-line-no">904</span><span id="line-904">  /**</span>
+<span class="source-line-no">905</span><span id="line-905">   * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
+<span class="source-line-no">906</span><span id="line-906">   */</span>
+<span class="source-line-no">907</span><span id="line-907">  public static InetAddress getRemoteIp() {</span>
+<span class="source-line-no">908</span><span id="line-908">    RpcCall call = CurCall.get();</span>
+<span class="source-line-no">909</span><span id="line-909">    if (call != null) {</span>
+<span class="source-line-no">910</span><span id="line-910">      return call.getRemoteAddress();</span>
+<span class="source-line-no">911</span><span id="line-911">    }</span>
+<span class="source-line-no">912</span><span id="line-912">    return null;</span>
+<span class="source-line-no">913</span><span id="line-913">  }</span>
+<span class="source-line-no">914</span><span id="line-914"></span>
+<span class="source-line-no">915</span><span id="line-915">  @Override</span>
+<span class="source-line-no">916</span><span id="line-916">  public RpcScheduler getScheduler() {</span>
+<span class="source-line-no">917</span><span id="line-917">    return scheduler;</span>
+<span class="source-line-no">918</span><span id="line-918">  }</span>
+<span class="source-line-no">919</span><span id="line-919"></span>
+<span class="source-line-no">920</span><span id="line-920">  @Override</span>
+<span class="source-line-no">921</span><span id="line-921">  public ByteBuffAllocator getByteBuffAllocator() {</span>
+<span class="source-line-no">922</span><span id="line-922">    return this.bbAllocator;</span>
+<span class="source-line-no">923</span><span id="line-923">  }</span>
+<span class="source-line-no">924</span><span id="line-924"></span>
+<span class="source-line-no">925</span><span id="line-925">  @Override</span>
+<span class="source-line-no">926</span><span id="line-926">  public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
+<span class="source-line-no">927</span><span id="line-927">    this.rsRpcServices = rsRpcServices;</span>
+<span class="source-line-no">928</span><span id="line-928">  }</span>
+<span class="source-line-no">929</span><span id="line-929"></span>
+<span class="source-line-no">930</span><span id="line-930">  @Override</span>
+<span class="source-line-no">931</span><span id="line-931">  public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
+<span class="source-line-no">932</span><span id="line-932">    this.namedQueueRecorder = namedQueueRecorder;</span>
+<span class="source-line-no">933</span><span id="line-933">  }</span>
+<span class="source-line-no">934</span><span id="line-934"></span>
+<span class="source-line-no">935</span><span id="line-935">  protected boolean needAuthorization() {</span>
+<span class="source-line-no">936</span><span id="line-936">    return authorize;</span>
+<span class="source-line-no">937</span><span id="line-937">  }</span>
+<span class="source-line-no">938</span><span id="line-938"></span>
+<span class="source-line-no">939</span><span id="line-939">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">940</span><span id="line-940">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">941</span><span id="line-941">  public List&lt;BlockingServiceAndInterface&gt; getServices() {</span>
+<span class="source-line-no">942</span><span id="line-942">    return services;</span>
+<span class="source-line-no">943</span><span id="line-943">  }</span>
+<span class="source-line-no">944</span><span id="line-944"></span>
+<span class="source-line-no">945</span><span id="line-945">  private void initializeCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">946</span><span id="line-946">    this.cpHost = new RpcCoprocessorHost(conf);</span>
+<span class="source-line-no">947</span><span id="line-947">  }</span>
+<span class="source-line-no">948</span><span id="line-948"></span>
+<span class="source-line-no">949</span><span id="line-949">  @Override</span>
+<span class="source-line-no">950</span><span id="line-950">  public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
+<span class="source-line-no">951</span><span id="line-951">    return cpHost;</span>
+<span class="source-line-no">952</span><span id="line-952">  }</span>
+<span class="source-line-no">953</span><span id="line-953">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.CallCleanup.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.CallCleanup.html
index 9c08cc84ce8..76832ab3ed3 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.CallCleanup.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.CallCleanup.html
@@ -848,104 +848,122 @@
 <span class="source-line-no">835</span><span id="line-835">  }</span>
 <span class="source-line-no">836</span><span id="line-836"></span>
 <span class="source-line-no">837</span><span id="line-837">  /**</span>
-<span class="source-line-no">838</span><span id="line-838">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">839</span><span id="line-839">   * @param services    Available service instances</span>
-<span class="source-line-no">840</span><span id="line-840">   * @return Matching BlockingServiceAndInterface pair</span>
-<span class="source-line-no">841</span><span id="line-841">   */</span>
-<span class="source-line-no">842</span><span id="line-842">  protected static BlockingServiceAndInterface getServiceAndInterface(</span>
-<span class="source-line-no">843</span><span id="line-843">    final List&lt;BlockingServiceAndInterface&gt; services, final String serviceName) {</span>
-<span class="source-line-no">844</span><span id="line-844">    for (BlockingServiceAndInterface bs : services) {</span>
-<span class="source-line-no">845</span><span id="line-845">      if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
-<span class="source-line-no">846</span><span id="line-846">        return bs;</span>
-<span class="source-line-no">847</span><span id="line-847">      }</span>
-<span class="source-line-no">848</span><span id="line-848">    }</span>
-<span class="source-line-no">849</span><span id="line-849">    return null;</span>
-<span class="source-line-no">850</span><span id="line-850">  }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852">  /**</span>
-<span class="source-line-no">853</span><span id="line-853">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">854</span><span id="line-854">   * @param services    Available services and their service interfaces.</span>
-<span class="source-line-no">855</span><span id="line-855">   * @return Service interface class for &lt;code&gt;serviceName&lt;/code&gt;</span>
-<span class="source-line-no">856</span><span id="line-856">   */</span>
-<span class="source-line-no">857</span><span id="line-857">  protected static Class&lt;?&gt; getServiceInterface(final List&lt;BlockingServiceAndInterface&gt; services,</span>
-<span class="source-line-no">858</span><span id="line-858">    final String serviceName) {</span>
-<span class="source-line-no">859</span><span id="line-859">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">860</span><span id="line-860">    return bsasi == null ? null : bsasi.getServiceInterface();</span>
-<span class="source-line-no">861</span><span id="line-861">  }</span>
-<span class="source-line-no">862</span><span id="line-862"></span>
-<span class="source-line-no">863</span><span id="line-863">  /**</span>
-<span class="source-line-no">864</span><span id="line-864">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">865</span><span id="line-865">   * @param services    Available services and their service interfaces.</span>
-<span class="source-line-no">866</span><span id="line-866">   * @return BlockingService that goes with the passed &lt;code&gt;serviceName&lt;/code&gt;</span>
-<span class="source-line-no">867</span><span id="line-867">   */</span>
-<span class="source-line-no">868</span><span id="line-868">  protected static BlockingService getService(final List&lt;BlockingServiceAndInterface&gt; services,</span>
-<span class="source-line-no">869</span><span id="line-869">    final String serviceName) {</span>
-<span class="source-line-no">870</span><span id="line-870">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">871</span><span id="line-871">    return bsasi == null ? null : bsasi.getBlockingService();</span>
-<span class="source-line-no">872</span><span id="line-872">  }</span>
-<span class="source-line-no">873</span><span id="line-873"></span>
-<span class="source-line-no">874</span><span id="line-874">  protected static MonitoredRPCHandler getStatus() {</span>
-<span class="source-line-no">875</span><span id="line-875">    // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
-<span class="source-line-no">876</span><span id="line-876">    MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
-<span class="source-line-no">877</span><span id="line-877">    if (status != null) {</span>
-<span class="source-line-no">878</span><span id="line-878">      return status;</span>
-<span class="source-line-no">879</span><span id="line-879">    }</span>
-<span class="source-line-no">880</span><span id="line-880">    status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
-<span class="source-line-no">881</span><span id="line-881">    status.pause("Waiting for a call");</span>
-<span class="source-line-no">882</span><span id="line-882">    RpcServer.MONITORED_RPC.set(status);</span>
-<span class="source-line-no">883</span><span id="line-883">    return status;</span>
-<span class="source-line-no">884</span><span id="line-884">  }</span>
-<span class="source-line-no">885</span><span id="line-885"></span>
-<span class="source-line-no">886</span><span id="line-886">  /**</span>
-<span class="source-line-no">887</span><span id="line-887">   * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
-<span class="source-line-no">888</span><span id="line-888">   */</span>
-<span class="source-line-no">889</span><span id="line-889">  public static InetAddress getRemoteIp() {</span>
-<span class="source-line-no">890</span><span id="line-890">    RpcCall call = CurCall.get();</span>
-<span class="source-line-no">891</span><span id="line-891">    if (call != null) {</span>
-<span class="source-line-no">892</span><span id="line-892">      return call.getRemoteAddress();</span>
-<span class="source-line-no">893</span><span id="line-893">    }</span>
-<span class="source-line-no">894</span><span id="line-894">    return null;</span>
-<span class="source-line-no">895</span><span id="line-895">  }</span>
-<span class="source-line-no">896</span><span id="line-896"></span>
-<span class="source-line-no">897</span><span id="line-897">  @Override</span>
-<span class="source-line-no">898</span><span id="line-898">  public RpcScheduler getScheduler() {</span>
-<span class="source-line-no">899</span><span id="line-899">    return scheduler;</span>
-<span class="source-line-no">900</span><span id="line-900">  }</span>
-<span class="source-line-no">901</span><span id="line-901"></span>
-<span class="source-line-no">902</span><span id="line-902">  @Override</span>
-<span class="source-line-no">903</span><span id="line-903">  public ByteBuffAllocator getByteBuffAllocator() {</span>
-<span class="source-line-no">904</span><span id="line-904">    return this.bbAllocator;</span>
-<span class="source-line-no">905</span><span id="line-905">  }</span>
-<span class="source-line-no">906</span><span id="line-906"></span>
-<span class="source-line-no">907</span><span id="line-907">  @Override</span>
-<span class="source-line-no">908</span><span id="line-908">  public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
-<span class="source-line-no">909</span><span id="line-909">    this.rsRpcServices = rsRpcServices;</span>
-<span class="source-line-no">910</span><span id="line-910">  }</span>
-<span class="source-line-no">911</span><span id="line-911"></span>
-<span class="source-line-no">912</span><span id="line-912">  @Override</span>
-<span class="source-line-no">913</span><span id="line-913">  public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
-<span class="source-line-no">914</span><span id="line-914">    this.namedQueueRecorder = namedQueueRecorder;</span>
-<span class="source-line-no">915</span><span id="line-915">  }</span>
-<span class="source-line-no">916</span><span id="line-916"></span>
-<span class="source-line-no">917</span><span id="line-917">  protected boolean needAuthorization() {</span>
-<span class="source-line-no">918</span><span id="line-918">    return authorize;</span>
-<span class="source-line-no">919</span><span id="line-919">  }</span>
-<span class="source-line-no">920</span><span id="line-920"></span>
-<span class="source-line-no">921</span><span id="line-921">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">922</span><span id="line-922">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">923</span><span id="line-923">  public List&lt;BlockingServiceAndInterface&gt; getServices() {</span>
-<span class="source-line-no">924</span><span id="line-924">    return services;</span>
-<span class="source-line-no">925</span><span id="line-925">  }</span>
-<span class="source-line-no">926</span><span id="line-926"></span>
-<span class="source-line-no">927</span><span id="line-927">  private void initializeCoprocessorHost(Configuration conf) {</span>
-<span class="source-line-no">928</span><span id="line-928">    this.cpHost = new RpcCoprocessorHost(conf);</span>
-<span class="source-line-no">929</span><span id="line-929">  }</span>
-<span class="source-line-no">930</span><span id="line-930"></span>
-<span class="source-line-no">931</span><span id="line-931">  @Override</span>
-<span class="source-line-no">932</span><span id="line-932">  public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
-<span class="source-line-no">933</span><span id="line-933">    return cpHost;</span>
-<span class="source-line-no">934</span><span id="line-934">  }</span>
-<span class="source-line-no">935</span><span id="line-935">}</span>
+<span class="source-line-no">838</span><span id="line-838">   * Returns the ServerRpcConnection for the current RPC request or not present if no connection is</span>
+<span class="source-line-no">839</span><span id="line-839">   * available. This allows access to connection-level information such as the client's IP address,</span>
+<span class="source-line-no">840</span><span id="line-840">   * authentication details, codec configuration, etc.</span>
+<span class="source-line-no">841</span><span id="line-841">   * &lt;p&gt;</span>
+<span class="source-line-no">842</span><span id="line-842">   * This method should only be called from within an RPC handler thread context.</span>
+<span class="source-line-no">843</span><span id="line-843">   * @return the current ServerRpcConnection, or Optional.empty() if called outside of an RPC</span>
+<span class="source-line-no">844</span><span id="line-844">   *         context</span>
+<span class="source-line-no">845</span><span id="line-845">   */</span>
+<span class="source-line-no">846</span><span id="line-846">  public static Optional&lt;ServerRpcConnection&gt; getCurrentServerRpcConnection() {</span>
+<span class="source-line-no">847</span><span id="line-847">    Optional&lt;RpcCall&gt; call = getCurrentCall();</span>
+<span class="source-line-no">848</span><span id="line-848">    if (call.isPresent() &amp;&amp; call.get() instanceof ServerCall) {</span>
+<span class="source-line-no">849</span><span id="line-849">      ServerCall&lt;?&gt; serverCall = (ServerCall&lt;?&gt;) call.get();</span>
+<span class="source-line-no">850</span><span id="line-850">      return Optional.ofNullable(serverCall.getConnection());</span>
+<span class="source-line-no">851</span><span id="line-851">    }</span>
+<span class="source-line-no">852</span><span id="line-852">    return Optional.empty();</span>
+<span class="source-line-no">853</span><span id="line-853">  }</span>
+<span class="source-line-no">854</span><span id="line-854"></span>
+<span class="source-line-no">855</span><span id="line-855">  /**</span>
+<span class="source-line-no">856</span><span id="line-856">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">857</span><span id="line-857">   * @param services    Available service instances</span>
+<span class="source-line-no">858</span><span id="line-858">   * @return Matching BlockingServiceAndInterface pair</span>
+<span class="source-line-no">859</span><span id="line-859">   */</span>
+<span class="source-line-no">860</span><span id="line-860">  protected static BlockingServiceAndInterface getServiceAndInterface(</span>
+<span class="source-line-no">861</span><span id="line-861">    final List&lt;BlockingServiceAndInterface&gt; services, final String serviceName) {</span>
+<span class="source-line-no">862</span><span id="line-862">    for (BlockingServiceAndInterface bs : services) {</span>
+<span class="source-line-no">863</span><span id="line-863">      if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
+<span class="source-line-no">864</span><span id="line-864">        return bs;</span>
+<span class="source-line-no">865</span><span id="line-865">      }</span>
+<span class="source-line-no">866</span><span id="line-866">    }</span>
+<span class="source-line-no">867</span><span id="line-867">    return null;</span>
+<span class="source-line-no">868</span><span id="line-868">  }</span>
+<span class="source-line-no">869</span><span id="line-869"></span>
+<span class="source-line-no">870</span><span id="line-870">  /**</span>
+<span class="source-line-no">871</span><span id="line-871">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">872</span><span id="line-872">   * @param services    Available services and their service interfaces.</span>
+<span class="source-line-no">873</span><span id="line-873">   * @return Service interface class for &lt;code&gt;serviceName&lt;/code&gt;</span>
+<span class="source-line-no">874</span><span id="line-874">   */</span>
+<span class="source-line-no">875</span><span id="line-875">  protected static Class&lt;?&gt; getServiceInterface(final List&lt;BlockingServiceAndInterface&gt; services,</span>
+<span class="source-line-no">876</span><span id="line-876">    final String serviceName) {</span>
+<span class="source-line-no">877</span><span id="line-877">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">878</span><span id="line-878">    return bsasi == null ? null : bsasi.getServiceInterface();</span>
+<span class="source-line-no">879</span><span id="line-879">  }</span>
+<span class="source-line-no">880</span><span id="line-880"></span>
+<span class="source-line-no">881</span><span id="line-881">  /**</span>
+<span class="source-line-no">882</span><span id="line-882">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">883</span><span id="line-883">   * @param services    Available services and their service interfaces.</span>
+<span class="source-line-no">884</span><span id="line-884">   * @return BlockingService that goes with the passed &lt;code&gt;serviceName&lt;/code&gt;</span>
+<span class="source-line-no">885</span><span id="line-885">   */</span>
+<span class="source-line-no">886</span><span id="line-886">  protected static BlockingService getService(final List&lt;BlockingServiceAndInterface&gt; services,</span>
+<span class="source-line-no">887</span><span id="line-887">    final String serviceName) {</span>
+<span class="source-line-no">888</span><span id="line-888">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">889</span><span id="line-889">    return bsasi == null ? null : bsasi.getBlockingService();</span>
+<span class="source-line-no">890</span><span id="line-890">  }</span>
+<span class="source-line-no">891</span><span id="line-891"></span>
+<span class="source-line-no">892</span><span id="line-892">  protected static MonitoredRPCHandler getStatus() {</span>
+<span class="source-line-no">893</span><span id="line-893">    // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
+<span class="source-line-no">894</span><span id="line-894">    MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
+<span class="source-line-no">895</span><span id="line-895">    if (status != null) {</span>
+<span class="source-line-no">896</span><span id="line-896">      return status;</span>
+<span class="source-line-no">897</span><span id="line-897">    }</span>
+<span class="source-line-no">898</span><span id="line-898">    status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
+<span class="source-line-no">899</span><span id="line-899">    status.pause("Waiting for a call");</span>
+<span class="source-line-no">900</span><span id="line-900">    RpcServer.MONITORED_RPC.set(status);</span>
+<span class="source-line-no">901</span><span id="line-901">    return status;</span>
+<span class="source-line-no">902</span><span id="line-902">  }</span>
+<span class="source-line-no">903</span><span id="line-903"></span>
+<span class="source-line-no">904</span><span id="line-904">  /**</span>
+<span class="source-line-no">905</span><span id="line-905">   * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
+<span class="source-line-no">906</span><span id="line-906">   */</span>
+<span class="source-line-no">907</span><span id="line-907">  public static InetAddress getRemoteIp() {</span>
+<span class="source-line-no">908</span><span id="line-908">    RpcCall call = CurCall.get();</span>
+<span class="source-line-no">909</span><span id="line-909">    if (call != null) {</span>
+<span class="source-line-no">910</span><span id="line-910">      return call.getRemoteAddress();</span>
+<span class="source-line-no">911</span><span id="line-911">    }</span>
+<span class="source-line-no">912</span><span id="line-912">    return null;</span>
+<span class="source-line-no">913</span><span id="line-913">  }</span>
+<span class="source-line-no">914</span><span id="line-914"></span>
+<span class="source-line-no">915</span><span id="line-915">  @Override</span>
+<span class="source-line-no">916</span><span id="line-916">  public RpcScheduler getScheduler() {</span>
+<span class="source-line-no">917</span><span id="line-917">    return scheduler;</span>
+<span class="source-line-no">918</span><span id="line-918">  }</span>
+<span class="source-line-no">919</span><span id="line-919"></span>
+<span class="source-line-no">920</span><span id="line-920">  @Override</span>
+<span class="source-line-no">921</span><span id="line-921">  public ByteBuffAllocator getByteBuffAllocator() {</span>
+<span class="source-line-no">922</span><span id="line-922">    return this.bbAllocator;</span>
+<span class="source-line-no">923</span><span id="line-923">  }</span>
+<span class="source-line-no">924</span><span id="line-924"></span>
+<span class="source-line-no">925</span><span id="line-925">  @Override</span>
+<span class="source-line-no">926</span><span id="line-926">  public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
+<span class="source-line-no">927</span><span id="line-927">    this.rsRpcServices = rsRpcServices;</span>
+<span class="source-line-no">928</span><span id="line-928">  }</span>
+<span class="source-line-no">929</span><span id="line-929"></span>
+<span class="source-line-no">930</span><span id="line-930">  @Override</span>
+<span class="source-line-no">931</span><span id="line-931">  public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
+<span class="source-line-no">932</span><span id="line-932">    this.namedQueueRecorder = namedQueueRecorder;</span>
+<span class="source-line-no">933</span><span id="line-933">  }</span>
+<span class="source-line-no">934</span><span id="line-934"></span>
+<span class="source-line-no">935</span><span id="line-935">  protected boolean needAuthorization() {</span>
+<span class="source-line-no">936</span><span id="line-936">    return authorize;</span>
+<span class="source-line-no">937</span><span id="line-937">  }</span>
+<span class="source-line-no">938</span><span id="line-938"></span>
+<span class="source-line-no">939</span><span id="line-939">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">940</span><span id="line-940">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">941</span><span id="line-941">  public List&lt;BlockingServiceAndInterface&gt; getServices() {</span>
+<span class="source-line-no">942</span><span id="line-942">    return services;</span>
+<span class="source-line-no">943</span><span id="line-943">  }</span>
+<span class="source-line-no">944</span><span id="line-944"></span>
+<span class="source-line-no">945</span><span id="line-945">  private void initializeCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">946</span><span id="line-946">    this.cpHost = new RpcCoprocessorHost(conf);</span>
+<span class="source-line-no">947</span><span id="line-947">  }</span>
+<span class="source-line-no">948</span><span id="line-948"></span>
+<span class="source-line-no">949</span><span id="line-949">  @Override</span>
+<span class="source-line-no">950</span><span id="line-950">  public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
+<span class="source-line-no">951</span><span id="line-951">    return cpHost;</span>
+<span class="source-line-no">952</span><span id="line-952">  }</span>
+<span class="source-line-no">953</span><span id="line-953">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.html
index b84b9718c5e..5f499ad8434 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.html
@@ -848,104 +848,122 @@
 <span class="source-line-no">835</span><span id="line-835">  }</span>
 <span class="source-line-no">836</span><span id="line-836"></span>
 <span class="source-line-no">837</span><span id="line-837">  /**</span>
-<span class="source-line-no">838</span><span id="line-838">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">839</span><span id="line-839">   * @param services    Available service instances</span>
-<span class="source-line-no">840</span><span id="line-840">   * @return Matching BlockingServiceAndInterface pair</span>
-<span class="source-line-no">841</span><span id="line-841">   */</span>
-<span class="source-line-no">842</span><span id="line-842">  protected static BlockingServiceAndInterface getServiceAndInterface(</span>
-<span class="source-line-no">843</span><span id="line-843">    final List&lt;BlockingServiceAndInterface&gt; services, final String serviceName) {</span>
-<span class="source-line-no">844</span><span id="line-844">    for (BlockingServiceAndInterface bs : services) {</span>
-<span class="source-line-no">845</span><span id="line-845">      if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
-<span class="source-line-no">846</span><span id="line-846">        return bs;</span>
-<span class="source-line-no">847</span><span id="line-847">      }</span>
-<span class="source-line-no">848</span><span id="line-848">    }</span>
-<span class="source-line-no">849</span><span id="line-849">    return null;</span>
-<span class="source-line-no">850</span><span id="line-850">  }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852">  /**</span>
-<span class="source-line-no">853</span><span id="line-853">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">854</span><span id="line-854">   * @param services    Available services and their service interfaces.</span>
-<span class="source-line-no">855</span><span id="line-855">   * @return Service interface class for &lt;code&gt;serviceName&lt;/code&gt;</span>
-<span class="source-line-no">856</span><span id="line-856">   */</span>
-<span class="source-line-no">857</span><span id="line-857">  protected static Class&lt;?&gt; getServiceInterface(final List&lt;BlockingServiceAndInterface&gt; services,</span>
-<span class="source-line-no">858</span><span id="line-858">    final String serviceName) {</span>
-<span class="source-line-no">859</span><span id="line-859">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">860</span><span id="line-860">    return bsasi == null ? null : bsasi.getServiceInterface();</span>
-<span class="source-line-no">861</span><span id="line-861">  }</span>
-<span class="source-line-no">862</span><span id="line-862"></span>
-<span class="source-line-no">863</span><span id="line-863">  /**</span>
-<span class="source-line-no">864</span><span id="line-864">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">865</span><span id="line-865">   * @param services    Available services and their service interfaces.</span>
-<span class="source-line-no">866</span><span id="line-866">   * @return BlockingService that goes with the passed &lt;code&gt;serviceName&lt;/code&gt;</span>
-<span class="source-line-no">867</span><span id="line-867">   */</span>
-<span class="source-line-no">868</span><span id="line-868">  protected static BlockingService getService(final List&lt;BlockingServiceAndInterface&gt; services,</span>
-<span class="source-line-no">869</span><span id="line-869">    final String serviceName) {</span>
-<span class="source-line-no">870</span><span id="line-870">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">871</span><span id="line-871">    return bsasi == null ? null : bsasi.getBlockingService();</span>
-<span class="source-line-no">872</span><span id="line-872">  }</span>
-<span class="source-line-no">873</span><span id="line-873"></span>
-<span class="source-line-no">874</span><span id="line-874">  protected static MonitoredRPCHandler getStatus() {</span>
-<span class="source-line-no">875</span><span id="line-875">    // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
-<span class="source-line-no">876</span><span id="line-876">    MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
-<span class="source-line-no">877</span><span id="line-877">    if (status != null) {</span>
-<span class="source-line-no">878</span><span id="line-878">      return status;</span>
-<span class="source-line-no">879</span><span id="line-879">    }</span>
-<span class="source-line-no">880</span><span id="line-880">    status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
-<span class="source-line-no">881</span><span id="line-881">    status.pause("Waiting for a call");</span>
-<span class="source-line-no">882</span><span id="line-882">    RpcServer.MONITORED_RPC.set(status);</span>
-<span class="source-line-no">883</span><span id="line-883">    return status;</span>
-<span class="source-line-no">884</span><span id="line-884">  }</span>
-<span class="source-line-no">885</span><span id="line-885"></span>
-<span class="source-line-no">886</span><span id="line-886">  /**</span>
-<span class="source-line-no">887</span><span id="line-887">   * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
-<span class="source-line-no">888</span><span id="line-888">   */</span>
-<span class="source-line-no">889</span><span id="line-889">  public static InetAddress getRemoteIp() {</span>
-<span class="source-line-no">890</span><span id="line-890">    RpcCall call = CurCall.get();</span>
-<span class="source-line-no">891</span><span id="line-891">    if (call != null) {</span>
-<span class="source-line-no">892</span><span id="line-892">      return call.getRemoteAddress();</span>
-<span class="source-line-no">893</span><span id="line-893">    }</span>
-<span class="source-line-no">894</span><span id="line-894">    return null;</span>
-<span class="source-line-no">895</span><span id="line-895">  }</span>
-<span class="source-line-no">896</span><span id="line-896"></span>
-<span class="source-line-no">897</span><span id="line-897">  @Override</span>
-<span class="source-line-no">898</span><span id="line-898">  public RpcScheduler getScheduler() {</span>
-<span class="source-line-no">899</span><span id="line-899">    return scheduler;</span>
-<span class="source-line-no">900</span><span id="line-900">  }</span>
-<span class="source-line-no">901</span><span id="line-901"></span>
-<span class="source-line-no">902</span><span id="line-902">  @Override</span>
-<span class="source-line-no">903</span><span id="line-903">  public ByteBuffAllocator getByteBuffAllocator() {</span>
-<span class="source-line-no">904</span><span id="line-904">    return this.bbAllocator;</span>
-<span class="source-line-no">905</span><span id="line-905">  }</span>
-<span class="source-line-no">906</span><span id="line-906"></span>
-<span class="source-line-no">907</span><span id="line-907">  @Override</span>
-<span class="source-line-no">908</span><span id="line-908">  public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
-<span class="source-line-no">909</span><span id="line-909">    this.rsRpcServices = rsRpcServices;</span>
-<span class="source-line-no">910</span><span id="line-910">  }</span>
-<span class="source-line-no">911</span><span id="line-911"></span>
-<span class="source-line-no">912</span><span id="line-912">  @Override</span>
-<span class="source-line-no">913</span><span id="line-913">  public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
-<span class="source-line-no">914</span><span id="line-914">    this.namedQueueRecorder = namedQueueRecorder;</span>
-<span class="source-line-no">915</span><span id="line-915">  }</span>
-<span class="source-line-no">916</span><span id="line-916"></span>
-<span class="source-line-no">917</span><span id="line-917">  protected boolean needAuthorization() {</span>
-<span class="source-line-no">918</span><span id="line-918">    return authorize;</span>
-<span class="source-line-no">919</span><span id="line-919">  }</span>
-<span class="source-line-no">920</span><span id="line-920"></span>
-<span class="source-line-no">921</span><span id="line-921">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">922</span><span id="line-922">      allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">923</span><span id="line-923">  public List&lt;BlockingServiceAndInterface&gt; getServices() {</span>
-<span class="source-line-no">924</span><span id="line-924">    return services;</span>
-<span class="source-line-no">925</span><span id="line-925">  }</span>
-<span class="source-line-no">926</span><span id="line-926"></span>
-<span class="source-line-no">927</span><span id="line-927">  private void initializeCoprocessorHost(Configuration conf) {</span>
-<span class="source-line-no">928</span><span id="line-928">    this.cpHost = new RpcCoprocessorHost(conf);</span>
-<span class="source-line-no">929</span><span id="line-929">  }</span>
-<span class="source-line-no">930</span><span id="line-930"></span>
-<span class="source-line-no">931</span><span id="line-931">  @Override</span>
-<span class="source-line-no">932</span><span id="line-932">  public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
-<span class="source-line-no">933</span><span id="line-933">    return cpHost;</span>
-<span class="source-line-no">934</span><span id="line-934">  }</span>
-<span class="source-line-no">935</span><span id="line-935">}</span>
+<span class="source-line-no">838</span><span id="line-838">   * Returns the ServerRpcConnection for the current RPC request or not present if no connection is</span>
+<span class="source-line-no">839</span><span id="line-839">   * available. This allows access to connection-level information such as the client's IP address,</span>
+<span class="source-line-no">840</span><span id="line-840">   * authentication details, codec configuration, etc.</span>
+<span class="source-line-no">841</span><span id="line-841">   * &lt;p&gt;</span>
+<span class="source-line-no">842</span><span id="line-842">   * This method should only be called from within an RPC handler thread context.</span>
+<span class="source-line-no">843</span><span id="line-843">   * @return the current ServerRpcConnection, or Optional.empty() if called outside of an RPC</span>
+<span class="source-line-no">844</span><span id="line-844">   *         context</span>
+<span class="source-line-no">845</span><span id="line-845">   */</span>
+<span class="source-line-no">846</span><span id="line-846">  public static Optional&lt;ServerRpcConnection&gt; getCurrentServerRpcConnection() {</span>
+<span class="source-line-no">847</span><span id="line-847">    Optional&lt;RpcCall&gt; call = getCurrentCall();</span>
+<span class="source-line-no">848</span><span id="line-848">    if (call.isPresent() &amp;&amp; call.get() instanceof ServerCall) {</span>
+<span class="source-line-no">849</span><span id="line-849">      ServerCall&lt;?&gt; serverCall = (ServerCall&lt;?&gt;) call.get();</span>
+<span class="source-line-no">850</span><span id="line-850">      return Optional.ofNullable(serverCall.getConnection());</span>
+<span class="source-line-no">851</span><span id="line-851">    }</span>
+<span class="source-line-no">852</span><span id="line-852">    return Optional.empty();</span>
+<span class="source-line-no">853</span><span id="line-853">  }</span>
+<span class="source-line-no">854</span><span id="line-854"></span>
+<span class="source-line-no">855</span><span id="line-855">  /**</span>
+<span class="source-line-no">856</span><span id="line-856">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">857</span><span id="line-857">   * @param services    Available service instances</span>
+<span class="source-line-no">858</span><span id="line-858">   * @return Matching BlockingServiceAndInterface pair</span>
+<span class="source-line-no">859</span><span id="line-859">   */</span>
+<span class="source-line-no">860</span><span id="line-860">  protected static BlockingServiceAndInterface getServiceAndInterface(</span>
+<span class="source-line-no">861</span><span id="line-861">    final List&lt;BlockingServiceAndInterface&gt; services, final String serviceName) {</span>
+<span class="source-line-no">862</span><span id="line-862">    for (BlockingServiceAndInterface bs : services) {</span>
+<span class="source-line-no">863</span><span id="line-863">      if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
+<span class="source-line-no">864</span><span id="line-864">        return bs;</span>
+<span class="source-line-no">865</span><span id="line-865">      }</span>
+<span class="source-line-no">866</span><span id="line-866">    }</span>
+<span class="source-line-no">867</span><span id="line-867">    return null;</span>
+<span class="source-line-no">868</span><span id="line-868">  }</span>
+<span class="source-line-no">869</span><span id="line-869"></span>
+<span class="source-line-no">870</span><span id="line-870">  /**</span>
+<span class="source-line-no">871</span><span id="line-871">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">872</span><span id="line-872">   * @param services    Available services and their service interfaces.</span>
+<span class="source-line-no">873</span><span id="line-873">   * @return Service interface class for &lt;code&gt;serviceName&lt;/code&gt;</span>
+<span class="source-line-no">874</span><span id="line-874">   */</span>
+<span class="source-line-no">875</span><span id="line-875">  protected static Class&lt;?&gt; getServiceInterface(final List&lt;BlockingServiceAndInterface&gt; services,</span>
+<span class="source-line-no">876</span><span id="line-876">    final String serviceName) {</span>
+<span class="source-line-no">877</span><span id="line-877">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">878</span><span id="line-878">    return bsasi == null ? null : bsasi.getServiceInterface();</span>
+<span class="source-line-no">879</span><span id="line-879">  }</span>
+<span class="source-line-no">880</span><span id="line-880"></span>
+<span class="source-line-no">881</span><span id="line-881">  /**</span>
+<span class="source-line-no">882</span><span id="line-882">   * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">883</span><span id="line-883">   * @param services    Available services and their service interfaces.</span>
+<span class="source-line-no">884</span><span id="line-884">   * @return BlockingService that goes with the passed &lt;code&gt;serviceName&lt;/code&gt;</span>
+<span class="source-line-no">885</span><span id="line-885">   */</span>
+<span class="source-line-no">886</span><span id="line-886">  protected static BlockingService getService(final List&lt;BlockingServiceAndInterface&gt; services,</span>
+<span class="source-line-no">887</span><span id="line-887">    final String serviceName) {</span>
+<span class="source-line-no">888</span><span id="line-888">    BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">889</span><span id="line-889">    return bsasi == null ? null : bsasi.getBlockingService();</span>
+<span class="source-line-no">890</span><span id="line-890">  }</span>
+<span class="source-line-no">891</span><span id="line-891"></span>
+<span class="source-line-no">892</span><span id="line-892">  protected static MonitoredRPCHandler getStatus() {</span>
+<span class="source-line-no">893</span><span id="line-893">    // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
+<span class="source-line-no">894</span><span id="line-894">    MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
+<span class="source-line-no">895</span><span id="line-895">    if (status != null) {</span>
+<span class="source-line-no">896</span><span id="line-896">      return status;</span>
+<span class="source-line-no">897</span><span id="line-897">    }</span>
+<span class="source-line-no">898</span><span id="line-898">    status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
+<span class="source-line-no">899</span><span id="line-899">    status.pause("Waiting for a call");</span>
+<span class="source-line-no">900</span><span id="line-900">    RpcServer.MONITORED_RPC.set(status);</span>
+<span class="source-line-no">901</span><span id="line-901">    return status;</span>
+<span class="source-line-no">902</span><span id="line-902">  }</span>
+<span class="source-line-no">903</span><span id="line-903"></span>
+<span class="source-line-no">904</span><span id="line-904">  /**</span>
+<span class="source-line-no">905</span><span id="line-905">   * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
+<span class="source-line-no">906</span><span id="line-906">   */</span>
+<span class="source-line-no">907</span><span id="line-907">  public static InetAddress getRemoteIp() {</span>
+<span class="source-line-no">908</span><span id="line-908">    RpcCall call = CurCall.get();</span>
+<span class="source-line-no">909</span><span id="line-909">    if (call != null) {</span>
+<span class="source-line-no">910</span><span id="line-910">      return call.getRemoteAddress();</span>
+<span class="source-line-no">911</span><span id="line-911">    }</span>
+<span class="source-line-no">912</span><span id="line-912">    return null;</span>
+<span class="source-line-no">913</span><span id="line-913">  }</span>
+<span class="source-line-no">914</span><span id="line-914"></span>
+<span class="source-line-no">915</span><span id="line-915">  @Override</span>
+<span class="source-line-no">916</span><span id="line-916">  public RpcScheduler getScheduler() {</span>
+<span class="source-line-no">917</span><span id="line-917">    return scheduler;</span>
+<span class="source-line-no">918</span><span id="line-918">  }</span>
+<span class="source-line-no">919</span><span id="line-919"></span>
+<span class="source-line-no">920</span><span id="line-920">  @Override</span>
+<span class="source-line-no">921</span><span id="line-921">  public ByteBuffAllocator getByteBuffAllocator() {</span>
+<span class="source-line-no">922</span><span id="line-922">    return this.bbAllocator;</span>
+<span class="source-line-no">923</span><span id="line-923">  }</span>
+<span class="source-line-no">924</span><span id="line-924"></span>
+<span class="source-line-no">925</span><span id="line-925">  @Override</span>
+<span class="source-line-no">926</span><span id="line-926">  public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
+<span class="source-line-no">927</span><span id="line-927">    this.rsRpcServices = rsRpcServices;</span>
+<span class="source-line-no">928</span><span id="line-928">  }</span>
+<span class="source-line-no">929</span><span id="line-929"></span>
+<span class="source-line-no">930</span><span id="line-930">  @Override</span>
+<span class="source-line-no">931</span><span id="line-931">  public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
+<span class="source-line-no">932</span><span id="line-932">    this.namedQueueRecorder = namedQueueRecorder;</span>
+<span class="source-line-no">933</span><span id="line-933">  }</span>
+<span class="source-line-no">934</span><span id="line-934"></span>
+<span class="source-line-no">935</span><span id="line-935">  protected boolean needAuthorization() {</span>
+<span class="source-line-no">936</span><span id="line-936">    return authorize;</span>
+<span class="source-line-no">937</span><span id="line-937">  }</span>
+<span class="source-line-no">938</span><span id="line-938"></span>
+<span class="source-line-no">939</span><span id="line-939">  @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">940</span><span id="line-940">      allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">941</span><span id="line-941">  public List&lt;BlockingServiceAndInterface&gt; getServices() {</span>
+<span class="source-line-no">942</span><span id="line-942">    return services;</span>
+<span class="source-line-no">943</span><span id="line-943">  }</span>
+<span class="source-line-no">944</span><span id="line-944"></span>
+<span class="source-line-no">945</span><span id="line-945">  private void initializeCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">946</span><span id="line-946">    this.cpHost = new RpcCoprocessorHost(conf);</span>
+<span class="source-line-no">947</span><span id="line-947">  }</span>
+<span class="source-line-no">948</span><span id="line-948"></span>
+<span class="source-line-no">949</span><span id="line-949">  @Override</span>
+<span class="source-line-no">950</span><span id="line-950">  public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
+<span class="source-line-no">951</span><span id="line-951">    return cpHost;</span>
+<span class="source-line-no">952</span><span id="line-952">  }</span>
+<span class="source-line-no">953</span><span id="line-953">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerCall.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerCall.html
index d86f4281cfb..1d10d72262c 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerCall.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerCall.html
@@ -269,354 +269,362 @@
 <span class="source-line-no">256</span><span id="line-256">    return this.header.getPriority();</span>
 <span class="source-line-no">257</span><span id="line-257">  }</span>
 <span class="source-line-no">258</span><span id="line-258"></span>
-<span class="source-line-no">259</span><span id="line-259">  /*</span>
-<span class="source-line-no">260</span><span id="line-260">   * Short string representation without param info because param itself could be huge depends on</span>
-<span class="source-line-no">261</span><span id="line-261">   * the payload of a command</span>
+<span class="source-line-no">259</span><span id="line-259">  /**</span>
+<span class="source-line-no">260</span><span id="line-260">   * Get the ServerRpcConnection associated with this call.</span>
+<span class="source-line-no">261</span><span id="line-261">   * @return the connection object</span>
 <span class="source-line-no">262</span><span id="line-262">   */</span>
-<span class="source-line-no">263</span><span id="line-263">  @Override</span>
-<span class="source-line-no">264</span><span id="line-264">  public String toShortString() {</span>
-<span class="source-line-no">265</span><span id="line-265">    String serviceName = this.connection.service != null</span>
-<span class="source-line-no">266</span><span id="line-266">      ? this.connection.service.getDescriptorForType().getName()</span>
-<span class="source-line-no">267</span><span id="line-267">      : "null";</span>
-<span class="source-line-no">268</span><span id="line-268">    return "callId: " + this.id + " service: " + serviceName + " methodName: "</span>
-<span class="source-line-no">269</span><span id="line-269">      + ((this.md != null) ? this.md.getName() : "n/a") + " size: "</span>
-<span class="source-line-no">270</span><span id="line-270">      + StringUtils.TraditionalBinaryPrefix.long2String(this.size, "", 1) + " connection: "</span>
-<span class="source-line-no">271</span><span id="line-271">      + connection + " deadline: " + deadline;</span>
-<span class="source-line-no">272</span><span id="line-272">  }</span>
-<span class="source-line-no">273</span><span id="line-273"></span>
-<span class="source-line-no">274</span><span id="line-274">  @Override</span>
-<span class="source-line-no">275</span><span id="line-275">  public synchronized void setResponse(Message m, final ExtendedCellScanner cells, Throwable t,</span>
-<span class="source-line-no">276</span><span id="line-276">    String errorMsg) {</span>
-<span class="source-line-no">277</span><span id="line-277">    if (this.isError) {</span>
-<span class="source-line-no">278</span><span id="line-278">      return;</span>
-<span class="source-line-no">279</span><span id="line-279">    }</span>
-<span class="source-line-no">280</span><span id="line-280">    if (t != null) {</span>
-<span class="source-line-no">281</span><span id="line-281">      this.isError = true;</span>
-<span class="source-line-no">282</span><span id="line-282">      TraceUtil.setError(span, t);</span>
-<span class="source-line-no">283</span><span id="line-283">    } else {</span>
-<span class="source-line-no">284</span><span id="line-284">      span.setStatus(StatusCode.OK);</span>
-<span class="source-line-no">285</span><span id="line-285">    }</span>
-<span class="source-line-no">286</span><span id="line-286">    BufferChain bc = null;</span>
-<span class="source-line-no">287</span><span id="line-287">    try {</span>
-<span class="source-line-no">288</span><span id="line-288">      ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder();</span>
-<span class="source-line-no">289</span><span id="line-289">      // Call id.</span>
-<span class="source-line-no">290</span><span id="line-290">      headerBuilder.setCallId(this.id);</span>
-<span class="source-line-no">291</span><span id="line-291">      if (t != null) {</span>
-<span class="source-line-no">292</span><span id="line-292">        setExceptionResponse(t, errorMsg, headerBuilder);</span>
-<span class="source-line-no">293</span><span id="line-293">      }</span>
-<span class="source-line-no">294</span><span id="line-294">      // Pass reservoir to buildCellBlock. Keep reference to returne so can add it back to the</span>
-<span class="source-line-no">295</span><span id="line-295">      // reservoir when finished. This is hacky and the hack is not contained but benefits are</span>
-<span class="source-line-no">296</span><span id="line-296">      // high when we can avoid a big buffer allocation on each rpc.</span>
-<span class="source-line-no">297</span><span id="line-297">      List&lt;ByteBuffer&gt; cellBlock = null;</span>
-<span class="source-line-no">298</span><span id="line-298">      int cellBlockSize = 0;</span>
-<span class="source-line-no">299</span><span id="line-299">      if (bbAllocator.isReservoirEnabled()) {</span>
-<span class="source-line-no">300</span><span id="line-300">        this.cellBlockStream = this.cellBlockBuilder.buildCellBlockStream(this.connection.codec,</span>
-<span class="source-line-no">301</span><span id="line-301">          this.connection.compressionCodec, cells, bbAllocator);</span>
-<span class="source-line-no">302</span><span id="line-302">        if (this.cellBlockStream != null) {</span>
-<span class="source-line-no">303</span><span id="line-303">          cellBlock = this.cellBlockStream.getByteBuffers();</span>
-<span class="source-line-no">304</span><span id="line-304">          cellBlockSize = this.cellBlockStream.size();</span>
-<span class="source-line-no">305</span><span id="line-305">        }</span>
-<span class="source-line-no">306</span><span id="line-306">      } else {</span>
-<span class="source-line-no">307</span><span id="line-307">        ByteBuffer b = this.cellBlockBuilder.buildCellBlock(this.connection.codec,</span>
-<span class="source-line-no">308</span><span id="line-308">          this.connection.compressionCodec, cells);</span>
-<span class="source-line-no">309</span><span id="line-309">        if (b != null) {</span>
-<span class="source-line-no">310</span><span id="line-310">          cellBlockSize = b.remaining();</span>
-<span class="source-line-no">311</span><span id="line-311">          cellBlock = new ArrayList&lt;&gt;(1);</span>
-<span class="source-line-no">312</span><span id="line-312">          cellBlock.add(b);</span>
+<span class="source-line-no">263</span><span id="line-263">  public T getConnection() {</span>
+<span class="source-line-no">264</span><span id="line-264">    return this.connection;</span>
+<span class="source-line-no">265</span><span id="line-265">  }</span>
+<span class="source-line-no">266</span><span id="line-266"></span>
+<span class="source-line-no">267</span><span id="line-267">  /*</span>
+<span class="source-line-no">268</span><span id="line-268">   * Short string representation without param info because param itself could be huge depends on</span>
+<span class="source-line-no">269</span><span id="line-269">   * the payload of a command</span>
+<span class="source-line-no">270</span><span id="line-270">   */</span>
+<span class="source-line-no">271</span><span id="line-271">  @Override</span>
+<span class="source-line-no">272</span><span id="line-272">  public String toShortString() {</span>
+<span class="source-line-no">273</span><span id="line-273">    String serviceName = this.connection.service != null</span>
+<span class="source-line-no">274</span><span id="line-274">      ? this.connection.service.getDescriptorForType().getName()</span>
+<span class="source-line-no">275</span><span id="line-275">      : "null";</span>
+<span class="source-line-no">276</span><span id="line-276">    return "callId: " + this.id + " service: " + serviceName + " methodName: "</span>
+<span class="source-line-no">277</span><span id="line-277">      + ((this.md != null) ? this.md.getName() : "n/a") + " size: "</span>
+<span class="source-line-no">278</span><span id="line-278">      + StringUtils.TraditionalBinaryPrefix.long2String(this.size, "", 1) + " connection: "</span>
+<span class="source-line-no">279</span><span id="line-279">      + connection + " deadline: " + deadline;</span>
+<span class="source-line-no">280</span><span id="line-280">  }</span>
+<span class="source-line-no">281</span><span id="line-281"></span>
+<span class="source-line-no">282</span><span id="line-282">  @Override</span>
+<span class="source-line-no">283</span><span id="line-283">  public synchronized void setResponse(Message m, final ExtendedCellScanner cells, Throwable t,</span>
+<span class="source-line-no">284</span><span id="line-284">    String errorMsg) {</span>
+<span class="source-line-no">285</span><span id="line-285">    if (this.isError) {</span>
+<span class="source-line-no">286</span><span id="line-286">      return;</span>
+<span class="source-line-no">287</span><span id="line-287">    }</span>
+<span class="source-line-no">288</span><span id="line-288">    if (t != null) {</span>
+<span class="source-line-no">289</span><span id="line-289">      this.isError = true;</span>
+<span class="source-line-no">290</span><span id="line-290">      TraceUtil.setError(span, t);</span>
+<span class="source-line-no">291</span><span id="line-291">    } else {</span>
+<span class="source-line-no">292</span><span id="line-292">      span.setStatus(StatusCode.OK);</span>
+<span class="source-line-no">293</span><span id="line-293">    }</span>
+<span class="source-line-no">294</span><span id="line-294">    BufferChain bc = null;</span>
+<span class="source-line-no">295</span><span id="line-295">    try {</span>
+<span class="source-line-no">296</span><span id="line-296">      ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder();</span>
+<span class="source-line-no">297</span><span id="line-297">      // Call id.</span>
+<span class="source-line-no">298</span><span id="line-298">      headerBuilder.setCallId(this.id);</span>
+<span class="source-line-no">299</span><span id="line-299">      if (t != null) {</span>
+<span class="source-line-no">300</span><span id="line-300">        setExceptionResponse(t, errorMsg, headerBuilder);</span>
+<span class="source-line-no">301</span><span id="line-301">      }</span>
+<span class="source-line-no">302</span><span id="line-302">      // Pass reservoir to buildCellBlock. Keep reference to returne so can add it back to the</span>
+<span class="source-line-no">303</span><span id="line-303">      // reservoir when finished. This is hacky and the hack is not contained but benefits are</span>
+<span class="source-line-no">304</span><span id="line-304">      // high when we can avoid a big buffer allocation on each rpc.</span>
+<span class="source-line-no">305</span><span id="line-305">      List&lt;ByteBuffer&gt; cellBlock = null;</span>
+<span class="source-line-no">306</span><span id="line-306">      int cellBlockSize = 0;</span>
+<span class="source-line-no">307</span><span id="line-307">      if (bbAllocator.isReservoirEnabled()) {</span>
+<span class="source-line-no">308</span><span id="line-308">        this.cellBlockStream = this.cellBlockBuilder.buildCellBlockStream(this.connection.codec,</span>
+<span class="source-line-no">309</span><span id="line-309">          this.connection.compressionCodec, cells, bbAllocator);</span>
+<span class="source-line-no">310</span><span id="line-310">        if (this.cellBlockStream != null) {</span>
+<span class="source-line-no">311</span><span id="line-311">          cellBlock = this.cellBlockStream.getByteBuffers();</span>
+<span class="source-line-no">312</span><span id="line-312">          cellBlockSize = this.cellBlockStream.size();</span>
 <span class="source-line-no">313</span><span id="line-313">        }</span>
-<span class="source-line-no">314</span><span id="line-314">      }</span>
-<span class="source-line-no">315</span><span id="line-315"></span>
-<span class="source-line-no">316</span><span id="line-316">      if (cellBlockSize &gt; 0) {</span>
-<span class="source-line-no">317</span><span id="line-317">        CellBlockMeta.Builder cellBlockBuilder = CellBlockMeta.newBuilder();</span>
-<span class="source-line-no">318</span><span id="line-318">        // Presumes the cellBlock bytebuffer has been flipped so limit has total size in it.</span>
-<span class="source-line-no">319</span><span id="line-319">        cellBlockBuilder.setLength(cellBlockSize);</span>
-<span class="source-line-no">320</span><span id="line-320">        headerBuilder.setCellBlockMeta(cellBlockBuilder.build());</span>
-<span class="source-line-no">321</span><span id="line-321">      }</span>
-<span class="source-line-no">322</span><span id="line-322">      Message header = headerBuilder.build();</span>
-<span class="source-line-no">323</span><span id="line-323">      ByteBuffer headerBuf = createHeaderAndMessageBytes(m, header, cellBlockSize, cellBlock);</span>
-<span class="source-line-no">324</span><span id="line-324">      ByteBuffer[] responseBufs = null;</span>
-<span class="source-line-no">325</span><span id="line-325">      int cellBlockBufferSize = 0;</span>
-<span class="source-line-no">326</span><span id="line-326">      if (cellBlock != null) {</span>
-<span class="source-line-no">327</span><span id="line-327">        cellBlockBufferSize = cellBlock.size();</span>
-<span class="source-line-no">328</span><span id="line-328">        responseBufs = new ByteBuffer[1 + cellBlockBufferSize];</span>
-<span class="source-line-no">329</span><span id="line-329">      } else {</span>
-<span class="source-line-no">330</span><span id="line-330">        responseBufs = new ByteBuffer[1];</span>
-<span class="source-line-no">331</span><span id="line-331">      }</span>
-<span class="source-line-no">332</span><span id="line-332">      responseBufs[0] = headerBuf;</span>
-<span class="source-line-no">333</span><span id="line-333">      if (cellBlock != null) {</span>
-<span class="source-line-no">334</span><span id="line-334">        for (int i = 0; i &lt; cellBlockBufferSize; i++) {</span>
-<span class="source-line-no">335</span><span id="line-335">          responseBufs[i + 1] = cellBlock.get(i);</span>
-<span class="source-line-no">336</span><span id="line-336">        }</span>
-<span class="source-line-no">337</span><span id="line-337">      }</span>
-<span class="source-line-no">338</span><span id="line-338">      bc = new BufferChain(responseBufs);</span>
-<span class="source-line-no">339</span><span id="line-339">    } catch (IOException e) {</span>
-<span class="source-line-no">340</span><span id="line-340">      RpcServer.LOG.warn("Exception while creating response " + e);</span>
-<span class="source-line-no">341</span><span id="line-341">      bc = createFallbackErrorResponse(e);</span>
-<span class="source-line-no">342</span><span id="line-342">    }</span>
-<span class="source-line-no">343</span><span id="line-343">    this.response = bc;</span>
-<span class="source-line-no">344</span><span id="line-344">    // Once a response message is created and set to this.response, this Call can be treated as</span>
-<span class="source-line-no">345</span><span id="line-345">    // done. The Responder thread will do the n/w write of this message back to client.</span>
-<span class="source-line-no">346</span><span id="line-346">    if (this.rpcCallback != null) {</span>
-<span class="source-line-no">347</span><span id="line-347">      try (Scope ignored = span.makeCurrent()) {</span>
-<span class="source-line-no">348</span><span id="line-348">        this.rpcCallback.run();</span>
-<span class="source-line-no">349</span><span id="line-349">      } catch (Exception e) {</span>
-<span class="source-line-no">350</span><span id="line-350">        // Don't allow any exception here to kill this handler thread.</span>
-<span class="source-line-no">351</span><span id="line-351">        RpcServer.LOG.warn("Exception while running the Rpc Callback.", e);</span>
-<span class="source-line-no">352</span><span id="line-352">        TraceUtil.setError(span, e);</span>
-<span class="source-line-no">353</span><span id="line-353">      }</span>
-<span class="source-line-no">354</span><span id="line-354">    }</span>
-<span class="source-line-no">355</span><span id="line-355">  }</span>
-<span class="source-line-no">356</span><span id="line-356"></span>
-<span class="source-line-no">357</span><span id="line-357">  static void setExceptionResponse(Throwable t, String errorMsg,</span>
-<span class="source-line-no">358</span><span id="line-358">    ResponseHeader.Builder headerBuilder) {</span>
-<span class="source-line-no">359</span><span id="line-359">    ExceptionResponse.Builder exceptionBuilder = ExceptionResponse.newBuilder();</span>
-<span class="source-line-no">360</span><span id="line-360">    exceptionBuilder.setExceptionClassName(t.getClass().getName());</span>
-<span class="source-line-no">361</span><span id="line-361">    exceptionBuilder.setStackTrace(errorMsg);</span>
-<span class="source-line-no">362</span><span id="line-362">    exceptionBuilder.setDoNotRetry(t instanceof DoNotRetryIOException);</span>
-<span class="source-line-no">363</span><span id="line-363">    if (t instanceof RegionMovedException) {</span>
-<span class="source-line-no">364</span><span id="line-364">      // Special casing for this exception. This is only one carrying a payload.</span>
-<span class="source-line-no">365</span><span id="line-365">      // Do this instead of build a generic system for allowing exceptions carry</span>
-<span class="source-line-no">366</span><span id="line-366">      // any kind of payload.</span>
-<span class="source-line-no">367</span><span id="line-367">      RegionMovedException rme = (RegionMovedException) t;</span>
-<span class="source-line-no">368</span><span id="line-368">      exceptionBuilder.setHostname(rme.getHostname());</span>
-<span class="source-line-no">369</span><span id="line-369">      exceptionBuilder.setPort(rme.getPort());</span>
-<span class="source-line-no">370</span><span id="line-370">    } else if (t instanceof HBaseServerException) {</span>
-<span class="source-line-no">371</span><span id="line-371">      HBaseServerException hse = (HBaseServerException) t;</span>
-<span class="source-line-no">372</span><span id="line-372">      exceptionBuilder.setServerOverloaded(hse.isServerOverloaded());</span>
-<span class="source-line-no">373</span><span id="line-373">    }</span>
-<span class="source-line-no">374</span><span id="line-374">    // Set the exception as the result of the method invocation.</span>
-<span class="source-line-no">375</span><span id="line-375">    headerBuilder.setException(exceptionBuilder.build());</span>
-<span class="source-line-no">376</span><span id="line-376">  }</span>
-<span class="source-line-no">377</span><span id="line-377"></span>
-<span class="source-line-no">378</span><span id="line-378">  /*</span>
-<span class="source-line-no">379</span><span id="line-379">   * Creates a fallback error response when the primary response creation fails. This method is</span>
-<span class="source-line-no">380</span><span id="line-380">   * invoked as a last resort when an IOException occurs during the normal response creation</span>
-<span class="source-line-no">381</span><span id="line-381">   * process. It attempts to create a minimal error response containing only the error information,</span>
-<span class="source-line-no">382</span><span id="line-382">   * without any cell blocks or additional data. The purpose is to ensure that the client receives</span>
-<span class="source-line-no">383</span><span id="line-383">   * some indication of the failure rather than experiencing a silent connection drop. This provides</span>
-<span class="source-line-no">384</span><span id="line-384">   * better error handling on the client side.</span>
-<span class="source-line-no">385</span><span id="line-385">   */</span>
-<span class="source-line-no">386</span><span id="line-386">  private BufferChain createFallbackErrorResponse(IOException originalException) {</span>
-<span class="source-line-no">387</span><span id="line-387">    try {</span>
-<span class="source-line-no">388</span><span id="line-388">      ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder();</span>
-<span class="source-line-no">389</span><span id="line-389">      headerBuilder.setCallId(this.id);</span>
-<span class="source-line-no">390</span><span id="line-390">      String responseErrorMsg =</span>
-<span class="source-line-no">391</span><span id="line-391">        "Failed to create response due to: " + originalException.getMessage();</span>
-<span class="source-line-no">392</span><span id="line-392">      setExceptionResponse(originalException, responseErrorMsg, headerBuilder);</span>
-<span class="source-line-no">393</span><span id="line-393">      Message header = headerBuilder.build();</span>
-<span class="source-line-no">394</span><span id="line-394">      ByteBuffer headerBuf = createHeaderAndMessageBytes(null, header, 0, null);</span>
-<span class="source-line-no">395</span><span id="line-395">      this.isError = true;</span>
-<span class="source-line-no">396</span><span id="line-396">      return new BufferChain(new ByteBuffer[] { headerBuf });</span>
-<span class="source-line-no">397</span><span id="line-397">    } catch (IOException e) {</span>
-<span class="source-line-no">398</span><span id="line-398">      RpcServer.LOG.error("Failed to create error response for client, connection may be dropped",</span>
-<span class="source-line-no">399</span><span id="line-399">        e);</span>
-<span class="source-line-no">400</span><span id="line-400">      return null;</span>
-<span class="source-line-no">401</span><span id="line-401">    }</span>
-<span class="source-line-no">402</span><span id="line-402">  }</span>
-<span class="source-line-no">403</span><span id="line-403"></span>
-<span class="source-line-no">404</span><span id="line-404">  static ByteBuffer createHeaderAndMessageBytes(Message result, Message header, int cellBlockSize,</span>
-<span class="source-line-no">405</span><span id="line-405">    List&lt;ByteBuffer&gt; cellBlock) throws IOException {</span>
-<span class="source-line-no">406</span><span id="line-406">    // Organize the response as a set of bytebuffers rather than collect it all together inside</span>
-<span class="source-line-no">407</span><span id="line-407">    // one big byte array; save on allocations.</span>
-<span class="source-line-no">408</span><span id="line-408">    // for writing the header, we check if there is available space in the buffers</span>
-<span class="source-line-no">409</span><span id="line-409">    // created for the cellblock itself. If there is space for the header, we reuse</span>
-<span class="source-line-no">410</span><span id="line-410">    // the last buffer in the cellblock. This applies to the cellblock created from the</span>
-<span class="source-line-no">411</span><span id="line-411">    // pool or even the onheap cellblock buffer in case there is no pool enabled.</span>
-<span class="source-line-no">412</span><span id="line-412">    // Possible reuse would avoid creating a temporary array for storing the header every time.</span>
-<span class="source-line-no">413</span><span id="line-413">    ByteBuffer possiblePBBuf = (cellBlockSize &gt; 0) ? cellBlock.get(cellBlock.size() - 1) : null;</span>
-<span class="source-line-no">414</span><span id="line-414">    int headerSerializedSize = 0, resultSerializedSize = 0, headerVintSize = 0, resultVintSize = 0;</span>
-<span class="source-line-no">415</span><span id="line-415">    if (header != null) {</span>
-<span class="source-line-no">416</span><span id="line-416">      headerSerializedSize = header.getSerializedSize();</span>
-<span class="source-line-no">417</span><span id="line-417">      headerVintSize = CodedOutputStream.computeUInt32SizeNoTag(headerSerializedSize);</span>
-<span class="source-line-no">418</span><span id="line-418">    }</span>
-<span class="source-line-no">419</span><span id="line-419">    if (result != null) {</span>
-<span class="source-line-no">420</span><span id="line-420">      resultSerializedSize = result.getSerializedSize();</span>
-<span class="source-line-no">421</span><span id="line-421">      resultVintSize = CodedOutputStream.computeUInt32SizeNoTag(resultSerializedSize);</span>
-<span class="source-line-no">422</span><span id="line-422">    }</span>
-<span class="source-line-no">423</span><span id="line-423">    // calculate the total size</span>
-<span class="source-line-no">424</span><span id="line-424">    int totalSize = headerSerializedSize + headerVintSize + (resultSerializedSize + resultVintSize)</span>
-<span class="source-line-no">425</span><span id="line-425">      + cellBlockSize;</span>
-<span class="source-line-no">426</span><span id="line-426">    int totalPBSize = headerSerializedSize + headerVintSize + resultSerializedSize + resultVintSize</span>
-<span class="source-line-no">427</span><span id="line-427">      + Bytes.SIZEOF_INT;</span>
-<span class="source-line-no">428</span><span id="line-428">    // Only if the last buffer has enough space for header use it. Else allocate</span>
-<span class="source-line-no">429</span><span id="line-429">    // a new buffer. Assume they are all flipped</span>
-<span class="source-line-no">430</span><span id="line-430">    if (possiblePBBuf != null &amp;&amp; possiblePBBuf.limit() + totalPBSize &lt;= possiblePBBuf.capacity()) {</span>
-<span class="source-line-no">431</span><span id="line-431">      // duplicate the buffer. This is where the header is going to be written</span>
-<span class="source-line-no">432</span><span id="line-432">      ByteBuffer pbBuf = possiblePBBuf.duplicate();</span>
-<span class="source-line-no">433</span><span id="line-433">      // get the current limit</span>
-<span class="source-line-no">434</span><span id="line-434">      int limit = pbBuf.limit();</span>
-<span class="source-line-no">435</span><span id="line-435">      // Position such that we write the header to the end of the buffer</span>
-<span class="source-line-no">436</span><span id="line-436">      pbBuf.position(limit);</span>
-<span class="source-line-no">437</span><span id="line-437">      // limit to the header size</span>
-<span class="source-line-no">438</span><span id="line-438">      pbBuf.limit(totalPBSize + limit);</span>
-<span class="source-line-no">439</span><span id="line-439">      // mark the current position</span>
-<span class="source-line-no">440</span><span id="line-440">      pbBuf.mark();</span>
-<span class="source-line-no">441</span><span id="line-441">      writeToCOS(result, header, totalSize, pbBuf);</span>
-<span class="source-line-no">442</span><span id="line-442">      // reset the buffer back to old position</span>
-<span class="source-line-no">443</span><span id="line-443">      pbBuf.reset();</span>
-<span class="source-line-no">444</span><span id="line-444">      return pbBuf;</span>
-<span class="source-line-no">445</span><span id="line-445">    } else {</span>
-<span class="source-line-no">446</span><span id="line-446">      return createHeaderAndMessageBytes(result, header, totalSize, totalPBSize);</span>
-<span class="source-line-no">447</span><span id="line-447">    }</span>
-<span class="source-line-no">448</span><span id="line-448">  }</span>
-<span class="source-line-no">449</span><span id="line-449"></span>
-<span class="source-line-no">450</span><span id="line-450">  private static void writeToCOS(Message result, Message header, int totalSize, ByteBuffer pbBuf)</span>
-<span class="source-line-no">451</span><span id="line-451">    throws IOException {</span>
-<span class="source-line-no">452</span><span id="line-452">    ByteBufferUtils.putInt(pbBuf, totalSize);</span>
-<span class="source-line-no">453</span><span id="line-453">    // create COS that works on BB</span>
-<span class="source-line-no">454</span><span id="line-454">    CodedOutputStream cos = CodedOutputStream.newInstance(pbBuf);</span>
-<span class="source-line-no">455</span><span id="line-455">    if (header != null) {</span>
-<span class="source-line-no">456</span><span id="line-456">      cos.writeMessageNoTag(header);</span>
-<span class="source-line-no">457</span><span id="line-457">    }</span>
-<span class="source-line-no">458</span><span id="line-458">    if (result != null) {</span>
-<span class="source-line-no">459</span><span id="line-459">      cos.writeMessageNoTag(result);</span>
-<span class="source-line-no">460</span><span id="line-460">    }</span>
-<span class="source-line-no">461</span><span id="line-461">    cos.flush();</span>
-<span class="source-line-no">462</span><span id="line-462">    cos.checkNoSpaceLeft();</span>
-<span class="source-line-no">463</span><span id="line-463">  }</span>
-<span class="source-line-no">464</span><span id="line-464"></span>
-<span class="source-line-no">465</span><span id="line-465">  private static ByteBuffer createHeaderAndMessageBytes(Message result, Message header,</span>
-<span class="source-line-no">466</span><span id="line-466">    int totalSize, int totalPBSize) throws IOException {</span>
-<span class="source-line-no">467</span><span id="line-467">    ByteBuffer pbBuf = ByteBuffer.allocate(totalPBSize);</span>
-<span class="source-line-no">468</span><span id="line-468">    writeToCOS(result, header, totalSize, pbBuf);</span>
-<span class="source-line-no">469</span><span id="line-469">    pbBuf.flip();</span>
-<span class="source-line-no">470</span><span id="line-470">    return pbBuf;</span>
+<span class="source-line-no">314</span><span id="line-314">      } else {</span>
+<span class="source-line-no">315</span><span id="line-315">        ByteBuffer b = this.cellBlockBuilder.buildCellBlock(this.connection.codec,</span>
+<span class="source-line-no">316</span><span id="line-316">          this.connection.compressionCodec, cells);</span>
+<span class="source-line-no">317</span><span id="line-317">        if (b != null) {</span>
+<span class="source-line-no">318</span><span id="line-318">          cellBlockSize = b.remaining();</span>
+<span class="source-line-no">319</span><span id="line-319">          cellBlock = new ArrayList&lt;&gt;(1);</span>
+<span class="source-line-no">320</span><span id="line-320">          cellBlock.add(b);</span>
+<span class="source-line-no">321</span><span id="line-321">        }</span>
+<span class="source-line-no">322</span><span id="line-322">      }</span>
+<span class="source-line-no">323</span><span id="line-323"></span>
+<span class="source-line-no">324</span><span id="line-324">      if (cellBlockSize &gt; 0) {</span>
+<span class="source-line-no">325</span><span id="line-325">        CellBlockMeta.Builder cellBlockBuilder = CellBlockMeta.newBuilder();</span>
+<span class="source-line-no">326</span><span id="line-326">        // Presumes the cellBlock bytebuffer has been flipped so limit has total size in it.</span>
+<span class="source-line-no">327</span><span id="line-327">        cellBlockBuilder.setLength(cellBlockSize);</span>
+<span class="source-line-no">328</span><span id="line-328">        headerBuilder.setCellBlockMeta(cellBlockBuilder.build());</span>
+<span class="source-line-no">329</span><span id="line-329">      }</span>
+<span class="source-line-no">330</span><span id="line-330">      Message header = headerBuilder.build();</span>
+<span class="source-line-no">331</span><span id="line-331">      ByteBuffer headerBuf = createHeaderAndMessageBytes(m, header, cellBlockSize, cellBlock);</span>
+<span class="source-line-no">332</span><span id="line-332">      ByteBuffer[] responseBufs = null;</span>
+<span class="source-line-no">333</span><span id="line-333">      int cellBlockBufferSize = 0;</span>
+<span class="source-line-no">334</span><span id="line-334">      if (cellBlock != null) {</span>
+<span class="source-line-no">335</span><span id="line-335">        cellBlockBufferSize = cellBlock.size();</span>
+<span class="source-line-no">336</span><span id="line-336">        responseBufs = new ByteBuffer[1 + cellBlockBufferSize];</span>
+<span class="source-line-no">337</span><span id="line-337">      } else {</span>
+<span class="source-line-no">338</span><span id="line-338">        responseBufs = new ByteBuffer[1];</span>
+<span class="source-line-no">339</span><span id="line-339">      }</span>
+<span class="source-line-no">340</span><span id="line-340">      responseBufs[0] = headerBuf;</span>
+<span class="source-line-no">341</span><span id="line-341">      if (cellBlock != null) {</span>
+<span class="source-line-no">342</span><span id="line-342">        for (int i = 0; i &lt; cellBlockBufferSize; i++) {</span>
+<span class="source-line-no">343</span><span id="line-343">          responseBufs[i + 1] = cellBlock.get(i);</span>
+<span class="source-line-no">344</span><span id="line-344">        }</span>
+<span class="source-line-no">345</span><span id="line-345">      }</span>
+<span class="source-line-no">346</span><span id="line-346">      bc = new BufferChain(responseBufs);</span>
+<span class="source-line-no">347</span><span id="line-347">    } catch (IOException e) {</span>
+<span class="source-line-no">348</span><span id="line-348">      RpcServer.LOG.warn("Exception while creating response " + e);</span>
+<span class="source-line-no">349</span><span id="line-349">      bc = createFallbackErrorResponse(e);</span>
+<span class="source-line-no">350</span><span id="line-350">    }</span>
+<span class="source-line-no">351</span><span id="line-351">    this.response = bc;</span>
+<span class="source-line-no">352</span><span id="line-352">    // Once a response message is created and set to this.response, this Call can be treated as</span>
+<span class="source-line-no">353</span><span id="line-353">    // done. The Responder thread will do the n/w write of this message back to client.</span>
+<span class="source-line-no">354</span><span id="line-354">    if (this.rpcCallback != null) {</span>
+<span class="source-line-no">355</span><span id="line-355">      try (Scope ignored = span.makeCurrent()) {</span>
+<span class="source-line-no">356</span><span id="line-356">        this.rpcCallback.run();</span>
+<span class="source-line-no">357</span><span id="line-357">      } catch (Exception e) {</span>
+<span class="source-line-no">358</span><span id="line-358">        // Don't allow any exception here to kill this handler thread.</span>
+<span class="source-line-no">359</span><span id="line-359">        RpcServer.LOG.warn("Exception while running the Rpc Callback.", e);</span>
+<span class="source-line-no">360</span><span id="line-360">        TraceUtil.setError(span, e);</span>
+<span class="source-line-no">361</span><span id="line-361">      }</span>
+<span class="source-line-no">362</span><span id="line-362">    }</span>
+<span class="source-line-no">363</span><span id="line-363">  }</span>
+<span class="source-line-no">364</span><span id="line-364"></span>
+<span class="source-line-no">365</span><span id="line-365">  static void setExceptionResponse(Throwable t, String errorMsg,</span>
+<span class="source-line-no">366</span><span id="line-366">    ResponseHeader.Builder headerBuilder) {</span>
+<span class="source-line-no">367</span><span id="line-367">    ExceptionResponse.Builder exceptionBuilder = ExceptionResponse.newBuilder();</span>
+<span class="source-line-no">368</span><span id="line-368">    exceptionBuilder.setExceptionClassName(t.getClass().getName());</span>
+<span class="source-line-no">369</span><span id="line-369">    exceptionBuilder.setStackTrace(errorMsg);</span>
+<span class="source-line-no">370</span><span id="line-370">    exceptionBuilder.setDoNotRetry(t instanceof DoNotRetryIOException);</span>
+<span class="source-line-no">371</span><span id="line-371">    if (t instanceof RegionMovedException) {</span>
+<span class="source-line-no">372</span><span id="line-372">      // Special casing for this exception. This is only one carrying a payload.</span>
+<span class="source-line-no">373</span><span id="line-373">      // Do this instead of build a generic system for allowing exceptions carry</span>
+<span class="source-line-no">374</span><span id="line-374">      // any kind of payload.</span>
+<span class="source-line-no">375</span><span id="line-375">      RegionMovedException rme = (RegionMovedException) t;</span>
+<span class="source-line-no">376</span><span id="line-376">      exceptionBuilder.setHostname(rme.getHostname());</span>
+<span class="source-line-no">377</span><span id="line-377">      exceptionBuilder.setPort(rme.getPort());</span>
+<span class="source-line-no">378</span><span id="line-378">    } else if (t instanceof HBaseServerException) {</span>
+<span class="source-line-no">379</span><span id="line-379">      HBaseServerException hse = (HBaseServerException) t;</span>
+<span class="source-line-no">380</span><span id="line-380">      exceptionBuilder.setServerOverloaded(hse.isServerOverloaded());</span>
+<span class="source-line-no">381</span><span id="line-381">    }</span>
+<span class="source-line-no">382</span><span id="line-382">    // Set the exception as the result of the method invocation.</span>
+<span class="source-line-no">383</span><span id="line-383">    headerBuilder.setException(exceptionBuilder.build());</span>
+<span class="source-line-no">384</span><span id="line-384">  }</span>
+<span class="source-line-no">385</span><span id="line-385"></span>
+<span class="source-line-no">386</span><span id="line-386">  /*</span>
+<span class="source-line-no">387</span><span id="line-387">   * Creates a fallback error response when the primary response creation fails. This method is</span>
+<span class="source-line-no">388</span><span id="line-388">   * invoked as a last resort when an IOException occurs during the normal response creation</span>
+<span class="source-line-no">389</span><span id="line-389">   * process. It attempts to create a minimal error response containing only the error information,</span>
+<span class="source-line-no">390</span><span id="line-390">   * without any cell blocks or additional data. The purpose is to ensure that the client receives</span>
+<span class="source-line-no">391</span><span id="line-391">   * some indication of the failure rather than experiencing a silent connection drop. This provides</span>
+<span class="source-line-no">392</span><span id="line-392">   * better error handling on the client side.</span>
+<span class="source-line-no">393</span><span id="line-393">   */</span>
+<span class="source-line-no">394</span><span id="line-394">  private BufferChain createFallbackErrorResponse(IOException originalException) {</span>
+<span class="source-line-no">395</span><span id="line-395">    try {</span>
+<span class="source-line-no">396</span><span id="line-396">      ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder();</span>
+<span class="source-line-no">397</span><span id="line-397">      headerBuilder.setCallId(this.id);</span>
+<span class="source-line-no">398</span><span id="line-398">      String responseErrorMsg =</span>
+<span class="source-line-no">399</span><span id="line-399">        "Failed to create response due to: " + originalException.getMessage();</span>
+<span class="source-line-no">400</span><span id="line-400">      setExceptionResponse(originalException, responseErrorMsg, headerBuilder);</span>
+<span class="source-line-no">401</span><span id="line-401">      Message header = headerBuilder.build();</span>
+<span class="source-line-no">402</span><span id="line-402">      ByteBuffer headerBuf = createHeaderAndMessageBytes(null, header, 0, null);</span>
+<span class="source-line-no">403</span><span id="line-403">      this.isError = true;</span>
+<span class="source-line-no">404</span><span id="line-404">      return new BufferChain(new ByteBuffer[] { headerBuf });</span>
+<span class="source-line-no">405</span><span id="line-405">    } catch (IOException e) {</span>
+<span class="source-line-no">406</span><span id="line-406">      RpcServer.LOG.error("Failed to create error response for client, connection may be dropped",</span>
+<span class="source-line-no">407</span><span id="line-407">        e);</span>
+<span class="source-line-no">408</span><span id="line-408">      return null;</span>
+<span class="source-line-no">409</span><span id="line-409">    }</span>
+<span class="source-line-no">410</span><span id="line-410">  }</span>
+<span class="source-line-no">411</span><span id="line-411"></span>
+<span class="source-line-no">412</span><span id="line-412">  static ByteBuffer createHeaderAndMessageBytes(Message result, Message header, int cellBlockSize,</span>
+<span class="source-line-no">413</span><span id="line-413">    List&lt;ByteBuffer&gt; cellBlock) throws IOException {</span>
+<span class="source-line-no">414</span><span id="line-414">    // Organize the response as a set of bytebuffers rather than collect it all together inside</span>
+<span class="source-line-no">415</span><span id="line-415">    // one big byte array; save on allocations.</span>
+<span class="source-line-no">416</span><span id="line-416">    // for writing the header, we check if there is available space in the buffers</span>
+<span class="source-line-no">417</span><span id="line-417">    // created for the cellblock itself. If there is space for the header, we reuse</span>
+<span class="source-line-no">418</span><span id="line-418">    // the last buffer in the cellblock. This applies to the cellblock created from the</span>
+<span class="source-line-no">419</span><span id="line-419">    // pool or even the onheap cellblock buffer in case there is no pool enabled.</span>
+<span class="source-line-no">420</span><span id="line-420">    // Possible reuse would avoid creating a temporary array for storing the header every time.</span>
+<span class="source-line-no">421</span><span id="line-421">    ByteBuffer possiblePBBuf = (cellBlockSize &gt; 0) ? cellBlock.get(cellBlock.size() - 1) : null;</span>
+<span class="source-line-no">422</span><span id="line-422">    int headerSerializedSize = 0, resultSerializedSize = 0, headerVintSize = 0, resultVintSize = 0;</span>
+<span class="source-line-no">423</span><span id="line-423">    if (header != null) {</span>
+<span class="source-line-no">424</span><span id="line-424">      headerSerializedSize = header.getSerializedSize();</span>
+<span class="source-line-no">425</span><span id="line-425">      headerVintSize = CodedOutputStream.computeUInt32SizeNoTag(headerSerializedSize);</span>
+<span class="source-line-no">426</span><span id="line-426">    }</span>
+<span class="source-line-no">427</span><span id="line-427">    if (result != null) {</span>
+<span class="source-line-no">428</span><span id="line-428">      resultSerializedSize = result.getSerializedSize();</span>
+<span class="source-line-no">429</span><span id="line-429">      resultVintSize = CodedOutputStream.computeUInt32SizeNoTag(resultSerializedSize);</span>
+<span class="source-line-no">430</span><span id="line-430">    }</span>
+<span class="source-line-no">431</span><span id="line-431">    // calculate the total size</span>
+<span class="source-line-no">432</span><span id="line-432">    int totalSize = headerSerializedSize + headerVintSize + (resultSerializedSize + resultVintSize)</span>
+<span class="source-line-no">433</span><span id="line-433">      + cellBlockSize;</span>
+<span class="source-line-no">434</span><span id="line-434">    int totalPBSize = headerSerializedSize + headerVintSize + resultSerializedSize + resultVintSize</span>
+<span class="source-line-no">435</span><span id="line-435">      + Bytes.SIZEOF_INT;</span>
+<span class="source-line-no">436</span><span id="line-436">    // Only if the last buffer has enough space for header use it. Else allocate</span>
+<span class="source-line-no">437</span><span id="line-437">    // a new buffer. Assume they are all flipped</span>
+<span class="source-line-no">438</span><span id="line-438">    if (possiblePBBuf != null &amp;&amp; possiblePBBuf.limit() + totalPBSize &lt;= possiblePBBuf.capacity()) {</span>
+<span class="source-line-no">439</span><span id="line-439">      // duplicate the buffer. This is where the header is going to be written</span>
+<span class="source-line-no">440</span><span id="line-440">      ByteBuffer pbBuf = possiblePBBuf.duplicate();</span>
+<span class="source-line-no">441</span><span id="line-441">      // get the current limit</span>
+<span class="source-line-no">442</span><span id="line-442">      int limit = pbBuf.limit();</span>
+<span class="source-line-no">443</span><span id="line-443">      // Position such that we write the header to the end of the buffer</span>
+<span class="source-line-no">444</span><span id="line-444">      pbBuf.position(limit);</span>
+<span class="source-line-no">445</span><span id="line-445">      // limit to the header size</span>
+<span class="source-line-no">446</span><span id="line-446">      pbBuf.limit(totalPBSize + limit);</span>
+<span class="source-line-no">447</span><span id="line-447">      // mark the current position</span>
+<span class="source-line-no">448</span><span id="line-448">      pbBuf.mark();</span>
+<span class="source-line-no">449</span><span id="line-449">      writeToCOS(result, header, totalSize, pbBuf);</span>
+<span class="source-line-no">450</span><span id="line-450">      // reset the buffer back to old position</span>
+<span class="source-line-no">451</span><span id="line-451">      pbBuf.reset();</span>
+<span class="source-line-no">452</span><span id="line-452">      return pbBuf;</span>
+<span class="source-line-no">453</span><span id="line-453">    } else {</span>
+<span class="source-line-no">454</span><span id="line-454">      return createHeaderAndMessageBytes(result, header, totalSize, totalPBSize);</span>
+<span class="source-line-no">455</span><span id="line-455">    }</span>
+<span class="source-line-no">456</span><span id="line-456">  }</span>
+<span class="source-line-no">457</span><span id="line-457"></span>
+<span class="source-line-no">458</span><span id="line-458">  private static void writeToCOS(Message result, Message header, int totalSize, ByteBuffer pbBuf)</span>
+<span class="source-line-no">459</span><span id="line-459">    throws IOException {</span>
+<span class="source-line-no">460</span><span id="line-460">    ByteBufferUtils.putInt(pbBuf, totalSize);</span>
+<span class="source-line-no">461</span><span id="line-461">    // create COS that works on BB</span>
+<span class="source-line-no">462</span><span id="line-462">    CodedOutputStream cos = CodedOutputStream.newInstance(pbBuf);</span>
+<span class="source-line-no">463</span><span id="line-463">    if (header != null) {</span>
+<span class="source-line-no">464</span><span id="line-464">      cos.writeMessageNoTag(header);</span>
+<span class="source-line-no">465</span><span id="line-465">    }</span>
+<span class="source-line-no">466</span><span id="line-466">    if (result != null) {</span>
+<span class="source-line-no">467</span><span id="line-467">      cos.writeMessageNoTag(result);</span>
+<span class="source-line-no">468</span><span id="line-468">    }</span>
+<span class="source-line-no">469</span><span id="line-469">    cos.flush();</span>
+<span class="source-line-no">470</span><span id="line-470">    cos.checkNoSpaceLeft();</span>
 <span class="source-line-no">471</span><span id="line-471">  }</span>
 <span class="source-line-no">472</span><span id="line-472"></span>
-<span class="source-line-no">473</span><span id="line-473">  @Override</span>
-<span class="source-line-no">474</span><span id="line-474">  public long disconnectSince() {</span>
-<span class="source-line-no">475</span><span id="line-475">    if (!this.connection.isConnectionOpen()) {</span>
-<span class="source-line-no">476</span><span id="line-476">      return EnvironmentEdgeManager.currentTime() - receiveTime;</span>
-<span class="source-line-no">477</span><span id="line-477">    } else {</span>
-<span class="source-line-no">478</span><span id="line-478">      return -1L;</span>
-<span class="source-line-no">479</span><span id="line-479">    }</span>
-<span class="source-line-no">480</span><span id="line-480">  }</span>
-<span class="source-line-no">481</span><span id="line-481"></span>
-<span class="source-line-no">482</span><span id="line-482">  @Override</span>
-<span class="source-line-no">483</span><span id="line-483">  public boolean isClientCellBlockSupported() {</span>
-<span class="source-line-no">484</span><span id="line-484">    return this.connection != null &amp;&amp; this.connection.codec != null;</span>
-<span class="source-line-no">485</span><span id="line-485">  }</span>
-<span class="source-line-no">486</span><span id="line-486"></span>
-<span class="source-line-no">487</span><span id="line-487">  @Override</span>
-<span class="source-line-no">488</span><span id="line-488">  public long getResponseCellSize() {</span>
-<span class="source-line-no">489</span><span id="line-489">    return responseCellSize;</span>
-<span class="source-line-no">490</span><span id="line-490">  }</span>
-<span class="source-line-no">491</span><span id="line-491"></span>
-<span class="source-line-no">492</span><span id="line-492">  @Override</span>
-<span class="source-line-no">493</span><span id="line-493">  public void incrementResponseCellSize(long cellSize) {</span>
-<span class="source-line-no">494</span><span id="line-494">    responseCellSize += cellSize;</span>
-<span class="source-line-no">495</span><span id="line-495">  }</span>
-<span class="source-line-no">496</span><span id="line-496"></span>
-<span class="source-line-no">497</span><span id="line-497">  @Override</span>
-<span class="source-line-no">498</span><span id="line-498">  public long getBlockBytesScanned() {</span>
-<span class="source-line-no">499</span><span id="line-499">    return responseBlockSize;</span>
-<span class="source-line-no">500</span><span id="line-500">  }</span>
-<span class="source-line-no">501</span><span id="line-501"></span>
-<span class="source-line-no">502</span><span id="line-502">  @Override</span>
-<span class="source-line-no">503</span><span id="line-503">  public void incrementBlockBytesScanned(long blockSize) {</span>
-<span class="source-line-no">504</span><span id="line-504">    responseBlockSize += blockSize;</span>
-<span class="source-line-no">505</span><span id="line-505">  }</span>
-<span class="source-line-no">506</span><span id="line-506"></span>
-<span class="source-line-no">507</span><span id="line-507">  @Override</span>
-<span class="source-line-no">508</span><span id="line-508">  public long getResponseExceptionSize() {</span>
-<span class="source-line-no">509</span><span id="line-509">    return exceptionSize;</span>
-<span class="source-line-no">510</span><span id="line-510">  }</span>
-<span class="source-line-no">511</span><span id="line-511"></span>
-<span class="source-line-no">512</span><span id="line-512">  @Override</span>
-<span class="source-line-no">513</span><span id="line-513">  public void incrementResponseExceptionSize(long exSize) {</span>
-<span class="source-line-no">514</span><span id="line-514">    exceptionSize += exSize;</span>
-<span class="source-line-no">515</span><span id="line-515">  }</span>
-<span class="source-line-no">516</span><span id="line-516"></span>
-<span class="source-line-no">517</span><span id="line-517">  @Override</span>
-<span class="source-line-no">518</span><span id="line-518">  public long getSize() {</span>
-<span class="source-line-no">519</span><span id="line-519">    return this.size;</span>
-<span class="source-line-no">520</span><span id="line-520">  }</span>
-<span class="source-line-no">521</span><span id="line-521"></span>
-<span class="source-line-no">522</span><span id="line-522">  @Override</span>
-<span class="source-line-no">523</span><span id="line-523">  public long getDeadline() {</span>
-<span class="source-line-no">524</span><span id="line-524">    return deadline;</span>
-<span class="source-line-no">525</span><span id="line-525">  }</span>
-<span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527">  @Override</span>
-<span class="source-line-no">528</span><span id="line-528">  public Optional&lt;User&gt; getRequestUser() {</span>
-<span class="source-line-no">529</span><span id="line-529">    return Optional.ofNullable(user);</span>
-<span class="source-line-no">530</span><span id="line-530">  }</span>
-<span class="source-line-no">531</span><span id="line-531"></span>
-<span class="source-line-no">532</span><span id="line-532">  @Override</span>
-<span class="source-line-no">533</span><span id="line-533">  public Optional&lt;X509Certificate[]&gt; getClientCertificateChain() {</span>
-<span class="source-line-no">534</span><span id="line-534">    return Optional.ofNullable(clientCertificateChain);</span>
-<span class="source-line-no">535</span><span id="line-535">  }</span>
-<span class="source-line-no">536</span><span id="line-536"></span>
-<span class="source-line-no">537</span><span id="line-537">  @Override</span>
-<span class="source-line-no">538</span><span id="line-538">  public InetAddress getRemoteAddress() {</span>
-<span class="source-line-no">539</span><span id="line-539">    return remoteAddress;</span>
-<span class="source-line-no">540</span><span id="line-540">  }</span>
-<span class="source-line-no">541</span><span id="line-541"></span>
-<span class="source-line-no">542</span><span id="line-542">  @Override</span>
-<span class="source-line-no">543</span><span id="line-543">  public VersionInfo getClientVersionInfo() {</span>
-<span class="source-line-no">544</span><span id="line-544">    return connection.getVersionInfo();</span>
-<span class="source-line-no">545</span><span id="line-545">  }</span>
-<span class="source-line-no">546</span><span id="line-546"></span>
-<span class="source-line-no">547</span><span id="line-547">  @Override</span>
-<span class="source-line-no">548</span><span id="line-548">  public synchronized void setCallBack(RpcCallback callback) {</span>
-<span class="source-line-no">549</span><span id="line-549">    this.rpcCallback = callback;</span>
-<span class="source-line-no">550</span><span id="line-550">  }</span>
-<span class="source-line-no">551</span><span id="line-551"></span>
-<span class="source-line-no">552</span><span id="line-552">  @Override</span>
-<span class="source-line-no">553</span><span id="line-553">  public boolean isRetryImmediatelySupported() {</span>
-<span class="source-line-no">554</span><span id="line-554">    return retryImmediatelySupported;</span>
-<span class="source-line-no">555</span><span id="line-555">  }</span>
-<span class="source-line-no">556</span><span id="line-556"></span>
-<span class="source-line-no">557</span><span id="line-557">  @Override</span>
-<span class="source-line-no">558</span><span id="line-558">  public BlockingService getService() {</span>
-<span class="source-line-no">559</span><span id="line-559">    return service;</span>
-<span class="source-line-no">560</span><span id="line-560">  }</span>
-<span class="source-line-no">561</span><span id="line-561"></span>
-<span class="source-line-no">562</span><span id="line-562">  @Override</span>
-<span class="source-line-no">563</span><span id="line-563">  public MethodDescriptor getMethod() {</span>
-<span class="source-line-no">564</span><span id="line-564">    return md;</span>
-<span class="source-line-no">565</span><span id="line-565">  }</span>
-<span class="source-line-no">566</span><span id="line-566"></span>
-<span class="source-line-no">567</span><span id="line-567">  @Override</span>
-<span class="source-line-no">568</span><span id="line-568">  public Message getParam() {</span>
-<span class="source-line-no">569</span><span id="line-569">    return param;</span>
-<span class="source-line-no">570</span><span id="line-570">  }</span>
-<span class="source-line-no">571</span><span id="line-571"></span>
-<span class="source-line-no">572</span><span id="line-572">  @Override</span>
-<span class="source-line-no">573</span><span id="line-573">  public ExtendedCellScanner getCellScanner() {</span>
-<span class="source-line-no">574</span><span id="line-574">    return cellScanner;</span>
-<span class="source-line-no">575</span><span id="line-575">  }</span>
-<span class="source-line-no">576</span><span id="line-576"></span>
-<span class="source-line-no">577</span><span id="line-577">  @Override</span>
-<span class="source-line-no">578</span><span id="line-578">  public long getReceiveTime() {</span>
-<span class="source-line-no">579</span><span id="line-579">    return receiveTime;</span>
-<span class="source-line-no">580</span><span id="line-580">  }</span>
-<span class="source-line-no">581</span><span id="line-581"></span>
-<span class="source-line-no">582</span><span id="line-582">  @Override</span>
-<span class="source-line-no">583</span><span id="line-583">  public long getStartTime() {</span>
-<span class="source-line-no">584</span><span id="line-584">    return startTime;</span>
-<span class="source-line-no">585</span><span id="line-585">  }</span>
-<span class="source-line-no">586</span><span id="line-586"></span>
-<span class="source-line-no">587</span><span id="line-587">  @Override</span>
-<span class="source-line-no">588</span><span id="line-588">  public void setStartTime(long t) {</span>
-<span class="source-line-no">589</span><span id="line-589">    this.startTime = t;</span>
-<span class="source-line-no">590</span><span id="line-590">  }</span>
-<span class="source-line-no">591</span><span id="line-591"></span>
-<span class="source-line-no">592</span><span id="line-592">  @Override</span>
-<span class="source-line-no">593</span><span id="line-593">  public int getTimeout() {</span>
-<span class="source-line-no">594</span><span id="line-594">    return timeout;</span>
-<span class="source-line-no">595</span><span id="line-595">  }</span>
-<span class="source-line-no">596</span><span id="line-596"></span>
-<span class="source-line-no">597</span><span id="line-597">  @Override</span>
-<span class="source-line-no">598</span><span id="line-598">  public int getRemotePort() {</span>
-<span class="source-line-no">599</span><span id="line-599">    return connection.getRemotePort();</span>
-<span class="source-line-no">600</span><span id="line-600">  }</span>
-<span class="source-line-no">601</span><span id="line-601"></span>
-<span class="source-line-no">602</span><span id="line-602">  @Override</span>
-<span class="source-line-no">603</span><span id="line-603">  public synchronized BufferChain getResponse() {</span>
-<span class="source-line-no">604</span><span id="line-604">    return response;</span>
-<span class="source-line-no">605</span><span id="line-605">  }</span>
-<span class="source-line-no">606</span><span id="line-606">}</span>
+<span class="source-line-no">473</span><span id="line-473">  private static ByteBuffer createHeaderAndMessageBytes(Message result, Message header,</span>
+<span class="source-line-no">474</span><span id="line-474">    int totalSize, int totalPBSize) throws IOException {</span>
+<span class="source-line-no">475</span><span id="line-475">    ByteBuffer pbBuf = ByteBuffer.allocate(totalPBSize);</span>
+<span class="source-line-no">476</span><span id="line-476">    writeToCOS(result, header, totalSize, pbBuf);</span>
+<span class="source-line-no">477</span><span id="line-477">    pbBuf.flip();</span>
+<span class="source-line-no">478</span><span id="line-478">    return pbBuf;</span>
+<span class="source-line-no">479</span><span id="line-479">  }</span>
+<span class="source-line-no">480</span><span id="line-480"></span>
+<span class="source-line-no">481</span><span id="line-481">  @Override</span>
+<span class="source-line-no">482</span><span id="line-482">  public long disconnectSince() {</span>
+<span class="source-line-no">483</span><span id="line-483">    if (!this.connection.isConnectionOpen()) {</span>
+<span class="source-line-no">484</span><span id="line-484">      return EnvironmentEdgeManager.currentTime() - receiveTime;</span>
+<span class="source-line-no">485</span><span id="line-485">    } else {</span>
+<span class="source-line-no">486</span><span id="line-486">      return -1L;</span>
+<span class="source-line-no">487</span><span id="line-487">    }</span>
+<span class="source-line-no">488</span><span id="line-488">  }</span>
+<span class="source-line-no">489</span><span id="line-489"></span>
+<span class="source-line-no">490</span><span id="line-490">  @Override</span>
+<span class="source-line-no">491</span><span id="line-491">  public boolean isClientCellBlockSupported() {</span>
+<span class="source-line-no">492</span><span id="line-492">    return this.connection != null &amp;&amp; this.connection.codec != null;</span>
+<span class="source-line-no">493</span><span id="line-493">  }</span>
+<span class="source-line-no">494</span><span id="line-494"></span>
+<span class="source-line-no">495</span><span id="line-495">  @Override</span>
+<span class="source-line-no">496</span><span id="line-496">  public long getResponseCellSize() {</span>
+<span class="source-line-no">497</span><span id="line-497">    return responseCellSize;</span>
+<span class="source-line-no">498</span><span id="line-498">  }</span>
+<span class="source-line-no">499</span><span id="line-499"></span>
+<span class="source-line-no">500</span><span id="line-500">  @Override</span>
+<span class="source-line-no">501</span><span id="line-501">  public void incrementResponseCellSize(long cellSize) {</span>
+<span class="source-line-no">502</span><span id="line-502">    responseCellSize += cellSize;</span>
+<span class="source-line-no">503</span><span id="line-503">  }</span>
+<span class="source-line-no">504</span><span id="line-504"></span>
+<span class="source-line-no">505</span><span id="line-505">  @Override</span>
+<span class="source-line-no">506</span><span id="line-506">  public long getBlockBytesScanned() {</span>
+<span class="source-line-no">507</span><span id="line-507">    return responseBlockSize;</span>
+<span class="source-line-no">508</span><span id="line-508">  }</span>
+<span class="source-line-no">509</span><span id="line-509"></span>
+<span class="source-line-no">510</span><span id="line-510">  @Override</span>
+<span class="source-line-no">511</span><span id="line-511">  public void incrementBlockBytesScanned(long blockSize) {</span>
+<span class="source-line-no">512</span><span id="line-512">    responseBlockSize += blockSize;</span>
+<span class="source-line-no">513</span><span id="line-513">  }</span>
+<span class="source-line-no">514</span><span id="line-514"></span>
+<span class="source-line-no">515</span><span id="line-515">  @Override</span>
+<span class="source-line-no">516</span><span id="line-516">  public long getResponseExceptionSize() {</span>
+<span class="source-line-no">517</span><span id="line-517">    return exceptionSize;</span>
+<span class="source-line-no">518</span><span id="line-518">  }</span>
+<span class="source-line-no">519</span><span id="line-519"></span>
+<span class="source-line-no">520</span><span id="line-520">  @Override</span>
+<span class="source-line-no">521</span><span id="line-521">  public void incrementResponseExceptionSize(long exSize) {</span>
+<span class="source-line-no">522</span><span id="line-522">    exceptionSize += exSize;</span>
+<span class="source-line-no">523</span><span id="line-523">  }</span>
+<span class="source-line-no">524</span><span id="line-524"></span>
+<span class="source-line-no">525</span><span id="line-525">  @Override</span>
+<span class="source-line-no">526</span><span id="line-526">  public long getSize() {</span>
+<span class="source-line-no">527</span><span id="line-527">    return this.size;</span>
+<span class="source-line-no">528</span><span id="line-528">  }</span>
+<span class="source-line-no">529</span><span id="line-529"></span>
+<span class="source-line-no">530</span><span id="line-530">  @Override</span>
+<span class="source-line-no">531</span><span id="line-531">  public long getDeadline() {</span>
+<span class="source-line-no">532</span><span id="line-532">    return deadline;</span>
+<span class="source-line-no">533</span><span id="line-533">  }</span>
+<span class="source-line-no">534</span><span id="line-534"></span>
+<span class="source-line-no">535</span><span id="line-535">  @Override</span>
+<span class="source-line-no">536</span><span id="line-536">  public Optional&lt;User&gt; getRequestUser() {</span>
+<span class="source-line-no">537</span><span id="line-537">    return Optional.ofNullable(user);</span>
+<span class="source-line-no">538</span><span id="line-538">  }</span>
+<span class="source-line-no">539</span><span id="line-539"></span>
+<span class="source-line-no">540</span><span id="line-540">  @Override</span>
+<span class="source-line-no">541</span><span id="line-541">  public Optional&lt;X509Certificate[]&gt; getClientCertificateChain() {</span>
+<span class="source-line-no">542</span><span id="line-542">    return Optional.ofNullable(clientCertificateChain);</span>
+<span class="source-line-no">543</span><span id="line-543">  }</span>
+<span class="source-line-no">544</span><span id="line-544"></span>
+<span class="source-line-no">545</span><span id="line-545">  @Override</span>
+<span class="source-line-no">546</span><span id="line-546">  public InetAddress getRemoteAddress() {</span>
+<span class="source-line-no">547</span><span id="line-547">    return remoteAddress;</span>
+<span class="source-line-no">548</span><span id="line-548">  }</span>
+<span class="source-line-no">549</span><span id="line-549"></span>
+<span class="source-line-no">550</span><span id="line-550">  @Override</span>
+<span class="source-line-no">551</span><span id="line-551">  public VersionInfo getClientVersionInfo() {</span>
+<span class="source-line-no">552</span><span id="line-552">    return connection.getVersionInfo();</span>
+<span class="source-line-no">553</span><span id="line-553">  }</span>
+<span class="source-line-no">554</span><span id="line-554"></span>
+<span class="source-line-no">555</span><span id="line-555">  @Override</span>
+<span class="source-line-no">556</span><span id="line-556">  public synchronized void setCallBack(RpcCallback callback) {</span>
+<span class="source-line-no">557</span><span id="line-557">    this.rpcCallback = callback;</span>
+<span class="source-line-no">558</span><span id="line-558">  }</span>
+<span class="source-line-no">559</span><span id="line-559"></span>
+<span class="source-line-no">560</span><span id="line-560">  @Override</span>
+<span class="source-line-no">561</span><span id="line-561">  public boolean isRetryImmediatelySupported() {</span>
+<span class="source-line-no">562</span><span id="line-562">    return retryImmediatelySupported;</span>
+<span class="source-line-no">563</span><span id="line-563">  }</span>
+<span class="source-line-no">564</span><span id="line-564"></span>
+<span class="source-line-no">565</span><span id="line-565">  @Override</span>
+<span class="source-line-no">566</span><span id="line-566">  public BlockingService getService() {</span>
+<span class="source-line-no">567</span><span id="line-567">    return service;</span>
+<span class="source-line-no">568</span><span id="line-568">  }</span>
+<span class="source-line-no">569</span><span id="line-569"></span>
+<span class="source-line-no">570</span><span id="line-570">  @Override</span>
+<span class="source-line-no">571</span><span id="line-571">  public MethodDescriptor getMethod() {</span>
+<span class="source-line-no">572</span><span id="line-572">    return md;</span>
+<span class="source-line-no">573</span><span id="line-573">  }</span>
+<span class="source-line-no">574</span><span id="line-574"></span>
+<span class="source-line-no">575</span><span id="line-575">  @Override</span>
+<span class="source-line-no">576</span><span id="line-576">  public Message getParam() {</span>
+<span class="source-line-no">577</span><span id="line-577">    return param;</span>
+<span class="source-line-no">578</span><span id="line-578">  }</span>
+<span class="source-line-no">579</span><span id="line-579"></span>
+<span class="source-line-no">580</span><span id="line-580">  @Override</span>
+<span class="source-line-no">581</span><span id="line-581">  public ExtendedCellScanner getCellScanner() {</span>
+<span class="source-line-no">582</span><span id="line-582">    return cellScanner;</span>
+<span class="source-line-no">583</span><span id="line-583">  }</span>
+<span class="source-line-no">584</span><span id="line-584"></span>
+<span class="source-line-no">585</span><span id="line-585">  @Override</span>
+<span class="source-line-no">586</span><span id="line-586">  public long getReceiveTime() {</span>
+<span class="source-line-no">587</span><span id="line-587">    return receiveTime;</span>
+<span class="source-line-no">588</span><span id="line-588">  }</span>
+<span class="source-line-no">589</span><span id="line-589"></span>
+<span class="source-line-no">590</span><span id="line-590">  @Override</span>
+<span class="source-line-no">591</span><span id="line-591">  public long getStartTime() {</span>
+<span class="source-line-no">592</span><span id="line-592">    return startTime;</span>
+<span class="source-line-no">593</span><span id="line-593">  }</span>
+<span class="source-line-no">594</span><span id="line-594"></span>
+<span class="source-line-no">595</span><span id="line-595">  @Override</span>
+<span class="source-line-no">596</span><span id="line-596">  public void setStartTime(long t) {</span>
+<span class="source-line-no">597</span><span id="line-597">    this.startTime = t;</span>
+<span class="source-line-no">598</span><span id="line-598">  }</span>
+<span class="source-line-no">599</span><span id="line-599"></span>
+<span class="source-line-no">600</span><span id="line-600">  @Override</span>
+<span class="source-line-no">601</span><span id="line-601">  public int getTimeout() {</span>
+<span class="source-line-no">602</span><span id="line-602">    return timeout;</span>
+<span class="source-line-no">603</span><span id="line-603">  }</span>
+<span class="source-line-no">604</span><span id="line-604"></span>
+<span class="source-line-no">605</span><span id="line-605">  @Override</span>
+<span class="source-line-no">606</span><span id="line-606">  public int getRemotePort() {</span>
+<span class="source-line-no">607</span><span id="line-607">    return connection.getRemotePort();</span>
+<span class="source-line-no">608</span><span id="line-608">  }</span>
+<span class="source-line-no">609</span><span id="line-609"></span>
+<span class="source-line-no">610</span><span id="line-610">  @Override</span>
+<span class="source-line-no">611</span><span id="line-611">  public synchronized BufferChain getResponse() {</span>
+<span class="source-line-no">612</span><span id="line-612">    return response;</span>
+<span class="source-line-no">613</span><span id="line-613">  }</span>
+<span class="source-line-no">614</span><span id="line-614">}</span>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
similarity index 83%
copy from devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
copy to apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
index 985d2429114..b38df1889ef 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
@@ -109,7 +109,7 @@
 <span class="source-line-no">096</span><span id="line-96">@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "VO_VOLATILE_INCREMENT",</span>
 <span class="source-line-no">097</span><span id="line-97">    justification = "False positive according to http://sourceforge.net/p/findbugs/bugs/1032/")</span>
 <span class="source-line-no">098</span><span id="line-98">@InterfaceAudience.Private</span>
-<span class="source-line-no">099</span><span id="line-99">abstract class ServerRpcConnection implements Closeable {</span>
+<span class="source-line-no">099</span><span id="line-99">public abstract class ServerRpcConnection implements Closeable {</span>
 <span class="source-line-no">100</span><span id="line-100"></span>
 <span class="source-line-no">101</span><span id="line-101">  private static final TextMapGetter&lt;RPCTInfo&gt; getter = new RPCTInfoGetter();</span>
 <span class="source-line-no">102</span><span id="line-102"></span>
@@ -500,380 +500,384 @@
 <span class="source-line-no">487</span><span id="line-487">      this.hostAddress, this.remotePort, version, this.useSasl, this.ugi, serviceName);</span>
 <span class="source-line-no">488</span><span id="line-488">  }</span>
 <span class="source-line-no">489</span><span id="line-489"></span>
-<span class="source-line-no">490</span><span id="line-490">  /**</span>
-<span class="source-line-no">491</span><span id="line-491">   * Send the response for connection header</span>
-<span class="source-line-no">492</span><span id="line-492">   */</span>
-<span class="source-line-no">493</span><span id="line-493">  private void sendConnectionHeaderResponseIfNeeded() throws FatalConnectionException {</span>
-<span class="source-line-no">494</span><span id="line-494">    Pair&lt;RPCProtos.ConnectionHeaderResponse, CryptoAES&gt; pair = setupCryptoCipher();</span>
-<span class="source-line-no">495</span><span id="line-495">    // Response the connection header if Crypto AES is enabled</span>
-<span class="source-line-no">496</span><span id="line-496">    if (pair == null) {</span>
-<span class="source-line-no">497</span><span id="line-497">      return;</span>
-<span class="source-line-no">498</span><span id="line-498">    }</span>
-<span class="source-line-no">499</span><span id="line-499">    try {</span>
-<span class="source-line-no">500</span><span id="line-500">      int size = pair.getFirst().getSerializedSize();</span>
-<span class="source-line-no">501</span><span id="line-501">      BufferChain bc;</span>
-<span class="source-line-no">502</span><span id="line-502">      try (ByteBufferOutputStream bbOut = new ByteBufferOutputStream(4 + size);</span>
-<span class="source-line-no">503</span><span id="line-503">        DataOutputStream out = new DataOutputStream(bbOut)) {</span>
-<span class="source-line-no">504</span><span id="line-504">        out.writeInt(size);</span>
-<span class="source-line-no">505</span><span id="line-505">        pair.getFirst().writeTo(out);</span>
-<span class="source-line-no">506</span><span id="line-506">        bc = new BufferChain(bbOut.getByteBuffer());</span>
-<span class="source-line-no">507</span><span id="line-507">      }</span>
-<span class="source-line-no">508</span><span id="line-508">      doRespond(new RpcResponse() {</span>
-<span class="source-line-no">509</span><span id="line-509"></span>
-<span class="source-line-no">510</span><span id="line-510">        @Override</span>
-<span class="source-line-no">511</span><span id="line-511">        public BufferChain getResponse() {</span>
-<span class="source-line-no">512</span><span id="line-512">          return bc;</span>
-<span class="source-line-no">513</span><span id="line-513">        }</span>
-<span class="source-line-no">514</span><span id="line-514"></span>
-<span class="source-line-no">515</span><span id="line-515">        @Override</span>
-<span class="source-line-no">516</span><span id="line-516">        public void done() {</span>
-<span class="source-line-no">517</span><span id="line-517">          // must switch after sending the connection header response, as the client still uses the</span>
-<span class="source-line-no">518</span><span id="line-518">          // original SaslClient to unwrap the data we send back</span>
-<span class="source-line-no">519</span><span id="line-519">          saslServer.switchToCryptoAES(pair.getSecond());</span>
-<span class="source-line-no">520</span><span id="line-520">        }</span>
-<span class="source-line-no">521</span><span id="line-521">      });</span>
-<span class="source-line-no">522</span><span id="line-522">    } catch (IOException ex) {</span>
-<span class="source-line-no">523</span><span id="line-523">      throw new UnsupportedCryptoException(ex.getMessage(), ex);</span>
-<span class="source-line-no">524</span><span id="line-524">    }</span>
-<span class="source-line-no">525</span><span id="line-525">  }</span>
-<span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527">  protected abstract void doRespond(RpcResponse resp) throws IOException;</span>
-<span class="source-line-no">528</span><span id="line-528"></span>
-<span class="source-line-no">529</span><span id="line-529">  /**</span>
-<span class="source-line-no">530</span><span id="line-530">   * Has the request header and the request param and optionally encoded data buffer all in this one</span>
-<span class="source-line-no">531</span><span id="line-531">   * array.</span>
-<span class="source-line-no">532</span><span id="line-532">   * &lt;p/&gt;</span>
-<span class="source-line-no">533</span><span id="line-533">   * Will be overridden in tests.</span>
-<span class="source-line-no">534</span><span id="line-534">   */</span>
-<span class="source-line-no">535</span><span id="line-535">  protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {</span>
-<span class="source-line-no">536</span><span id="line-536">    long totalRequestSize = buf.limit();</span>
-<span class="source-line-no">537</span><span id="line-537">    int offset = 0;</span>
-<span class="source-line-no">538</span><span id="line-538">    // Here we read in the header. We avoid having pb</span>
-<span class="source-line-no">539</span><span id="line-539">    // do its default 4k allocation for CodedInputStream. We force it to use</span>
-<span class="source-line-no">540</span><span id="line-540">    // backing array.</span>
-<span class="source-line-no">541</span><span id="line-541">    CodedInputStream cis = createCis(buf);</span>
-<span class="source-line-no">542</span><span id="line-542">    int headerSize = cis.readRawVarint32();</span>
-<span class="source-line-no">543</span><span id="line-543">    offset = cis.getTotalBytesRead();</span>
-<span class="source-line-no">544</span><span id="line-544">    Message.Builder builder = RequestHeader.newBuilder();</span>
-<span class="source-line-no">545</span><span id="line-545">    ProtobufUtil.mergeFrom(builder, cis, headerSize);</span>
-<span class="source-line-no">546</span><span id="line-546">    RequestHeader header = (RequestHeader) builder.build();</span>
-<span class="source-line-no">547</span><span id="line-547">    offset += headerSize;</span>
-<span class="source-line-no">548</span><span id="line-548">    Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()</span>
-<span class="source-line-no">549</span><span id="line-549">      .extract(Context.current(), header.getTraceInfo(), getter);</span>
-<span class="source-line-no">550</span><span id="line-550"></span>
-<span class="source-line-no">551</span><span id="line-551">    // n.b. Management of this Span instance is a little odd. Most exit paths from this try scope</span>
-<span class="source-line-no">552</span><span id="line-552">    // are early-exits due to error cases. There's only one success path, the asynchronous call to</span>
-<span class="source-line-no">553</span><span id="line-553">    // RpcScheduler#dispatch. The success path assumes ownership of the span, which is represented</span>
-<span class="source-line-no">554</span><span id="line-554">    // by null-ing out the reference in this scope. All other paths end the span. Thus, and in</span>
-<span class="source-line-no">555</span><span id="line-555">    // order to avoid accidentally orphaning the span, the call to Span#end happens in a finally</span>
-<span class="source-line-no">556</span><span id="line-556">    // block iff the span is non-null.</span>
-<span class="source-line-no">557</span><span id="line-557">    Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);</span>
-<span class="source-line-no">558</span><span id="line-558">    try (Scope ignored = span.makeCurrent()) {</span>
-<span class="source-line-no">559</span><span id="line-559">      int id = header.getCallId();</span>
-<span class="source-line-no">560</span><span id="line-560">      // HBASE-28128 - if server is aborting, don't bother trying to process. It will</span>
-<span class="source-line-no">561</span><span id="line-561">      // fail at the handler layer, but worse might result in CallQueueTooBigException if the</span>
-<span class="source-line-no">562</span><span id="line-562">      // queue is full but server is not properly processing requests. Better to throw an aborted</span>
-<span class="source-line-no">563</span><span id="line-563">      // exception here so that the client can properly react.</span>
-<span class="source-line-no">564</span><span id="line-564">      if (rpcServer.server != null &amp;&amp; rpcServer.server.isAborted()) {</span>
-<span class="source-line-no">565</span><span id="line-565">        RegionServerAbortedException serverIsAborted = new RegionServerAbortedException(</span>
-<span class="source-line-no">566</span><span id="line-566">          "Server " + rpcServer.server.getServerName() + " aborting");</span>
-<span class="source-line-no">567</span><span id="line-567">        this.rpcServer.metrics.exception(serverIsAborted);</span>
-<span class="source-line-no">568</span><span id="line-568">        sendErrorResponseForCall(id, totalRequestSize, span, serverIsAborted.getMessage(),</span>
-<span class="source-line-no">569</span><span id="line-569">          serverIsAborted);</span>
-<span class="source-line-no">570</span><span id="line-570">        return;</span>
-<span class="source-line-no">571</span><span id="line-571">      }</span>
-<span class="source-line-no">572</span><span id="line-572"></span>
-<span class="source-line-no">573</span><span id="line-573">      if (RpcServer.LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">574</span><span id="line-574">        RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header)</span>
-<span class="source-line-no">575</span><span id="line-575">          + " totalRequestSize: " + totalRequestSize + " bytes");</span>
-<span class="source-line-no">576</span><span id="line-576">      }</span>
-<span class="source-line-no">577</span><span id="line-577">      // Enforcing the call queue size, this triggers a retry in the client</span>
-<span class="source-line-no">578</span><span id="line-578">      // This is a bit late to be doing this check - we have already read in the</span>
-<span class="source-line-no">579</span><span id="line-579">      // total request.</span>
-<span class="source-line-no">580</span><span id="line-580">      if (</span>
-<span class="source-line-no">581</span><span id="line-581">        (totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum())</span>
-<span class="source-line-no">582</span><span id="line-582">            &gt; this.rpcServer.maxQueueSizeInBytes</span>
-<span class="source-line-no">583</span><span id="line-583">      ) {</span>
-<span class="source-line-no">584</span><span id="line-584">        this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">585</span><span id="line-585">        sendErrorResponseForCall(id, totalRequestSize, span,</span>
-<span class="source-line-no">586</span><span id="line-586">          "Call queue is full on " + this.rpcServer.server.getServerName()</span>
-<span class="source-line-no">587</span><span id="line-587">            + ", is hbase.ipc.server.max.callqueue.size too small?",</span>
-<span class="source-line-no">588</span><span id="line-588">          RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">589</span><span id="line-589">        return;</span>
-<span class="source-line-no">590</span><span id="line-590">      }</span>
-<span class="source-line-no">591</span><span id="line-591">      MethodDescriptor md = null;</span>
-<span class="source-line-no">592</span><span id="line-592">      Message param = null;</span>
-<span class="source-line-no">593</span><span id="line-593">      ExtendedCellScanner cellScanner = null;</span>
-<span class="source-line-no">594</span><span id="line-594">      try {</span>
-<span class="source-line-no">595</span><span id="line-595">        if (header.hasRequestParam() &amp;&amp; header.getRequestParam()) {</span>
-<span class="source-line-no">596</span><span id="line-596">          md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());</span>
-<span class="source-line-no">597</span><span id="line-597">          if (md == null) {</span>
-<span class="source-line-no">598</span><span id="line-598">            throw new UnsupportedOperationException(header.getMethodName());</span>
-<span class="source-line-no">599</span><span id="line-599">          }</span>
-<span class="source-line-no">600</span><span id="line-600">          builder = this.service.getRequestPrototype(md).newBuilderForType();</span>
-<span class="source-line-no">601</span><span id="line-601">          cis.resetSizeCounter();</span>
-<span class="source-line-no">602</span><span id="line-602">          int paramSize = cis.readRawVarint32();</span>
-<span class="source-line-no">603</span><span id="line-603">          offset += cis.getTotalBytesRead();</span>
-<span class="source-line-no">604</span><span id="line-604">          if (builder != null) {</span>
-<span class="source-line-no">605</span><span id="line-605">            ProtobufUtil.mergeFrom(builder, cis, paramSize);</span>
-<span class="source-line-no">606</span><span id="line-606">            param = builder.build();</span>
-<span class="source-line-no">607</span><span id="line-607">          }</span>
-<span class="source-line-no">608</span><span id="line-608">          offset += paramSize;</span>
-<span class="source-line-no">609</span><span id="line-609">        } else {</span>
-<span class="source-line-no">610</span><span id="line-610">          // currently header must have request param, so we directly throw</span>
-<span class="source-line-no">611</span><span id="line-611">          // exception here</span>
-<span class="source-line-no">612</span><span id="line-612">          String msg = "Invalid request header: " + TextFormat.shortDebugString(header)</span>
-<span class="source-line-no">613</span><span id="line-613">            + ", should have param set in it";</span>
-<span class="source-line-no">614</span><span id="line-614">          RpcServer.LOG.warn(msg);</span>
-<span class="source-line-no">615</span><span id="line-615">          throw new DoNotRetryIOException(msg);</span>
-<span class="source-line-no">616</span><span id="line-616">        }</span>
-<span class="source-line-no">617</span><span id="line-617">        if (header.hasCellBlockMeta()) {</span>
-<span class="source-line-no">618</span><span id="line-618">          buf.position(offset);</span>
-<span class="source-line-no">619</span><span id="line-619">          ByteBuff dup = buf.duplicate();</span>
-<span class="source-line-no">620</span><span id="line-620">          dup.limit(offset + header.getCellBlockMeta().getLength());</span>
-<span class="source-line-no">621</span><span id="line-621">          cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec,</span>
-<span class="source-line-no">622</span><span id="line-622">            this.compressionCodec, dup);</span>
-<span class="source-line-no">623</span><span id="line-623">        }</span>
-<span class="source-line-no">624</span><span id="line-624">      } catch (Throwable thrown) {</span>
-<span class="source-line-no">625</span><span id="line-625">        InetSocketAddress address = this.rpcServer.getListenerAddress();</span>
-<span class="source-line-no">626</span><span id="line-626">        String msg = (address != null ? address : "(channel closed)")</span>
-<span class="source-line-no">627</span><span id="line-627">          + " is unable to read call parameter from client " + getHostAddress();</span>
-<span class="source-line-no">628</span><span id="line-628">        RpcServer.LOG.warn(msg, thrown);</span>
-<span class="source-line-no">629</span><span id="line-629"></span>
-<span class="source-line-no">630</span><span id="line-630">        this.rpcServer.metrics.exception(thrown);</span>
-<span class="source-line-no">631</span><span id="line-631"></span>
-<span class="source-line-no">632</span><span id="line-632">        final Throwable responseThrowable;</span>
-<span class="source-line-no">633</span><span id="line-633">        if (thrown instanceof LinkageError) {</span>
-<span class="source-line-no">634</span><span id="line-634">          // probably the hbase hadoop version does not match the running hadoop version</span>
-<span class="source-line-no">635</span><span id="line-635">          responseThrowable = new DoNotRetryIOException(thrown);</span>
-<span class="source-line-no">636</span><span id="line-636">        } else if (thrown instanceof UnsupportedOperationException) {</span>
-<span class="source-line-no">637</span><span id="line-637">          // If the method is not present on the server, do not retry.</span>
-<span class="source-line-no">638</span><span id="line-638">          responseThrowable = new DoNotRetryIOException(thrown);</span>
-<span class="source-line-no">639</span><span id="line-639">        } else {</span>
-<span class="source-line-no">640</span><span id="line-640">          responseThrowable = thrown;</span>
-<span class="source-line-no">641</span><span id="line-641">        }</span>
-<span class="source-line-no">642</span><span id="line-642"></span>
-<span class="source-line-no">643</span><span id="line-643">        sendErrorResponseForCall(id, totalRequestSize, span,</span>
-<span class="source-line-no">644</span><span id="line-644">          msg + "; " + responseThrowable.getMessage(), responseThrowable);</span>
-<span class="source-line-no">645</span><span id="line-645">        return;</span>
-<span class="source-line-no">646</span><span id="line-646">      }</span>
-<span class="source-line-no">647</span><span id="line-647"></span>
-<span class="source-line-no">648</span><span id="line-648">      int timeout = 0;</span>
-<span class="source-line-no">649</span><span id="line-649">      if (header.hasTimeout() &amp;&amp; header.getTimeout() &gt; 0) {</span>
-<span class="source-line-no">650</span><span id="line-650">        timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());</span>
-<span class="source-line-no">651</span><span id="line-651">      }</span>
-<span class="source-line-no">652</span><span id="line-652">      ServerCall&lt;?&gt; call = createCall(id, this.service, md, header, param, cellScanner,</span>
-<span class="source-line-no">653</span><span id="line-653">        totalRequestSize, this.addr, timeout, this.callCleanup);</span>
-<span class="source-line-no">654</span><span id="line-654"></span>
-<span class="source-line-no">655</span><span id="line-655">      if (this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {</span>
-<span class="source-line-no">656</span><span id="line-656">        // unset span do that it's not closed in the finally block</span>
-<span class="source-line-no">657</span><span id="line-657">        span = null;</span>
-<span class="source-line-no">658</span><span id="line-658">      } else {</span>
-<span class="source-line-no">659</span><span id="line-659">        this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());</span>
-<span class="source-line-no">660</span><span id="line-660">        this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">661</span><span id="line-661">        call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION,</span>
-<span class="source-line-no">662</span><span id="line-662">          "Call queue is full on " + this.rpcServer.server.getServerName()</span>
-<span class="source-line-no">663</span><span id="line-663">            + ", too many items queued ?");</span>
-<span class="source-line-no">664</span><span id="line-664">        TraceUtil.setError(span, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">665</span><span id="line-665">        call.sendResponseIfReady();</span>
-<span class="source-line-no">666</span><span id="line-666">      }</span>
-<span class="source-line-no">667</span><span id="line-667">    } finally {</span>
-<span class="source-line-no">668</span><span id="line-668">      if (span != null) {</span>
-<span class="source-line-no">669</span><span id="line-669">        span.end();</span>
+<span class="source-line-no">490</span><span id="line-490">  public ConnectionHeader getConnectionHeader() {</span>
+<span class="source-line-no">491</span><span id="line-491">    return connectionHeader;</span>
+<span class="source-line-no">492</span><span id="line-492">  }</span>
+<span class="source-line-no">493</span><span id="line-493"></span>
+<span class="source-line-no">494</span><span id="line-494">  /**</span>
+<span class="source-line-no">495</span><span id="line-495">   * Send the response for connection header</span>
+<span class="source-line-no">496</span><span id="line-496">   */</span>
+<span class="source-line-no">497</span><span id="line-497">  private void sendConnectionHeaderResponseIfNeeded() throws FatalConnectionException {</span>
+<span class="source-line-no">498</span><span id="line-498">    Pair&lt;RPCProtos.ConnectionHeaderResponse, CryptoAES&gt; pair = setupCryptoCipher();</span>
+<span class="source-line-no">499</span><span id="line-499">    // Response the connection header if Crypto AES is enabled</span>
+<span class="source-line-no">500</span><span id="line-500">    if (pair == null) {</span>
+<span class="source-line-no">501</span><span id="line-501">      return;</span>
+<span class="source-line-no">502</span><span id="line-502">    }</span>
+<span class="source-line-no">503</span><span id="line-503">    try {</span>
+<span class="source-line-no">504</span><span id="line-504">      int size = pair.getFirst().getSerializedSize();</span>
+<span class="source-line-no">505</span><span id="line-505">      BufferChain bc;</span>
+<span class="source-line-no">506</span><span id="line-506">      try (ByteBufferOutputStream bbOut = new ByteBufferOutputStream(4 + size);</span>
+<span class="source-line-no">507</span><span id="line-507">        DataOutputStream out = new DataOutputStream(bbOut)) {</span>
+<span class="source-line-no">508</span><span id="line-508">        out.writeInt(size);</span>
+<span class="source-line-no">509</span><span id="line-509">        pair.getFirst().writeTo(out);</span>
+<span class="source-line-no">510</span><span id="line-510">        bc = new BufferChain(bbOut.getByteBuffer());</span>
+<span class="source-line-no">511</span><span id="line-511">      }</span>
+<span class="source-line-no">512</span><span id="line-512">      doRespond(new RpcResponse() {</span>
+<span class="source-line-no">513</span><span id="line-513"></span>
+<span class="source-line-no">514</span><span id="line-514">        @Override</span>
+<span class="source-line-no">515</span><span id="line-515">        public BufferChain getResponse() {</span>
+<span class="source-line-no">516</span><span id="line-516">          return bc;</span>
+<span class="source-line-no">517</span><span id="line-517">        }</span>
+<span class="source-line-no">518</span><span id="line-518"></span>
+<span class="source-line-no">519</span><span id="line-519">        @Override</span>
+<span class="source-line-no">520</span><span id="line-520">        public void done() {</span>
+<span class="source-line-no">521</span><span id="line-521">          // must switch after sending the connection header response, as the client still uses the</span>
+<span class="source-line-no">522</span><span id="line-522">          // original SaslClient to unwrap the data we send back</span>
+<span class="source-line-no">523</span><span id="line-523">          saslServer.switchToCryptoAES(pair.getSecond());</span>
+<span class="source-line-no">524</span><span id="line-524">        }</span>
+<span class="source-line-no">525</span><span id="line-525">      });</span>
+<span class="source-line-no">526</span><span id="line-526">    } catch (IOException ex) {</span>
+<span class="source-line-no">527</span><span id="line-527">      throw new UnsupportedCryptoException(ex.getMessage(), ex);</span>
+<span class="source-line-no">528</span><span id="line-528">    }</span>
+<span class="source-line-no">529</span><span id="line-529">  }</span>
+<span class="source-line-no">530</span><span id="line-530"></span>
+<span class="source-line-no">531</span><span id="line-531">  protected abstract void doRespond(RpcResponse resp) throws IOException;</span>
+<span class="source-line-no">532</span><span id="line-532"></span>
+<span class="source-line-no">533</span><span id="line-533">  /**</span>
+<span class="source-line-no">534</span><span id="line-534">   * Has the request header and the request param and optionally encoded data buffer all in this one</span>
+<span class="source-line-no">535</span><span id="line-535">   * array.</span>
+<span class="source-line-no">536</span><span id="line-536">   * &lt;p/&gt;</span>
+<span class="source-line-no">537</span><span id="line-537">   * Will be overridden in tests.</span>
+<span class="source-line-no">538</span><span id="line-538">   */</span>
+<span class="source-line-no">539</span><span id="line-539">  protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {</span>
+<span class="source-line-no">540</span><span id="line-540">    long totalRequestSize = buf.limit();</span>
+<span class="source-line-no">541</span><span id="line-541">    int offset = 0;</span>
+<span class="source-line-no">542</span><span id="line-542">    // Here we read in the header. We avoid having pb</span>
+<span class="source-line-no">543</span><span id="line-543">    // do its default 4k allocation for CodedInputStream. We force it to use</span>
+<span class="source-line-no">544</span><span id="line-544">    // backing array.</span>
+<span class="source-line-no">545</span><span id="line-545">    CodedInputStream cis = createCis(buf);</span>
+<span class="source-line-no">546</span><span id="line-546">    int headerSize = cis.readRawVarint32();</span>
+<span class="source-line-no">547</span><span id="line-547">    offset = cis.getTotalBytesRead();</span>
+<span class="source-line-no">548</span><span id="line-548">    Message.Builder builder = RequestHeader.newBuilder();</span>
+<span class="source-line-no">549</span><span id="line-549">    ProtobufUtil.mergeFrom(builder, cis, headerSize);</span>
+<span class="source-line-no">550</span><span id="line-550">    RequestHeader header = (RequestHeader) builder.build();</span>
+<span class="source-line-no">551</span><span id="line-551">    offset += headerSize;</span>
+<span class="source-line-no">552</span><span id="line-552">    Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()</span>
+<span class="source-line-no">553</span><span id="line-553">      .extract(Context.current(), header.getTraceInfo(), getter);</span>
+<span class="source-line-no">554</span><span id="line-554"></span>
+<span class="source-line-no">555</span><span id="line-555">    // n.b. Management of this Span instance is a little odd. Most exit paths from this try scope</span>
+<span class="source-line-no">556</span><span id="line-556">    // are early-exits due to error cases. There's only one success path, the asynchronous call to</span>
+<span class="source-line-no">557</span><span id="line-557">    // RpcScheduler#dispatch. The success path assumes ownership of the span, which is represented</span>
+<span class="source-line-no">558</span><span id="line-558">    // by null-ing out the reference in this scope. All other paths end the span. Thus, and in</span>
+<span class="source-line-no">559</span><span id="line-559">    // order to avoid accidentally orphaning the span, the call to Span#end happens in a finally</span>
+<span class="source-line-no">560</span><span id="line-560">    // block iff the span is non-null.</span>
+<span class="source-line-no">561</span><span id="line-561">    Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);</span>
+<span class="source-line-no">562</span><span id="line-562">    try (Scope ignored = span.makeCurrent()) {</span>
+<span class="source-line-no">563</span><span id="line-563">      int id = header.getCallId();</span>
+<span class="source-line-no">564</span><span id="line-564">      // HBASE-28128 - if server is aborting, don't bother trying to process. It will</span>
+<span class="source-line-no">565</span><span id="line-565">      // fail at the handler layer, but worse might result in CallQueueTooBigException if the</span>
+<span class="source-line-no">566</span><span id="line-566">      // queue is full but server is not properly processing requests. Better to throw an aborted</span>
+<span class="source-line-no">567</span><span id="line-567">      // exception here so that the client can properly react.</span>
+<span class="source-line-no">568</span><span id="line-568">      if (rpcServer.server != null &amp;&amp; rpcServer.server.isAborted()) {</span>
+<span class="source-line-no">569</span><span id="line-569">        RegionServerAbortedException serverIsAborted = new RegionServerAbortedException(</span>
+<span class="source-line-no">570</span><span id="line-570">          "Server " + rpcServer.server.getServerName() + " aborting");</span>
+<span class="source-line-no">571</span><span id="line-571">        this.rpcServer.metrics.exception(serverIsAborted);</span>
+<span class="source-line-no">572</span><span id="line-572">        sendErrorResponseForCall(id, totalRequestSize, span, serverIsAborted.getMessage(),</span>
+<span class="source-line-no">573</span><span id="line-573">          serverIsAborted);</span>
+<span class="source-line-no">574</span><span id="line-574">        return;</span>
+<span class="source-line-no">575</span><span id="line-575">      }</span>
+<span class="source-line-no">576</span><span id="line-576"></span>
+<span class="source-line-no">577</span><span id="line-577">      if (RpcServer.LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">578</span><span id="line-578">        RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header)</span>
+<span class="source-line-no">579</span><span id="line-579">          + " totalRequestSize: " + totalRequestSize + " bytes");</span>
+<span class="source-line-no">580</span><span id="line-580">      }</span>
+<span class="source-line-no">581</span><span id="line-581">      // Enforcing the call queue size, this triggers a retry in the client</span>
+<span class="source-line-no">582</span><span id="line-582">      // This is a bit late to be doing this check - we have already read in the</span>
+<span class="source-line-no">583</span><span id="line-583">      // total request.</span>
+<span class="source-line-no">584</span><span id="line-584">      if (</span>
+<span class="source-line-no">585</span><span id="line-585">        (totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum())</span>
+<span class="source-line-no">586</span><span id="line-586">            &gt; this.rpcServer.maxQueueSizeInBytes</span>
+<span class="source-line-no">587</span><span id="line-587">      ) {</span>
+<span class="source-line-no">588</span><span id="line-588">        this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">589</span><span id="line-589">        sendErrorResponseForCall(id, totalRequestSize, span,</span>
+<span class="source-line-no">590</span><span id="line-590">          "Call queue is full on " + this.rpcServer.server.getServerName()</span>
+<span class="source-line-no">591</span><span id="line-591">            + ", is hbase.ipc.server.max.callqueue.size too small?",</span>
+<span class="source-line-no">592</span><span id="line-592">          RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">593</span><span id="line-593">        return;</span>
+<span class="source-line-no">594</span><span id="line-594">      }</span>
+<span class="source-line-no">595</span><span id="line-595">      MethodDescriptor md = null;</span>
+<span class="source-line-no">596</span><span id="line-596">      Message param = null;</span>
+<span class="source-line-no">597</span><span id="line-597">      ExtendedCellScanner cellScanner = null;</span>
+<span class="source-line-no">598</span><span id="line-598">      try {</span>
+<span class="source-line-no">599</span><span id="line-599">        if (header.hasRequestParam() &amp;&amp; header.getRequestParam()) {</span>
+<span class="source-line-no">600</span><span id="line-600">          md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());</span>
+<span class="source-line-no">601</span><span id="line-601">          if (md == null) {</span>
+<span class="source-line-no">602</span><span id="line-602">            throw new UnsupportedOperationException(header.getMethodName());</span>
+<span class="source-line-no">603</span><span id="line-603">          }</span>
+<span class="source-line-no">604</span><span id="line-604">          builder = this.service.getRequestPrototype(md).newBuilderForType();</span>
+<span class="source-line-no">605</span><span id="line-605">          cis.resetSizeCounter();</span>
+<span class="source-line-no">606</span><span id="line-606">          int paramSize = cis.readRawVarint32();</span>
+<span class="source-line-no">607</span><span id="line-607">          offset += cis.getTotalBytesRead();</span>
+<span class="source-line-no">608</span><span id="line-608">          if (builder != null) {</span>
+<span class="source-line-no">609</span><span id="line-609">            ProtobufUtil.mergeFrom(builder, cis, paramSize);</span>
+<span class="source-line-no">610</span><span id="line-610">            param = builder.build();</span>
+<span class="source-line-no">611</span><span id="line-611">          }</span>
+<span class="source-line-no">612</span><span id="line-612">          offset += paramSize;</span>
+<span class="source-line-no">613</span><span id="line-613">        } else {</span>
+<span class="source-line-no">614</span><span id="line-614">          // currently header must have request param, so we directly throw</span>
+<span class="source-line-no">615</span><span id="line-615">          // exception here</span>
+<span class="source-line-no">616</span><span id="line-616">          String msg = "Invalid request header: " + TextFormat.shortDebugString(header)</span>
+<span class="source-line-no">617</span><span id="line-617">            + ", should have param set in it";</span>
+<span class="source-line-no">618</span><span id="line-618">          RpcServer.LOG.warn(msg);</span>
+<span class="source-line-no">619</span><span id="line-619">          throw new DoNotRetryIOException(msg);</span>
+<span class="source-line-no">620</span><span id="line-620">        }</span>
+<span class="source-line-no">621</span><span id="line-621">        if (header.hasCellBlockMeta()) {</span>
+<span class="source-line-no">622</span><span id="line-622">          buf.position(offset);</span>
+<span class="source-line-no">623</span><span id="line-623">          ByteBuff dup = buf.duplicate();</span>
+<span class="source-line-no">624</span><span id="line-624">          dup.limit(offset + header.getCellBlockMeta().getLength());</span>
+<span class="source-line-no">625</span><span id="line-625">          cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec,</span>
+<span class="source-line-no">626</span><span id="line-626">            this.compressionCodec, dup);</span>
+<span class="source-line-no">627</span><span id="line-627">        }</span>
+<span class="source-line-no">628</span><span id="line-628">      } catch (Throwable thrown) {</span>
+<span class="source-line-no">629</span><span id="line-629">        InetSocketAddress address = this.rpcServer.getListenerAddress();</span>
+<span class="source-line-no">630</span><span id="line-630">        String msg = (address != null ? address : "(channel closed)")</span>
+<span class="source-line-no">631</span><span id="line-631">          + " is unable to read call parameter from client " + getHostAddress();</span>
+<span class="source-line-no">632</span><span id="line-632">        RpcServer.LOG.warn(msg, thrown);</span>
+<span class="source-line-no">633</span><span id="line-633"></span>
+<span class="source-line-no">634</span><span id="line-634">        this.rpcServer.metrics.exception(thrown);</span>
+<span class="source-line-no">635</span><span id="line-635"></span>
+<span class="source-line-no">636</span><span id="line-636">        final Throwable responseThrowable;</span>
+<span class="source-line-no">637</span><span id="line-637">        if (thrown instanceof LinkageError) {</span>
+<span class="source-line-no">638</span><span id="line-638">          // probably the hbase hadoop version does not match the running hadoop version</span>
+<span class="source-line-no">639</span><span id="line-639">          responseThrowable = new DoNotRetryIOException(thrown);</span>
+<span class="source-line-no">640</span><span id="line-640">        } else if (thrown instanceof UnsupportedOperationException) {</span>
+<span class="source-line-no">641</span><span id="line-641">          // If the method is not present on the server, do not retry.</span>
+<span class="source-line-no">642</span><span id="line-642">          responseThrowable = new DoNotRetryIOException(thrown);</span>
+<span class="source-line-no">643</span><span id="line-643">        } else {</span>
+<span class="source-line-no">644</span><span id="line-644">          responseThrowable = thrown;</span>
+<span class="source-line-no">645</span><span id="line-645">        }</span>
+<span class="source-line-no">646</span><span id="line-646"></span>
+<span class="source-line-no">647</span><span id="line-647">        sendErrorResponseForCall(id, totalRequestSize, span,</span>
+<span class="source-line-no">648</span><span id="line-648">          msg + "; " + responseThrowable.getMessage(), responseThrowable);</span>
+<span class="source-line-no">649</span><span id="line-649">        return;</span>
+<span class="source-line-no">650</span><span id="line-650">      }</span>
+<span class="source-line-no">651</span><span id="line-651"></span>
+<span class="source-line-no">652</span><span id="line-652">      int timeout = 0;</span>
+<span class="source-line-no">653</span><span id="line-653">      if (header.hasTimeout() &amp;&amp; header.getTimeout() &gt; 0) {</span>
+<span class="source-line-no">654</span><span id="line-654">        timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());</span>
+<span class="source-line-no">655</span><span id="line-655">      }</span>
+<span class="source-line-no">656</span><span id="line-656">      ServerCall&lt;?&gt; call = createCall(id, this.service, md, header, param, cellScanner,</span>
+<span class="source-line-no">657</span><span id="line-657">        totalRequestSize, this.addr, timeout, this.callCleanup);</span>
+<span class="source-line-no">658</span><span id="line-658"></span>
+<span class="source-line-no">659</span><span id="line-659">      if (this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {</span>
+<span class="source-line-no">660</span><span id="line-660">        // unset span do that it's not closed in the finally block</span>
+<span class="source-line-no">661</span><span id="line-661">        span = null;</span>
+<span class="source-line-no">662</span><span id="line-662">      } else {</span>
+<span class="source-line-no">663</span><span id="line-663">        this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());</span>
+<span class="source-line-no">664</span><span id="line-664">        this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">665</span><span id="line-665">        call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION,</span>
+<span class="source-line-no">666</span><span id="line-666">          "Call queue is full on " + this.rpcServer.server.getServerName()</span>
+<span class="source-line-no">667</span><span id="line-667">            + ", too many items queued ?");</span>
+<span class="source-line-no">668</span><span id="line-668">        TraceUtil.setError(span, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">669</span><span id="line-669">        call.sendResponseIfReady();</span>
 <span class="source-line-no">670</span><span id="line-670">      }</span>
-<span class="source-line-no">671</span><span id="line-671">    }</span>
-<span class="source-line-no">672</span><span id="line-672">  }</span>
-<span class="source-line-no">673</span><span id="line-673"></span>
-<span class="source-line-no">674</span><span id="line-674">  private void sendErrorResponseForCall(int id, long totalRequestSize, Span span, String msg,</span>
-<span class="source-line-no">675</span><span id="line-675">    Throwable responseThrowable) throws IOException {</span>
-<span class="source-line-no">676</span><span id="line-676">    ServerCall&lt;?&gt; failedcall = createCall(id, this.service, null, null, null, null,</span>
-<span class="source-line-no">677</span><span id="line-677">      totalRequestSize, null, 0, this.callCleanup);</span>
-<span class="source-line-no">678</span><span id="line-678">    failedcall.setResponse(null, null, responseThrowable, msg);</span>
-<span class="source-line-no">679</span><span id="line-679">    TraceUtil.setError(span, responseThrowable);</span>
-<span class="source-line-no">680</span><span id="line-680">    failedcall.sendResponseIfReady();</span>
-<span class="source-line-no">681</span><span id="line-681">  }</span>
-<span class="source-line-no">682</span><span id="line-682"></span>
-<span class="source-line-no">683</span><span id="line-683">  protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException {</span>
-<span class="source-line-no">684</span><span id="line-684">    ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1);</span>
-<span class="source-line-no">685</span><span id="line-685">    ServerCall.setExceptionResponse(e, msg, headerBuilder);</span>
-<span class="source-line-no">686</span><span id="line-686">    ByteBuffer headerBuf =</span>
-<span class="source-line-no">687</span><span id="line-687">      ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null);</span>
-<span class="source-line-no">688</span><span id="line-688">    BufferChain buf = new BufferChain(headerBuf);</span>
-<span class="source-line-no">689</span><span id="line-689">    return () -&gt; buf;</span>
-<span class="source-line-no">690</span><span id="line-690">  }</span>
-<span class="source-line-no">691</span><span id="line-691"></span>
-<span class="source-line-no">692</span><span id="line-692">  private void doBadPreambleHandling(String msg) throws IOException {</span>
-<span class="source-line-no">693</span><span id="line-693">    doBadPreambleHandling(msg, new FatalConnectionException(msg));</span>
+<span class="source-line-no">671</span><span id="line-671">    } finally {</span>
+<span class="source-line-no">672</span><span id="line-672">      if (span != null) {</span>
+<span class="source-line-no">673</span><span id="line-673">        span.end();</span>
+<span class="source-line-no">674</span><span id="line-674">      }</span>
+<span class="source-line-no">675</span><span id="line-675">    }</span>
+<span class="source-line-no">676</span><span id="line-676">  }</span>
+<span class="source-line-no">677</span><span id="line-677"></span>
+<span class="source-line-no">678</span><span id="line-678">  private void sendErrorResponseForCall(int id, long totalRequestSize, Span span, String msg,</span>
+<span class="source-line-no">679</span><span id="line-679">    Throwable responseThrowable) throws IOException {</span>
+<span class="source-line-no">680</span><span id="line-680">    ServerCall&lt;?&gt; failedcall = createCall(id, this.service, null, null, null, null,</span>
+<span class="source-line-no">681</span><span id="line-681">      totalRequestSize, null, 0, this.callCleanup);</span>
+<span class="source-line-no">682</span><span id="line-682">    failedcall.setResponse(null, null, responseThrowable, msg);</span>
+<span class="source-line-no">683</span><span id="line-683">    TraceUtil.setError(span, responseThrowable);</span>
+<span class="source-line-no">684</span><span id="line-684">    failedcall.sendResponseIfReady();</span>
+<span class="source-line-no">685</span><span id="line-685">  }</span>
+<span class="source-line-no">686</span><span id="line-686"></span>
+<span class="source-line-no">687</span><span id="line-687">  protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException {</span>
+<span class="source-line-no">688</span><span id="line-688">    ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1);</span>
+<span class="source-line-no">689</span><span id="line-689">    ServerCall.setExceptionResponse(e, msg, headerBuilder);</span>
+<span class="source-line-no">690</span><span id="line-690">    ByteBuffer headerBuf =</span>
+<span class="source-line-no">691</span><span id="line-691">      ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null);</span>
+<span class="source-line-no">692</span><span id="line-692">    BufferChain buf = new BufferChain(headerBuf);</span>
+<span class="source-line-no">693</span><span id="line-693">    return () -&gt; buf;</span>
 <span class="source-line-no">694</span><span id="line-694">  }</span>
 <span class="source-line-no">695</span><span id="line-695"></span>
-<span class="source-line-no">696</span><span id="line-696">  private void doBadPreambleHandling(String msg, Exception e) throws IOException {</span>
-<span class="source-line-no">697</span><span id="line-697">    RpcServer.LOG.warn(msg, e);</span>
-<span class="source-line-no">698</span><span id="line-698">    doRespond(getErrorResponse(msg, e));</span>
-<span class="source-line-no">699</span><span id="line-699">  }</span>
-<span class="source-line-no">700</span><span id="line-700"></span>
-<span class="source-line-no">701</span><span id="line-701">  private void doPreambleResponse(Message resp) throws IOException {</span>
-<span class="source-line-no">702</span><span id="line-702">    ResponseHeader header = ResponseHeader.newBuilder().setCallId(-1).build();</span>
-<span class="source-line-no">703</span><span id="line-703">    ByteBuffer buf = ServerCall.createHeaderAndMessageBytes(resp, header, 0, null);</span>
-<span class="source-line-no">704</span><span id="line-704">    BufferChain bufChain = new BufferChain(buf);</span>
-<span class="source-line-no">705</span><span id="line-705">    doRespond(() -&gt; bufChain);</span>
-<span class="source-line-no">706</span><span id="line-706">  }</span>
-<span class="source-line-no">707</span><span id="line-707"></span>
-<span class="source-line-no">708</span><span id="line-708">  private boolean doConnectionRegistryResponse() throws IOException {</span>
-<span class="source-line-no">709</span><span id="line-709">    if (!(rpcServer.server instanceof ConnectionRegistryEndpoint)) {</span>
-<span class="source-line-no">710</span><span id="line-710">      // should be in tests or some scenarios where we should not reach here</span>
-<span class="source-line-no">711</span><span id="line-711">      return false;</span>
-<span class="source-line-no">712</span><span id="line-712">    }</span>
-<span class="source-line-no">713</span><span id="line-713">    // on backup masters, this request may be blocked since we need to fetch it from filesystem,</span>
-<span class="source-line-no">714</span><span id="line-714">    // but since it is just backup master, it is not a critical problem</span>
-<span class="source-line-no">715</span><span id="line-715">    String clusterId = ((ConnectionRegistryEndpoint) rpcServer.server).getClusterId();</span>
-<span class="source-line-no">716</span><span id="line-716">    RpcServer.LOG.debug("Response connection registry, clusterId = '{}'", clusterId);</span>
-<span class="source-line-no">717</span><span id="line-717">    if (clusterId == null) {</span>
-<span class="source-line-no">718</span><span id="line-718">      // should be in tests or some scenarios where we should not reach here</span>
-<span class="source-line-no">719</span><span id="line-719">      return false;</span>
-<span class="source-line-no">720</span><span id="line-720">    }</span>
-<span class="source-line-no">721</span><span id="line-721">    GetConnectionRegistryResponse resp =</span>
-<span class="source-line-no">722</span><span id="line-722">      GetConnectionRegistryResponse.newBuilder().setClusterId(clusterId).build();</span>
-<span class="source-line-no">723</span><span id="line-723">    doPreambleResponse(resp);</span>
-<span class="source-line-no">724</span><span id="line-724">    return true;</span>
-<span class="source-line-no">725</span><span id="line-725">  }</span>
-<span class="source-line-no">726</span><span id="line-726"></span>
-<span class="source-line-no">727</span><span id="line-727">  private void doSecurityPreambleResponse() throws IOException {</span>
-<span class="source-line-no">728</span><span id="line-728">    if (rpcServer.isSecurityEnabled) {</span>
-<span class="source-line-no">729</span><span id="line-729">      SecurityPreamableResponse resp = SecurityPreamableResponse.newBuilder()</span>
-<span class="source-line-no">730</span><span id="line-730">        .setServerPrincipal(rpcServer.serverPrincipal).build();</span>
-<span class="source-line-no">731</span><span id="line-731">      doPreambleResponse(resp);</span>
-<span class="source-line-no">732</span><span id="line-732">    } else {</span>
-<span class="source-line-no">733</span><span id="line-733">      // security is not enabled, do not need a principal when connecting, throw a special exception</span>
-<span class="source-line-no">734</span><span id="line-734">      // to let client know it should just use simple authentication</span>
-<span class="source-line-no">735</span><span id="line-735">      doRespond(getErrorResponse("security is not enabled", new SecurityNotEnabledException()));</span>
-<span class="source-line-no">736</span><span id="line-736">    }</span>
-<span class="source-line-no">737</span><span id="line-737">  }</span>
-<span class="source-line-no">738</span><span id="line-738"></span>
-<span class="source-line-no">739</span><span id="line-739">  protected final void callCleanupIfNeeded() {</span>
-<span class="source-line-no">740</span><span id="line-740">    if (callCleanup != null) {</span>
-<span class="source-line-no">741</span><span id="line-741">      callCleanup.run();</span>
-<span class="source-line-no">742</span><span id="line-742">      callCleanup = null;</span>
-<span class="source-line-no">743</span><span id="line-743">    }</span>
-<span class="source-line-no">744</span><span id="line-744">  }</span>
-<span class="source-line-no">745</span><span id="line-745"></span>
-<span class="source-line-no">746</span><span id="line-746">  protected enum PreambleResponse {</span>
-<span class="source-line-no">747</span><span id="line-747">    SUCCEED, // successfully processed the rpc preamble header</span>
-<span class="source-line-no">748</span><span id="line-748">    CONTINUE, // the preamble header is for other purpose, wait for the rpc preamble header</span>
-<span class="source-line-no">749</span><span id="line-749">    CLOSE // close the rpc connection</span>
-<span class="source-line-no">750</span><span id="line-750">  }</span>
-<span class="source-line-no">751</span><span id="line-751"></span>
-<span class="source-line-no">752</span><span id="line-752">  protected final PreambleResponse processPreamble(ByteBuffer preambleBuffer) throws IOException {</span>
-<span class="source-line-no">753</span><span id="line-753">    assert preambleBuffer.remaining() == 6;</span>
-<span class="source-line-no">754</span><span id="line-754">    if (</span>
-<span class="source-line-no">755</span><span id="line-755">      ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
-<span class="source-line-no">756</span><span id="line-756">        RpcClient.REGISTRY_PREAMBLE_HEADER, 0, 6) &amp;&amp; doConnectionRegistryResponse()</span>
-<span class="source-line-no">757</span><span id="line-757">    ) {</span>
-<span class="source-line-no">758</span><span id="line-758">      return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">759</span><span id="line-759">    }</span>
-<span class="source-line-no">760</span><span id="line-760">    if (</span>
-<span class="source-line-no">761</span><span id="line-761">      ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
-<span class="source-line-no">762</span><span id="line-762">        RpcClient.SECURITY_PREAMBLE_HEADER, 0, 6)</span>
-<span class="source-line-no">763</span><span id="line-763">    ) {</span>
-<span class="source-line-no">764</span><span id="line-764">      doSecurityPreambleResponse();</span>
-<span class="source-line-no">765</span><span id="line-765">      return PreambleResponse.CONTINUE;</span>
-<span class="source-line-no">766</span><span id="line-766">    }</span>
-<span class="source-line-no">767</span><span id="line-767">    if (!ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 4, RPC_HEADER, 0, 4)) {</span>
-<span class="source-line-no">768</span><span id="line-768">      doBadPreambleHandling(</span>
-<span class="source-line-no">769</span><span id="line-769">        "Expected HEADER=" + Bytes.toStringBinary(RPC_HEADER) + " but received HEADER="</span>
-<span class="source-line-no">770</span><span id="line-770">          + Bytes.toStringBinary(</span>
-<span class="source-line-no">771</span><span id="line-771">            ByteBufferUtils.toBytes(preambleBuffer, preambleBuffer.position(), RPC_HEADER.length),</span>
-<span class="source-line-no">772</span><span id="line-772">            0, RPC_HEADER.length)</span>
-<span class="source-line-no">773</span><span id="line-773">          + " from " + toString());</span>
-<span class="source-line-no">774</span><span id="line-774">      return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">775</span><span id="line-775">    }</span>
-<span class="source-line-no">776</span><span id="line-776">    int version = preambleBuffer.get(preambleBuffer.position() + 4) &amp; 0xFF;</span>
-<span class="source-line-no">777</span><span id="line-777">    byte authByte = preambleBuffer.get(preambleBuffer.position() + 5);</span>
-<span class="source-line-no">778</span><span id="line-778">    if (version != RpcServer.CURRENT_VERSION) {</span>
-<span class="source-line-no">779</span><span id="line-779">      String msg = getFatalConnectionString(version, authByte);</span>
-<span class="source-line-no">780</span><span id="line-780">      doBadPreambleHandling(msg, new WrongVersionException(msg));</span>
-<span class="source-line-no">781</span><span id="line-781">      return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">782</span><span id="line-782">    }</span>
-<span class="source-line-no">783</span><span id="line-783"></span>
-<span class="source-line-no">784</span><span id="line-784">    this.provider = rpcServer.saslProviders.selectProvider(authByte);</span>
-<span class="source-line-no">785</span><span id="line-785">    if (this.provider == null) {</span>
-<span class="source-line-no">786</span><span id="line-786">      String msg = getFatalConnectionString(version, authByte);</span>
-<span class="source-line-no">787</span><span id="line-787">      doBadPreambleHandling(msg, new BadAuthException(msg));</span>
-<span class="source-line-no">788</span><span id="line-788">      return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">789</span><span id="line-789">    }</span>
-<span class="source-line-no">790</span><span id="line-790">    // TODO this is a wart while simple auth'n doesn't go through sasl.</span>
-<span class="source-line-no">791</span><span id="line-791">    if (this.rpcServer.isSecurityEnabled &amp;&amp; isSimpleAuthentication()) {</span>
-<span class="source-line-no">792</span><span id="line-792">      if (this.rpcServer.allowFallbackToSimpleAuth) {</span>
-<span class="source-line-no">793</span><span id="line-793">        this.rpcServer.metrics.authenticationFallback();</span>
-<span class="source-line-no">794</span><span id="line-794">        authenticatedWithFallback = true;</span>
-<span class="source-line-no">795</span><span id="line-795">      } else {</span>
-<span class="source-line-no">796</span><span id="line-796">        AccessDeniedException ae = new AccessDeniedException("Authentication is required");</span>
-<span class="source-line-no">797</span><span id="line-797">        doRespond(getErrorResponse(ae.getMessage(), ae));</span>
-<span class="source-line-no">798</span><span id="line-798">        return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">799</span><span id="line-799">      }</span>
-<span class="source-line-no">800</span><span id="line-800">    }</span>
-<span class="source-line-no">801</span><span id="line-801">    if (!this.rpcServer.isSecurityEnabled &amp;&amp; !isSimpleAuthentication()) {</span>
-<span class="source-line-no">802</span><span id="line-802">      doRawSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslUtil.SWITCH_TO_SIMPLE_AUTH), null,</span>
-<span class="source-line-no">803</span><span id="line-803">        null);</span>
-<span class="source-line-no">804</span><span id="line-804">      provider = rpcServer.saslProviders.getSimpleProvider();</span>
-<span class="source-line-no">805</span><span id="line-805">      // client has already sent the initial Sasl message and we</span>
-<span class="source-line-no">806</span><span id="line-806">      // should ignore it. Both client and server should fall back</span>
-<span class="source-line-no">807</span><span id="line-807">      // to simple auth from now on.</span>
-<span class="source-line-no">808</span><span id="line-808">      skipInitialSaslHandshake = true;</span>
-<span class="source-line-no">809</span><span id="line-809">    }</span>
-<span class="source-line-no">810</span><span id="line-810">    useSasl = !(provider instanceof SimpleSaslServerAuthenticationProvider);</span>
-<span class="source-line-no">811</span><span id="line-811">    return PreambleResponse.SUCCEED;</span>
-<span class="source-line-no">812</span><span id="line-812">  }</span>
-<span class="source-line-no">813</span><span id="line-813"></span>
-<span class="source-line-no">814</span><span id="line-814">  boolean isSimpleAuthentication() {</span>
-<span class="source-line-no">815</span><span id="line-815">    return Objects.requireNonNull(provider) instanceof SimpleSaslServerAuthenticationProvider;</span>
+<span class="source-line-no">696</span><span id="line-696">  private void doBadPreambleHandling(String msg) throws IOException {</span>
+<span class="source-line-no">697</span><span id="line-697">    doBadPreambleHandling(msg, new FatalConnectionException(msg));</span>
+<span class="source-line-no">698</span><span id="line-698">  }</span>
+<span class="source-line-no">699</span><span id="line-699"></span>
+<span class="source-line-no">700</span><span id="line-700">  private void doBadPreambleHandling(String msg, Exception e) throws IOException {</span>
+<span class="source-line-no">701</span><span id="line-701">    RpcServer.LOG.warn(msg, e);</span>
+<span class="source-line-no">702</span><span id="line-702">    doRespond(getErrorResponse(msg, e));</span>
+<span class="source-line-no">703</span><span id="line-703">  }</span>
+<span class="source-line-no">704</span><span id="line-704"></span>
+<span class="source-line-no">705</span><span id="line-705">  private void doPreambleResponse(Message resp) throws IOException {</span>
+<span class="source-line-no">706</span><span id="line-706">    ResponseHeader header = ResponseHeader.newBuilder().setCallId(-1).build();</span>
+<span class="source-line-no">707</span><span id="line-707">    ByteBuffer buf = ServerCall.createHeaderAndMessageBytes(resp, header, 0, null);</span>
+<span class="source-line-no">708</span><span id="line-708">    BufferChain bufChain = new BufferChain(buf);</span>
+<span class="source-line-no">709</span><span id="line-709">    doRespond(() -&gt; bufChain);</span>
+<span class="source-line-no">710</span><span id="line-710">  }</span>
+<span class="source-line-no">711</span><span id="line-711"></span>
+<span class="source-line-no">712</span><span id="line-712">  private boolean doConnectionRegistryResponse() throws IOException {</span>
+<span class="source-line-no">713</span><span id="line-713">    if (!(rpcServer.server instanceof ConnectionRegistryEndpoint)) {</span>
+<span class="source-line-no">714</span><span id="line-714">      // should be in tests or some scenarios where we should not reach here</span>
+<span class="source-line-no">715</span><span id="line-715">      return false;</span>
+<span class="source-line-no">716</span><span id="line-716">    }</span>
+<span class="source-line-no">717</span><span id="line-717">    // on backup masters, this request may be blocked since we need to fetch it from filesystem,</span>
+<span class="source-line-no">718</span><span id="line-718">    // but since it is just backup master, it is not a critical problem</span>
+<span class="source-line-no">719</span><span id="line-719">    String clusterId = ((ConnectionRegistryEndpoint) rpcServer.server).getClusterId();</span>
+<span class="source-line-no">720</span><span id="line-720">    RpcServer.LOG.debug("Response connection registry, clusterId = '{}'", clusterId);</span>
+<span class="source-line-no">721</span><span id="line-721">    if (clusterId == null) {</span>
+<span class="source-line-no">722</span><span id="line-722">      // should be in tests or some scenarios where we should not reach here</span>
+<span class="source-line-no">723</span><span id="line-723">      return false;</span>
+<span class="source-line-no">724</span><span id="line-724">    }</span>
+<span class="source-line-no">725</span><span id="line-725">    GetConnectionRegistryResponse resp =</span>
+<span class="source-line-no">726</span><span id="line-726">      GetConnectionRegistryResponse.newBuilder().setClusterId(clusterId).build();</span>
+<span class="source-line-no">727</span><span id="line-727">    doPreambleResponse(resp);</span>
+<span class="source-line-no">728</span><span id="line-728">    return true;</span>
+<span class="source-line-no">729</span><span id="line-729">  }</span>
+<span class="source-line-no">730</span><span id="line-730"></span>
+<span class="source-line-no">731</span><span id="line-731">  private void doSecurityPreambleResponse() throws IOException {</span>
+<span class="source-line-no">732</span><span id="line-732">    if (rpcServer.isSecurityEnabled) {</span>
+<span class="source-line-no">733</span><span id="line-733">      SecurityPreamableResponse resp = SecurityPreamableResponse.newBuilder()</span>
+<span class="source-line-no">734</span><span id="line-734">        .setServerPrincipal(rpcServer.serverPrincipal).build();</span>
+<span class="source-line-no">735</span><span id="line-735">      doPreambleResponse(resp);</span>
+<span class="source-line-no">736</span><span id="line-736">    } else {</span>
+<span class="source-line-no">737</span><span id="line-737">      // security is not enabled, do not need a principal when connecting, throw a special exception</span>
+<span class="source-line-no">738</span><span id="line-738">      // to let client know it should just use simple authentication</span>
+<span class="source-line-no">739</span><span id="line-739">      doRespond(getErrorResponse("security is not enabled", new SecurityNotEnabledException()));</span>
+<span class="source-line-no">740</span><span id="line-740">    }</span>
+<span class="source-line-no">741</span><span id="line-741">  }</span>
+<span class="source-line-no">742</span><span id="line-742"></span>
+<span class="source-line-no">743</span><span id="line-743">  protected final void callCleanupIfNeeded() {</span>
+<span class="source-line-no">744</span><span id="line-744">    if (callCleanup != null) {</span>
+<span class="source-line-no">745</span><span id="line-745">      callCleanup.run();</span>
+<span class="source-line-no">746</span><span id="line-746">      callCleanup = null;</span>
+<span class="source-line-no">747</span><span id="line-747">    }</span>
+<span class="source-line-no">748</span><span id="line-748">  }</span>
+<span class="source-line-no">749</span><span id="line-749"></span>
+<span class="source-line-no">750</span><span id="line-750">  protected enum PreambleResponse {</span>
+<span class="source-line-no">751</span><span id="line-751">    SUCCEED, // successfully processed the rpc preamble header</span>
+<span class="source-line-no">752</span><span id="line-752">    CONTINUE, // the preamble header is for other purpose, wait for the rpc preamble header</span>
+<span class="source-line-no">753</span><span id="line-753">    CLOSE // close the rpc connection</span>
+<span class="source-line-no">754</span><span id="line-754">  }</span>
+<span class="source-line-no">755</span><span id="line-755"></span>
+<span class="source-line-no">756</span><span id="line-756">  protected final PreambleResponse processPreamble(ByteBuffer preambleBuffer) throws IOException {</span>
+<span class="source-line-no">757</span><span id="line-757">    assert preambleBuffer.remaining() == 6;</span>
+<span class="source-line-no">758</span><span id="line-758">    if (</span>
+<span class="source-line-no">759</span><span id="line-759">      ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
+<span class="source-line-no">760</span><span id="line-760">        RpcClient.REGISTRY_PREAMBLE_HEADER, 0, 6) &amp;&amp; doConnectionRegistryResponse()</span>
+<span class="source-line-no">761</span><span id="line-761">    ) {</span>
+<span class="source-line-no">762</span><span id="line-762">      return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">763</span><span id="line-763">    }</span>
+<span class="source-line-no">764</span><span id="line-764">    if (</span>
+<span class="source-line-no">765</span><span id="line-765">      ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
+<span class="source-line-no">766</span><span id="line-766">        RpcClient.SECURITY_PREAMBLE_HEADER, 0, 6)</span>
+<span class="source-line-no">767</span><span id="line-767">    ) {</span>
+<span class="source-line-no">768</span><span id="line-768">      doSecurityPreambleResponse();</span>
+<span class="source-line-no">769</span><span id="line-769">      return PreambleResponse.CONTINUE;</span>
+<span class="source-line-no">770</span><span id="line-770">    }</span>
+<span class="source-line-no">771</span><span id="line-771">    if (!ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 4, RPC_HEADER, 0, 4)) {</span>
+<span class="source-line-no">772</span><span id="line-772">      doBadPreambleHandling(</span>
+<span class="source-line-no">773</span><span id="line-773">        "Expected HEADER=" + Bytes.toStringBinary(RPC_HEADER) + " but received HEADER="</span>
+<span class="source-line-no">774</span><span id="line-774">          + Bytes.toStringBinary(</span>
+<span class="source-line-no">775</span><span id="line-775">            ByteBufferUtils.toBytes(preambleBuffer, preambleBuffer.position(), RPC_HEADER.length),</span>
+<span class="source-line-no">776</span><span id="line-776">            0, RPC_HEADER.length)</span>
+<span class="source-line-no">777</span><span id="line-777">          + " from " + toString());</span>
+<span class="source-line-no">778</span><span id="line-778">      return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">779</span><span id="line-779">    }</span>
+<span class="source-line-no">780</span><span id="line-780">    int version = preambleBuffer.get(preambleBuffer.position() + 4) &amp; 0xFF;</span>
+<span class="source-line-no">781</span><span id="line-781">    byte authByte = preambleBuffer.get(preambleBuffer.position() + 5);</span>
+<span class="source-line-no">782</span><span id="line-782">    if (version != RpcServer.CURRENT_VERSION) {</span>
+<span class="source-line-no">783</span><span id="line-783">      String msg = getFatalConnectionString(version, authByte);</span>
+<span class="source-line-no">784</span><span id="line-784">      doBadPreambleHandling(msg, new WrongVersionException(msg));</span>
+<span class="source-line-no">785</span><span id="line-785">      return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">786</span><span id="line-786">    }</span>
+<span class="source-line-no">787</span><span id="line-787"></span>
+<span class="source-line-no">788</span><span id="line-788">    this.provider = rpcServer.saslProviders.selectProvider(authByte);</span>
+<span class="source-line-no">789</span><span id="line-789">    if (this.provider == null) {</span>
+<span class="source-line-no">790</span><span id="line-790">      String msg = getFatalConnectionString(version, authByte);</span>
+<span class="source-line-no">791</span><span id="line-791">      doBadPreambleHandling(msg, new BadAuthException(msg));</span>
+<span class="source-line-no">792</span><span id="line-792">      return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">793</span><span id="line-793">    }</span>
+<span class="source-line-no">794</span><span id="line-794">    // TODO this is a wart while simple auth'n doesn't go through sasl.</span>
+<span class="source-line-no">795</span><span id="line-795">    if (this.rpcServer.isSecurityEnabled &amp;&amp; isSimpleAuthentication()) {</span>
+<span class="source-line-no">796</span><span id="line-796">      if (this.rpcServer.allowFallbackToSimpleAuth) {</span>
+<span class="source-line-no">797</span><span id="line-797">        this.rpcServer.metrics.authenticationFallback();</span>
+<span class="source-line-no">798</span><span id="line-798">        authenticatedWithFallback = true;</span>
+<span class="source-line-no">799</span><span id="line-799">      } else {</span>
+<span class="source-line-no">800</span><span id="line-800">        AccessDeniedException ae = new AccessDeniedException("Authentication is required");</span>
+<span class="source-line-no">801</span><span id="line-801">        doRespond(getErrorResponse(ae.getMessage(), ae));</span>
+<span class="source-line-no">802</span><span id="line-802">        return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">803</span><span id="line-803">      }</span>
+<span class="source-line-no">804</span><span id="line-804">    }</span>
+<span class="source-line-no">805</span><span id="line-805">    if (!this.rpcServer.isSecurityEnabled &amp;&amp; !isSimpleAuthentication()) {</span>
+<span class="source-line-no">806</span><span id="line-806">      doRawSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslUtil.SWITCH_TO_SIMPLE_AUTH), null,</span>
+<span class="source-line-no">807</span><span id="line-807">        null);</span>
+<span class="source-line-no">808</span><span id="line-808">      provider = rpcServer.saslProviders.getSimpleProvider();</span>
+<span class="source-line-no">809</span><span id="line-809">      // client has already sent the initial Sasl message and we</span>
+<span class="source-line-no">810</span><span id="line-810">      // should ignore it. Both client and server should fall back</span>
+<span class="source-line-no">811</span><span id="line-811">      // to simple auth from now on.</span>
+<span class="source-line-no">812</span><span id="line-812">      skipInitialSaslHandshake = true;</span>
+<span class="source-line-no">813</span><span id="line-813">    }</span>
+<span class="source-line-no">814</span><span id="line-814">    useSasl = !(provider instanceof SimpleSaslServerAuthenticationProvider);</span>
+<span class="source-line-no">815</span><span id="line-815">    return PreambleResponse.SUCCEED;</span>
 <span class="source-line-no">816</span><span id="line-816">  }</span>
 <span class="source-line-no">817</span><span id="line-817"></span>
-<span class="source-line-no">818</span><span id="line-818">  public abstract boolean isConnectionOpen();</span>
-<span class="source-line-no">819</span><span id="line-819"></span>
-<span class="source-line-no">820</span><span id="line-820">  public abstract ServerCall&lt;?&gt; createCall(int id, BlockingService service, MethodDescriptor md,</span>
-<span class="source-line-no">821</span><span id="line-821">    RequestHeader header, Message param, ExtendedCellScanner cellScanner, long size,</span>
-<span class="source-line-no">822</span><span id="line-822">    InetAddress remoteAddress, int timeout, CallCleanup reqCleanup);</span>
+<span class="source-line-no">818</span><span id="line-818">  boolean isSimpleAuthentication() {</span>
+<span class="source-line-no">819</span><span id="line-819">    return Objects.requireNonNull(provider) instanceof SimpleSaslServerAuthenticationProvider;</span>
+<span class="source-line-no">820</span><span id="line-820">  }</span>
+<span class="source-line-no">821</span><span id="line-821"></span>
+<span class="source-line-no">822</span><span id="line-822">  public abstract boolean isConnectionOpen();</span>
 <span class="source-line-no">823</span><span id="line-823"></span>
-<span class="source-line-no">824</span><span id="line-824">  private static class ByteBuffByteInput extends ByteInput {</span>
-<span class="source-line-no">825</span><span id="line-825"></span>
-<span class="source-line-no">826</span><span id="line-826">    private ByteBuff buf;</span>
-<span class="source-line-no">827</span><span id="line-827">    private int length;</span>
-<span class="source-line-no">828</span><span id="line-828"></span>
-<span class="source-line-no">829</span><span id="line-829">    ByteBuffByteInput(ByteBuff buf, int length) {</span>
-<span class="source-line-no">830</span><span id="line-830">      this.buf = buf;</span>
-<span class="source-line-no">831</span><span id="line-831">      this.length = length;</span>
-<span class="source-line-no">832</span><span id="line-832">    }</span>
-<span class="source-line-no">833</span><span id="line-833"></span>
-<span class="source-line-no">834</span><span id="line-834">    @Override</span>
-<span class="source-line-no">835</span><span id="line-835">    public byte read(int offset) {</span>
-<span class="source-line-no">836</span><span id="line-836">      return this.buf.get(offset);</span>
-<span class="source-line-no">837</span><span id="line-837">    }</span>
-<span class="source-line-no">838</span><span id="line-838"></span>
-<span class="source-line-no">839</span><span id="line-839">    @Override</span>
-<span class="source-line-no">840</span><span id="line-840">    public int read(int offset, byte[] out, int outOffset, int len) {</span>
-<span class="source-line-no">841</span><span id="line-841">      this.buf.get(offset, out, outOffset, len);</span>
-<span class="source-line-no">842</span><span id="line-842">      return len;</span>
-<span class="source-line-no">843</span><span id="line-843">    }</span>
-<span class="source-line-no">844</span><span id="line-844"></span>
-<span class="source-line-no">845</span><span id="line-845">    @Override</span>
-<span class="source-line-no">846</span><span id="line-846">    public int read(int offset, ByteBuffer out) {</span>
-<span class="source-line-no">847</span><span id="line-847">      int len = out.remaining();</span>
-<span class="source-line-no">848</span><span id="line-848">      this.buf.get(out, offset, len);</span>
-<span class="source-line-no">849</span><span id="line-849">      return len;</span>
-<span class="source-line-no">850</span><span id="line-850">    }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852">    @Override</span>
-<span class="source-line-no">853</span><span id="line-853">    public long readLong(int offset) {</span>
-<span class="source-line-no">854</span><span id="line-854">      return this.buf.getLong(offset);</span>
-<span class="source-line-no">855</span><span id="line-855">    }</span>
-<span class="source-line-no">856</span><span id="line-856"></span>
-<span class="source-line-no">857</span><span id="line-857">    @Override</span>
-<span class="source-line-no">858</span><span id="line-858">    public int size() {</span>
-<span class="source-line-no">859</span><span id="line-859">      return this.length;</span>
-<span class="source-line-no">860</span><span id="line-860">    }</span>
-<span class="source-line-no">861</span><span id="line-861"></span>
-<span class="source-line-no">862</span><span id="line-862">  }</span>
-<span class="source-line-no">863</span><span id="line-863">}</span>
+<span class="source-line-no">824</span><span id="line-824">  public abstract ServerCall&lt;?&gt; createCall(int id, BlockingService service, MethodDescriptor md,</span>
+<span class="source-line-no">825</span><span id="line-825">    RequestHeader header, Message param, ExtendedCellScanner cellScanner, long size,</span>
+<span class="source-line-no">826</span><span id="line-826">    InetAddress remoteAddress, int timeout, CallCleanup reqCleanup);</span>
+<span class="source-line-no">827</span><span id="line-827"></span>
+<span class="source-line-no">828</span><span id="line-828">  private static class ByteBuffByteInput extends ByteInput {</span>
+<span class="source-line-no">829</span><span id="line-829"></span>
+<span class="source-line-no">830</span><span id="line-830">    private ByteBuff buf;</span>
+<span class="source-line-no">831</span><span id="line-831">    private int length;</span>
+<span class="source-line-no">832</span><span id="line-832"></span>
+<span class="source-line-no">833</span><span id="line-833">    ByteBuffByteInput(ByteBuff buf, int length) {</span>
+<span class="source-line-no">834</span><span id="line-834">      this.buf = buf;</span>
+<span class="source-line-no">835</span><span id="line-835">      this.length = length;</span>
+<span class="source-line-no">836</span><span id="line-836">    }</span>
+<span class="source-line-no">837</span><span id="line-837"></span>
+<span class="source-line-no">838</span><span id="line-838">    @Override</span>
+<span class="source-line-no">839</span><span id="line-839">    public byte read(int offset) {</span>
+<span class="source-line-no">840</span><span id="line-840">      return this.buf.get(offset);</span>
+<span class="source-line-no">841</span><span id="line-841">    }</span>
+<span class="source-line-no">842</span><span id="line-842"></span>
+<span class="source-line-no">843</span><span id="line-843">    @Override</span>
+<span class="source-line-no">844</span><span id="line-844">    public int read(int offset, byte[] out, int outOffset, int len) {</span>
+<span class="source-line-no">845</span><span id="line-845">      this.buf.get(offset, out, outOffset, len);</span>
+<span class="source-line-no">846</span><span id="line-846">      return len;</span>
+<span class="source-line-no">847</span><span id="line-847">    }</span>
+<span class="source-line-no">848</span><span id="line-848"></span>
+<span class="source-line-no">849</span><span id="line-849">    @Override</span>
+<span class="source-line-no">850</span><span id="line-850">    public int read(int offset, ByteBuffer out) {</span>
+<span class="source-line-no">851</span><span id="line-851">      int len = out.remaining();</span>
+<span class="source-line-no">852</span><span id="line-852">      this.buf.get(out, offset, len);</span>
+<span class="source-line-no">853</span><span id="line-853">      return len;</span>
+<span class="source-line-no">854</span><span id="line-854">    }</span>
+<span class="source-line-no">855</span><span id="line-855"></span>
+<span class="source-line-no">856</span><span id="line-856">    @Override</span>
+<span class="source-line-no">857</span><span id="line-857">    public long readLong(int offset) {</span>
+<span class="source-line-no">858</span><span id="line-858">      return this.buf.getLong(offset);</span>
+<span class="source-line-no">859</span><span id="line-859">    }</span>
+<span class="source-line-no">860</span><span id="line-860"></span>
+<span class="source-line-no">861</span><span id="line-861">    @Override</span>
+<span class="source-line-no">862</span><span id="line-862">    public int size() {</span>
+<span class="source-line-no">863</span><span id="line-863">      return this.length;</span>
+<span class="source-line-no">864</span><span id="line-864">    }</span>
+<span class="source-line-no">865</span><span id="line-865"></span>
+<span class="source-line-no">866</span><span id="line-866">  }</span>
+<span class="source-line-no">867</span><span id="line-867">}</span>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
similarity index 83%
copy from devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
copy to apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
index f48206b6470..b95e539c00b 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
@@ -109,7 +109,7 @@
 <span class="source-line-no">096</span><span id="line-96">@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "VO_VOLATILE_INCREMENT",</span>
 <span class="source-line-no">097</span><span id="line-97">    justification = "False positive according to http://sourceforge.net/p/findbugs/bugs/1032/")</span>
 <span class="source-line-no">098</span><span id="line-98">@InterfaceAudience.Private</span>
-<span class="source-line-no">099</span><span id="line-99">abstract class ServerRpcConnection implements Closeable {</span>
+<span class="source-line-no">099</span><span id="line-99">public abstract class ServerRpcConnection implements Closeable {</span>
 <span class="source-line-no">100</span><span id="line-100"></span>
 <span class="source-line-no">101</span><span id="line-101">  private static final TextMapGetter&lt;RPCTInfo&gt; getter = new RPCTInfoGetter();</span>
 <span class="source-line-no">102</span><span id="line-102"></span>
@@ -500,380 +500,384 @@
 <span class="source-line-no">487</span><span id="line-487">      this.hostAddress, this.remotePort, version, this.useSasl, this.ugi, serviceName);</span>
 <span class="source-line-no">488</span><span id="line-488">  }</span>
 <span class="source-line-no">489</span><span id="line-489"></span>
-<span class="source-line-no">490</span><span id="line-490">  /**</span>
-<span class="source-line-no">491</span><span id="line-491">   * Send the response for connection header</span>
-<span class="source-line-no">492</span><span id="line-492">   */</span>
-<span class="source-line-no">493</span><span id="line-493">  private void sendConnectionHeaderResponseIfNeeded() throws FatalConnectionException {</span>
-<span class="source-line-no">494</span><span id="line-494">    Pair&lt;RPCProtos.ConnectionHeaderResponse, CryptoAES&gt; pair = setupCryptoCipher();</span>
-<span class="source-line-no">495</span><span id="line-495">    // Response the connection header if Crypto AES is enabled</span>
-<span class="source-line-no">496</span><span id="line-496">    if (pair == null) {</span>
-<span class="source-line-no">497</span><span id="line-497">      return;</span>
-<span class="source-line-no">498</span><span id="line-498">    }</span>
-<span class="source-line-no">499</span><span id="line-499">    try {</span>
-<span class="source-line-no">500</span><span id="line-500">      int size = pair.getFirst().getSerializedSize();</span>
-<span class="source-line-no">501</span><span id="line-501">      BufferChain bc;</span>
-<span class="source-line-no">502</span><span id="line-502">      try (ByteBufferOutputStream bbOut = new ByteBufferOutputStream(4 + size);</span>
-<span class="source-line-no">503</span><span id="line-503">        DataOutputStream out = new DataOutputStream(bbOut)) {</span>
-<span class="source-line-no">504</span><span id="line-504">        out.writeInt(size);</span>
-<span class="source-line-no">505</span><span id="line-505">        pair.getFirst().writeTo(out);</span>
-<span class="source-line-no">506</span><span id="line-506">        bc = new BufferChain(bbOut.getByteBuffer());</span>
-<span class="source-line-no">507</span><span id="line-507">      }</span>
-<span class="source-line-no">508</span><span id="line-508">      doRespond(new RpcResponse() {</span>
-<span class="source-line-no">509</span><span id="line-509"></span>
-<span class="source-line-no">510</span><span id="line-510">        @Override</span>
-<span class="source-line-no">511</span><span id="line-511">        public BufferChain getResponse() {</span>
-<span class="source-line-no">512</span><span id="line-512">          return bc;</span>
-<span class="source-line-no">513</span><span id="line-513">        }</span>
-<span class="source-line-no">514</span><span id="line-514"></span>
-<span class="source-line-no">515</span><span id="line-515">        @Override</span>
-<span class="source-line-no">516</span><span id="line-516">        public void done() {</span>
-<span class="source-line-no">517</span><span id="line-517">          // must switch after sending the connection header response, as the client still uses the</span>
-<span class="source-line-no">518</span><span id="line-518">          // original SaslClient to unwrap the data we send back</span>
-<span class="source-line-no">519</span><span id="line-519">          saslServer.switchToCryptoAES(pair.getSecond());</span>
-<span class="source-line-no">520</span><span id="line-520">        }</span>
-<span class="source-line-no">521</span><span id="line-521">      });</span>
-<span class="source-line-no">522</span><span id="line-522">    } catch (IOException ex) {</span>
-<span class="source-line-no">523</span><span id="line-523">      throw new UnsupportedCryptoException(ex.getMessage(), ex);</span>
-<span class="source-line-no">524</span><span id="line-524">    }</span>
-<span class="source-line-no">525</span><span id="line-525">  }</span>
-<span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527">  protected abstract void doRespond(RpcResponse resp) throws IOException;</span>
-<span class="source-line-no">528</span><span id="line-528"></span>
-<span class="source-line-no">529</span><span id="line-529">  /**</span>
-<span class="source-line-no">530</span><span id="line-530">   * Has the request header and the request param and optionally encoded data buffer all in this one</span>
-<span class="source-line-no">531</span><span id="line-531">   * array.</span>
-<span class="source-line-no">532</span><span id="line-532">   * &lt;p/&gt;</span>
-<span class="source-line-no">533</span><span id="line-533">   * Will be overridden in tests.</span>
-<span class="source-line-no">534</span><span id="line-534">   */</span>
-<span class="source-line-no">535</span><span id="line-535">  protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {</span>
-<span class="source-line-no">536</span><span id="line-536">    long totalRequestSize = buf.limit();</span>
-<span class="source-line-no">537</span><span id="line-537">    int offset = 0;</span>
-<span class="source-line-no">538</span><span id="line-538">    // Here we read in the header. We avoid having pb</span>
-<span class="source-line-no">539</span><span id="line-539">    // do its default 4k allocation for CodedInputStream. We force it to use</span>
-<span class="source-line-no">540</span><span id="line-540">    // backing array.</span>
-<span class="source-line-no">541</span><span id="line-541">    CodedInputStream cis = createCis(buf);</span>
-<span class="source-line-no">542</span><span id="line-542">    int headerSize = cis.readRawVarint32();</span>
-<span class="source-line-no">543</span><span id="line-543">    offset = cis.getTotalBytesRead();</span>
-<span class="source-line-no">544</span><span id="line-544">    Message.Builder builder = RequestHeader.newBuilder();</span>
-<span class="source-line-no">545</span><span id="line-545">    ProtobufUtil.mergeFrom(builder, cis, headerSize);</span>
-<span class="source-line-no">546</span><span id="line-546">    RequestHeader header = (RequestHeader) builder.build();</span>
-<span class="source-line-no">547</span><span id="line-547">    offset += headerSize;</span>
-<span class="source-line-no">548</span><span id="line-548">    Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()</span>
-<span class="source-line-no">549</span><span id="line-549">      .extract(Context.current(), header.getTraceInfo(), getter);</span>
-<span class="source-line-no">550</span><span id="line-550"></span>
-<span class="source-line-no">551</span><span id="line-551">    // n.b. Management of this Span instance is a little odd. Most exit paths from this try scope</span>
-<span class="source-line-no">552</span><span id="line-552">    // are early-exits due to error cases. There's only one success path, the asynchronous call to</span>
-<span class="source-line-no">553</span><span id="line-553">    // RpcScheduler#dispatch. The success path assumes ownership of the span, which is represented</span>
-<span class="source-line-no">554</span><span id="line-554">    // by null-ing out the reference in this scope. All other paths end the span. Thus, and in</span>
-<span class="source-line-no">555</span><span id="line-555">    // order to avoid accidentally orphaning the span, the call to Span#end happens in a finally</span>
-<span class="source-line-no">556</span><span id="line-556">    // block iff the span is non-null.</span>
-<span class="source-line-no">557</span><span id="line-557">    Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);</span>
-<span class="source-line-no">558</span><span id="line-558">    try (Scope ignored = span.makeCurrent()) {</span>
-<span class="source-line-no">559</span><span id="line-559">      int id = header.getCallId();</span>
-<span class="source-line-no">560</span><span id="line-560">      // HBASE-28128 - if server is aborting, don't bother trying to process. It will</span>
-<span class="source-line-no">561</span><span id="line-561">      // fail at the handler layer, but worse might result in CallQueueTooBigException if the</span>
-<span class="source-line-no">562</span><span id="line-562">      // queue is full but server is not properly processing requests. Better to throw an aborted</span>
-<span class="source-line-no">563</span><span id="line-563">      // exception here so that the client can properly react.</span>
-<span class="source-line-no">564</span><span id="line-564">      if (rpcServer.server != null &amp;&amp; rpcServer.server.isAborted()) {</span>
-<span class="source-line-no">565</span><span id="line-565">        RegionServerAbortedException serverIsAborted = new RegionServerAbortedException(</span>
-<span class="source-line-no">566</span><span id="line-566">          "Server " + rpcServer.server.getServerName() + " aborting");</span>
-<span class="source-line-no">567</span><span id="line-567">        this.rpcServer.metrics.exception(serverIsAborted);</span>
-<span class="source-line-no">568</span><span id="line-568">        sendErrorResponseForCall(id, totalRequestSize, span, serverIsAborted.getMessage(),</span>
-<span class="source-line-no">569</span><span id="line-569">          serverIsAborted);</span>
-<span class="source-line-no">570</span><span id="line-570">        return;</span>
-<span class="source-line-no">571</span><span id="line-571">      }</span>
-<span class="source-line-no">572</span><span id="line-572"></span>
-<span class="source-line-no">573</span><span id="line-573">      if (RpcServer.LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">574</span><span id="line-574">        RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header)</span>
-<span class="source-line-no">575</span><span id="line-575">          + " totalRequestSize: " + totalRequestSize + " bytes");</span>
-<span class="source-line-no">576</span><span id="line-576">      }</span>
-<span class="source-line-no">577</span><span id="line-577">      // Enforcing the call queue size, this triggers a retry in the client</span>
-<span class="source-line-no">578</span><span id="line-578">      // This is a bit late to be doing this check - we have already read in the</span>
-<span class="source-line-no">579</span><span id="line-579">      // total request.</span>
-<span class="source-line-no">580</span><span id="line-580">      if (</span>
-<span class="source-line-no">581</span><span id="line-581">        (totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum())</span>
-<span class="source-line-no">582</span><span id="line-582">            &gt; this.rpcServer.maxQueueSizeInBytes</span>
-<span class="source-line-no">583</span><span id="line-583">      ) {</span>
-<span class="source-line-no">584</span><span id="line-584">        this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">585</span><span id="line-585">        sendErrorResponseForCall(id, totalRequestSize, span,</span>
-<span class="source-line-no">586</span><span id="line-586">          "Call queue is full on " + this.rpcServer.server.getServerName()</span>
-<span class="source-line-no">587</span><span id="line-587">            + ", is hbase.ipc.server.max.callqueue.size too small?",</span>
-<span class="source-line-no">588</span><span id="line-588">          RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">589</span><span id="line-589">        return;</span>
-<span class="source-line-no">590</span><span id="line-590">      }</span>
-<span class="source-line-no">591</span><span id="line-591">      MethodDescriptor md = null;</span>
-<span class="source-line-no">592</span><span id="line-592">      Message param = null;</span>
-<span class="source-line-no">593</span><span id="line-593">      ExtendedCellScanner cellScanner = null;</span>
-<span class="source-line-no">594</span><span id="line-594">      try {</span>
-<span class="source-line-no">595</span><span id="line-595">        if (header.hasRequestParam() &amp;&amp; header.getRequestParam()) {</span>
-<span class="source-line-no">596</span><span id="line-596">          md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());</span>
-<span class="source-line-no">597</span><span id="line-597">          if (md == null) {</span>
-<span class="source-line-no">598</span><span id="line-598">            throw new UnsupportedOperationException(header.getMethodName());</span>
-<span class="source-line-no">599</span><span id="line-599">          }</span>
-<span class="source-line-no">600</span><span id="line-600">          builder = this.service.getRequestPrototype(md).newBuilderForType();</span>
-<span class="source-line-no">601</span><span id="line-601">          cis.resetSizeCounter();</span>
-<span class="source-line-no">602</span><span id="line-602">          int paramSize = cis.readRawVarint32();</span>
-<span class="source-line-no">603</span><span id="line-603">          offset += cis.getTotalBytesRead();</span>
-<span class="source-line-no">604</span><span id="line-604">          if (builder != null) {</span>
-<span class="source-line-no">605</span><span id="line-605">            ProtobufUtil.mergeFrom(builder, cis, paramSize);</span>
-<span class="source-line-no">606</span><span id="line-606">            param = builder.build();</span>
-<span class="source-line-no">607</span><span id="line-607">          }</span>
-<span class="source-line-no">608</span><span id="line-608">          offset += paramSize;</span>
-<span class="source-line-no">609</span><span id="line-609">        } else {</span>
-<span class="source-line-no">610</span><span id="line-610">          // currently header must have request param, so we directly throw</span>
-<span class="source-line-no">611</span><span id="line-611">          // exception here</span>
-<span class="source-line-no">612</span><span id="line-612">          String msg = "Invalid request header: " + TextFormat.shortDebugString(header)</span>
-<span class="source-line-no">613</span><span id="line-613">            + ", should have param set in it";</span>
-<span class="source-line-no">614</span><span id="line-614">          RpcServer.LOG.warn(msg);</span>
-<span class="source-line-no">615</span><span id="line-615">          throw new DoNotRetryIOException(msg);</span>
-<span class="source-line-no">616</span><span id="line-616">        }</span>
-<span class="source-line-no">617</span><span id="line-617">        if (header.hasCellBlockMeta()) {</span>
-<span class="source-line-no">618</span><span id="line-618">          buf.position(offset);</span>
-<span class="source-line-no">619</span><span id="line-619">          ByteBuff dup = buf.duplicate();</span>
-<span class="source-line-no">620</span><span id="line-620">          dup.limit(offset + header.getCellBlockMeta().getLength());</span>
-<span class="source-line-no">621</span><span id="line-621">          cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec,</span>
-<span class="source-line-no">622</span><span id="line-622">            this.compressionCodec, dup);</span>
-<span class="source-line-no">623</span><span id="line-623">        }</span>
-<span class="source-line-no">624</span><span id="line-624">      } catch (Throwable thrown) {</span>
-<span class="source-line-no">625</span><span id="line-625">        InetSocketAddress address = this.rpcServer.getListenerAddress();</span>
-<span class="source-line-no">626</span><span id="line-626">        String msg = (address != null ? address : "(channel closed)")</span>
-<span class="source-line-no">627</span><span id="line-627">          + " is unable to read call parameter from client " + getHostAddress();</span>
-<span class="source-line-no">628</span><span id="line-628">        RpcServer.LOG.warn(msg, thrown);</span>
-<span class="source-line-no">629</span><span id="line-629"></span>
-<span class="source-line-no">630</span><span id="line-630">        this.rpcServer.metrics.exception(thrown);</span>
-<span class="source-line-no">631</span><span id="line-631"></span>
-<span class="source-line-no">632</span><span id="line-632">        final Throwable responseThrowable;</span>
-<span class="source-line-no">633</span><span id="line-633">        if (thrown instanceof LinkageError) {</span>
-<span class="source-line-no">634</span><span id="line-634">          // probably the hbase hadoop version does not match the running hadoop version</span>
-<span class="source-line-no">635</span><span id="line-635">          responseThrowable = new DoNotRetryIOException(thrown);</span>
-<span class="source-line-no">636</span><span id="line-636">        } else if (thrown instanceof UnsupportedOperationException) {</span>
-<span class="source-line-no">637</span><span id="line-637">          // If the method is not present on the server, do not retry.</span>
-<span class="source-line-no">638</span><span id="line-638">          responseThrowable = new DoNotRetryIOException(thrown);</span>
-<span class="source-line-no">639</span><span id="line-639">        } else {</span>
-<span class="source-line-no">640</span><span id="line-640">          responseThrowable = thrown;</span>
-<span class="source-line-no">641</span><span id="line-641">        }</span>
-<span class="source-line-no">642</span><span id="line-642"></span>
-<span class="source-line-no">643</span><span id="line-643">        sendErrorResponseForCall(id, totalRequestSize, span,</span>
-<span class="source-line-no">644</span><span id="line-644">          msg + "; " + responseThrowable.getMessage(), responseThrowable);</span>
-<span class="source-line-no">645</span><span id="line-645">        return;</span>
-<span class="source-line-no">646</span><span id="line-646">      }</span>
-<span class="source-line-no">647</span><span id="line-647"></span>
-<span class="source-line-no">648</span><span id="line-648">      int timeout = 0;</span>
-<span class="source-line-no">649</span><span id="line-649">      if (header.hasTimeout() &amp;&amp; header.getTimeout() &gt; 0) {</span>
-<span class="source-line-no">650</span><span id="line-650">        timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());</span>
-<span class="source-line-no">651</span><span id="line-651">      }</span>
-<span class="source-line-no">652</span><span id="line-652">      ServerCall&lt;?&gt; call = createCall(id, this.service, md, header, param, cellScanner,</span>
-<span class="source-line-no">653</span><span id="line-653">        totalRequestSize, this.addr, timeout, this.callCleanup);</span>
-<span class="source-line-no">654</span><span id="line-654"></span>
-<span class="source-line-no">655</span><span id="line-655">      if (this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {</span>
-<span class="source-line-no">656</span><span id="line-656">        // unset span do that it's not closed in the finally block</span>
-<span class="source-line-no">657</span><span id="line-657">        span = null;</span>
-<span class="source-line-no">658</span><span id="line-658">      } else {</span>
-<span class="source-line-no">659</span><span id="line-659">        this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());</span>
-<span class="source-line-no">660</span><span id="line-660">        this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">661</span><span id="line-661">        call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION,</span>
-<span class="source-line-no">662</span><span id="line-662">          "Call queue is full on " + this.rpcServer.server.getServerName()</span>
-<span class="source-line-no">663</span><span id="line-663">            + ", too many items queued ?");</span>
-<span class="source-line-no">664</span><span id="line-664">        TraceUtil.setError(span, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">665</span><span id="line-665">        call.sendResponseIfReady();</span>
-<span class="source-line-no">666</span><span id="line-666">      }</span>
-<span class="source-line-no">667</span><span id="line-667">    } finally {</span>
-<span class="source-line-no">668</span><span id="line-668">      if (span != null) {</span>
-<span class="source-line-no">669</span><span id="line-669">        span.end();</span>
+<span class="source-line-no">490</span><span id="line-490">  public ConnectionHeader getConnectionHeader() {</span>
+<span class="source-line-no">491</span><span id="line-491">    return connectionHeader;</span>
+<span class="source-line-no">492</span><span id="line-492">  }</span>
+<span class="source-line-no">493</span><span id="line-493"></span>
+<span class="source-line-no">494</span><span id="line-494">  /**</span>
+<span class="source-line-no">495</span><span id="line-495">   * Send the response for connection header</span>
+<span class="source-line-no">496</span><span id="line-496">   */</span>
+<span class="source-line-no">497</span><span id="line-497">  private void sendConnectionHeaderResponseIfNeeded() throws FatalConnectionException {</span>
+<span class="source-line-no">498</span><span id="line-498">    Pair&lt;RPCProtos.ConnectionHeaderResponse, CryptoAES&gt; pair = setupCryptoCipher();</span>
+<span class="source-line-no">499</span><span id="line-499">    // Response the connection header if Crypto AES is enabled</span>
+<span class="source-line-no">500</span><span id="line-500">    if (pair == null) {</span>
+<span class="source-line-no">501</span><span id="line-501">      return;</span>
+<span class="source-line-no">502</span><span id="line-502">    }</span>
+<span class="source-line-no">503</span><span id="line-503">    try {</span>
+<span class="source-line-no">504</span><span id="line-504">      int size = pair.getFirst().getSerializedSize();</span>
+<span class="source-line-no">505</span><span id="line-505">      BufferChain bc;</span>
+<span class="source-line-no">506</span><span id="line-506">      try (ByteBufferOutputStream bbOut = new ByteBufferOutputStream(4 + size);</span>
+<span class="source-line-no">507</span><span id="line-507">        DataOutputStream out = new DataOutputStream(bbOut)) {</span>
+<span class="source-line-no">508</span><span id="line-508">        out.writeInt(size);</span>
+<span class="source-line-no">509</span><span id="line-509">        pair.getFirst().writeTo(out);</span>
+<span class="source-line-no">510</span><span id="line-510">        bc = new BufferChain(bbOut.getByteBuffer());</span>
+<span class="source-line-no">511</span><span id="line-511">      }</span>
+<span class="source-line-no">512</span><span id="line-512">      doRespond(new RpcResponse() {</span>
+<span class="source-line-no">513</span><span id="line-513"></span>
+<span class="source-line-no">514</span><span id="line-514">        @Override</span>
+<span class="source-line-no">515</span><span id="line-515">        public BufferChain getResponse() {</span>
+<span class="source-line-no">516</span><span id="line-516">          return bc;</span>
+<span class="source-line-no">517</span><span id="line-517">        }</span>
+<span class="source-line-no">518</span><span id="line-518"></span>
+<span class="source-line-no">519</span><span id="line-519">        @Override</span>
+<span class="source-line-no">520</span><span id="line-520">        public void done() {</span>
+<span class="source-line-no">521</span><span id="line-521">          // must switch after sending the connection header response, as the client still uses the</span>
+<span class="source-line-no">522</span><span id="line-522">          // original SaslClient to unwrap the data we send back</span>
+<span class="source-line-no">523</span><span id="line-523">          saslServer.switchToCryptoAES(pair.getSecond());</span>
+<span class="source-line-no">524</span><span id="line-524">        }</span>
+<span class="source-line-no">525</span><span id="line-525">      });</span>
+<span class="source-line-no">526</span><span id="line-526">    } catch (IOException ex) {</span>
+<span class="source-line-no">527</span><span id="line-527">      throw new UnsupportedCryptoException(ex.getMessage(), ex);</span>
+<span class="source-line-no">528</span><span id="line-528">    }</span>
+<span class="source-line-no">529</span><span id="line-529">  }</span>
+<span class="source-line-no">530</span><span id="line-530"></span>
+<span class="source-line-no">531</span><span id="line-531">  protected abstract void doRespond(RpcResponse resp) throws IOException;</span>
+<span class="source-line-no">532</span><span id="line-532"></span>
+<span class="source-line-no">533</span><span id="line-533">  /**</span>
+<span class="source-line-no">534</span><span id="line-534">   * Has the request header and the request param and optionally encoded data buffer all in this one</span>
+<span class="source-line-no">535</span><span id="line-535">   * array.</span>
+<span class="source-line-no">536</span><span id="line-536">   * &lt;p/&gt;</span>
+<span class="source-line-no">537</span><span id="line-537">   * Will be overridden in tests.</span>
+<span class="source-line-no">538</span><span id="line-538">   */</span>
+<span class="source-line-no">539</span><span id="line-539">  protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {</span>
+<span class="source-line-no">540</span><span id="line-540">    long totalRequestSize = buf.limit();</span>
+<span class="source-line-no">541</span><span id="line-541">    int offset = 0;</span>
+<span class="source-line-no">542</span><span id="line-542">    // Here we read in the header. We avoid having pb</span>
+<span class="source-line-no">543</span><span id="line-543">    // do its default 4k allocation for CodedInputStream. We force it to use</span>
+<span class="source-line-no">544</span><span id="line-544">    // backing array.</span>
+<span class="source-line-no">545</span><span id="line-545">    CodedInputStream cis = createCis(buf);</span>
+<span class="source-line-no">546</span><span id="line-546">    int headerSize = cis.readRawVarint32();</span>
+<span class="source-line-no">547</span><span id="line-547">    offset = cis.getTotalBytesRead();</span>
+<span class="source-line-no">548</span><span id="line-548">    Message.Builder builder = RequestHeader.newBuilder();</span>
+<span class="source-line-no">549</span><span id="line-549">    ProtobufUtil.mergeFrom(builder, cis, headerSize);</span>
+<span class="source-line-no">550</span><span id="line-550">    RequestHeader header = (RequestHeader) builder.build();</span>
+<span class="source-line-no">551</span><span id="line-551">    offset += headerSize;</span>
+<span class="source-line-no">552</span><span id="line-552">    Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()</span>
+<span class="source-line-no">553</span><span id="line-553">      .extract(Context.current(), header.getTraceInfo(), getter);</span>
+<span class="source-line-no">554</span><span id="line-554"></span>
+<span class="source-line-no">555</span><span id="line-555">    // n.b. Management of this Span instance is a little odd. Most exit paths from this try scope</span>
+<span class="source-line-no">556</span><span id="line-556">    // are early-exits due to error cases. There's only one success path, the asynchronous call to</span>
+<span class="source-line-no">557</span><span id="line-557">    // RpcScheduler#dispatch. The success path assumes ownership of the span, which is represented</span>
+<span class="source-line-no">558</span><span id="line-558">    // by null-ing out the reference in this scope. All other paths end the span. Thus, and in</span>
+<span class="source-line-no">559</span><span id="line-559">    // order to avoid accidentally orphaning the span, the call to Span#end happens in a finally</span>
+<span class="source-line-no">560</span><span id="line-560">    // block iff the span is non-null.</span>
+<span class="source-line-no">561</span><span id="line-561">    Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);</span>
+<span class="source-line-no">562</span><span id="line-562">    try (Scope ignored = span.makeCurrent()) {</span>
+<span class="source-line-no">563</span><span id="line-563">      int id = header.getCallId();</span>
+<span class="source-line-no">564</span><span id="line-564">      // HBASE-28128 - if server is aborting, don't bother trying to process. It will</span>
+<span class="source-line-no">565</span><span id="line-565">      // fail at the handler layer, but worse might result in CallQueueTooBigException if the</span>
+<span class="source-line-no">566</span><span id="line-566">      // queue is full but server is not properly processing requests. Better to throw an aborted</span>
+<span class="source-line-no">567</span><span id="line-567">      // exception here so that the client can properly react.</span>
+<span class="source-line-no">568</span><span id="line-568">      if (rpcServer.server != null &amp;&amp; rpcServer.server.isAborted()) {</span>
+<span class="source-line-no">569</span><span id="line-569">        RegionServerAbortedException serverIsAborted = new RegionServerAbortedException(</span>
+<span class="source-line-no">570</span><span id="line-570">          "Server " + rpcServer.server.getServerName() + " aborting");</span>
+<span class="source-line-no">571</span><span id="line-571">        this.rpcServer.metrics.exception(serverIsAborted);</span>
+<span class="source-line-no">572</span><span id="line-572">        sendErrorResponseForCall(id, totalRequestSize, span, serverIsAborted.getMessage(),</span>
+<span class="source-line-no">573</span><span id="line-573">          serverIsAborted);</span>
+<span class="source-line-no">574</span><span id="line-574">        return;</span>
+<span class="source-line-no">575</span><span id="line-575">      }</span>
+<span class="source-line-no">576</span><span id="line-576"></span>
+<span class="source-line-no">577</span><span id="line-577">      if (RpcServer.LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">578</span><span id="line-578">        RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header)</span>
+<span class="source-line-no">579</span><span id="line-579">          + " totalRequestSize: " + totalRequestSize + " bytes");</span>
+<span class="source-line-no">580</span><span id="line-580">      }</span>
+<span class="source-line-no">581</span><span id="line-581">      // Enforcing the call queue size, this triggers a retry in the client</span>
+<span class="source-line-no">582</span><span id="line-582">      // This is a bit late to be doing this check - we have already read in the</span>
+<span class="source-line-no">583</span><span id="line-583">      // total request.</span>
+<span class="source-line-no">584</span><span id="line-584">      if (</span>
+<span class="source-line-no">585</span><span id="line-585">        (totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum())</span>
+<span class="source-line-no">586</span><span id="line-586">            &gt; this.rpcServer.maxQueueSizeInBytes</span>
+<span class="source-line-no">587</span><span id="line-587">      ) {</span>
+<span class="source-line-no">588</span><span id="line-588">        this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">589</span><span id="line-589">        sendErrorResponseForCall(id, totalRequestSize, span,</span>
+<span class="source-line-no">590</span><span id="line-590">          "Call queue is full on " + this.rpcServer.server.getServerName()</span>
+<span class="source-line-no">591</span><span id="line-591">            + ", is hbase.ipc.server.max.callqueue.size too small?",</span>
+<span class="source-line-no">592</span><span id="line-592">          RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">593</span><span id="line-593">        return;</span>
+<span class="source-line-no">594</span><span id="line-594">      }</span>
+<span class="source-line-no">595</span><span id="line-595">      MethodDescriptor md = null;</span>
+<span class="source-line-no">596</span><span id="line-596">      Message param = null;</span>
+<span class="source-line-no">597</span><span id="line-597">      ExtendedCellScanner cellScanner = null;</span>
+<span class="source-line-no">598</span><span id="line-598">      try {</span>
+<span class="source-line-no">599</span><span id="line-599">        if (header.hasRequestParam() &amp;&amp; header.getRequestParam()) {</span>
+<span class="source-line-no">600</span><span id="line-600">          md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());</span>
+<span class="source-line-no">601</span><span id="line-601">          if (md == null) {</span>
+<span class="source-line-no">602</span><span id="line-602">            throw new UnsupportedOperationException(header.getMethodName());</span>
+<span class="source-line-no">603</span><span id="line-603">          }</span>
+<span class="source-line-no">604</span><span id="line-604">          builder = this.service.getRequestPrototype(md).newBuilderForType();</span>
+<span class="source-line-no">605</span><span id="line-605">          cis.resetSizeCounter();</span>
+<span class="source-line-no">606</span><span id="line-606">          int paramSize = cis.readRawVarint32();</span>
+<span class="source-line-no">607</span><span id="line-607">          offset += cis.getTotalBytesRead();</span>
+<span class="source-line-no">608</span><span id="line-608">          if (builder != null) {</span>
+<span class="source-line-no">609</span><span id="line-609">            ProtobufUtil.mergeFrom(builder, cis, paramSize);</span>
+<span class="source-line-no">610</span><span id="line-610">            param = builder.build();</span>
+<span class="source-line-no">611</span><span id="line-611">          }</span>
+<span class="source-line-no">612</span><span id="line-612">          offset += paramSize;</span>
+<span class="source-line-no">613</span><span id="line-613">        } else {</span>
+<span class="source-line-no">614</span><span id="line-614">          // currently header must have request param, so we directly throw</span>
+<span class="source-line-no">615</span><span id="line-615">          // exception here</span>
+<span class="source-line-no">616</span><span id="line-616">          String msg = "Invalid request header: " + TextFormat.shortDebugString(header)</span>
+<span class="source-line-no">617</span><span id="line-617">            + ", should have param set in it";</span>
+<span class="source-line-no">618</span><span id="line-618">          RpcServer.LOG.warn(msg);</span>
+<span class="source-line-no">619</span><span id="line-619">          throw new DoNotRetryIOException(msg);</span>
+<span class="source-line-no">620</span><span id="line-620">        }</span>
+<span class="source-line-no">621</span><span id="line-621">        if (header.hasCellBlockMeta()) {</span>
+<span class="source-line-no">622</span><span id="line-622">          buf.position(offset);</span>
+<span class="source-line-no">623</span><span id="line-623">          ByteBuff dup = buf.duplicate();</span>
+<span class="source-line-no">624</span><span id="line-624">          dup.limit(offset + header.getCellBlockMeta().getLength());</span>
+<span class="source-line-no">625</span><span id="line-625">          cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec,</span>
+<span class="source-line-no">626</span><span id="line-626">            this.compressionCodec, dup);</span>
+<span class="source-line-no">627</span><span id="line-627">        }</span>
+<span class="source-line-no">628</span><span id="line-628">      } catch (Throwable thrown) {</span>
+<span class="source-line-no">629</span><span id="line-629">        InetSocketAddress address = this.rpcServer.getListenerAddress();</span>
+<span class="source-line-no">630</span><span id="line-630">        String msg = (address != null ? address : "(channel closed)")</span>
+<span class="source-line-no">631</span><span id="line-631">          + " is unable to read call parameter from client " + getHostAddress();</span>
+<span class="source-line-no">632</span><span id="line-632">        RpcServer.LOG.warn(msg, thrown);</span>
+<span class="source-line-no">633</span><span id="line-633"></span>
+<span class="source-line-no">634</span><span id="line-634">        this.rpcServer.metrics.exception(thrown);</span>
+<span class="source-line-no">635</span><span id="line-635"></span>
+<span class="source-line-no">636</span><span id="line-636">        final Throwable responseThrowable;</span>
+<span class="source-line-no">637</span><span id="line-637">        if (thrown instanceof LinkageError) {</span>
+<span class="source-line-no">638</span><span id="line-638">          // probably the hbase hadoop version does not match the running hadoop version</span>
+<span class="source-line-no">639</span><span id="line-639">          responseThrowable = new DoNotRetryIOException(thrown);</span>
+<span class="source-line-no">640</span><span id="line-640">        } else if (thrown instanceof UnsupportedOperationException) {</span>
+<span class="source-line-no">641</span><span id="line-641">          // If the method is not present on the server, do not retry.</span>
+<span class="source-line-no">642</span><span id="line-642">          responseThrowable = new DoNotRetryIOException(thrown);</span>
+<span class="source-line-no">643</span><span id="line-643">        } else {</span>
+<span class="source-line-no">644</span><span id="line-644">          responseThrowable = thrown;</span>
+<span class="source-line-no">645</span><span id="line-645">        }</span>
+<span class="source-line-no">646</span><span id="line-646"></span>
+<span class="source-line-no">647</span><span id="line-647">        sendErrorResponseForCall(id, totalRequestSize, span,</span>
+<span class="source-line-no">648</span><span id="line-648">          msg + "; " + responseThrowable.getMessage(), responseThrowable);</span>
+<span class="source-line-no">649</span><span id="line-649">        return;</span>
+<span class="source-line-no">650</span><span id="line-650">      }</span>
+<span class="source-line-no">651</span><span id="line-651"></span>
+<span class="source-line-no">652</span><span id="line-652">      int timeout = 0;</span>
+<span class="source-line-no">653</span><span id="line-653">      if (header.hasTimeout() &amp;&amp; header.getTimeout() &gt; 0) {</span>
+<span class="source-line-no">654</span><span id="line-654">        timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());</span>
+<span class="source-line-no">655</span><span id="line-655">      }</span>
+<span class="source-line-no">656</span><span id="line-656">      ServerCall&lt;?&gt; call = createCall(id, this.service, md, header, param, cellScanner,</span>
+<span class="source-line-no">657</span><span id="line-657">        totalRequestSize, this.addr, timeout, this.callCleanup);</span>
+<span class="source-line-no">658</span><span id="line-658"></span>
+<span class="source-line-no">659</span><span id="line-659">      if (this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {</span>
+<span class="source-line-no">660</span><span id="line-660">        // unset span do that it's not closed in the finally block</span>
+<span class="source-line-no">661</span><span id="line-661">        span = null;</span>
+<span class="source-line-no">662</span><span id="line-662">      } else {</span>
+<span class="source-line-no">663</span><span id="line-663">        this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());</span>
+<span class="source-line-no">664</span><span id="line-664">        this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">665</span><span id="line-665">        call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION,</span>
+<span class="source-line-no">666</span><span id="line-666">          "Call queue is full on " + this.rpcServer.server.getServerName()</span>
+<span class="source-line-no">667</span><span id="line-667">            + ", too many items queued ?");</span>
+<span class="source-line-no">668</span><span id="line-668">        TraceUtil.setError(span, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">669</span><span id="line-669">        call.sendResponseIfReady();</span>
 <span class="source-line-no">670</span><span id="line-670">      }</span>
-<span class="source-line-no">671</span><span id="line-671">    }</span>
-<span class="source-line-no">672</span><span id="line-672">  }</span>
-<span class="source-line-no">673</span><span id="line-673"></span>
-<span class="source-line-no">674</span><span id="line-674">  private void sendErrorResponseForCall(int id, long totalRequestSize, Span span, String msg,</span>
-<span class="source-line-no">675</span><span id="line-675">    Throwable responseThrowable) throws IOException {</span>
-<span class="source-line-no">676</span><span id="line-676">    ServerCall&lt;?&gt; failedcall = createCall(id, this.service, null, null, null, null,</span>
-<span class="source-line-no">677</span><span id="line-677">      totalRequestSize, null, 0, this.callCleanup);</span>
-<span class="source-line-no">678</span><span id="line-678">    failedcall.setResponse(null, null, responseThrowable, msg);</span>
-<span class="source-line-no">679</span><span id="line-679">    TraceUtil.setError(span, responseThrowable);</span>
-<span class="source-line-no">680</span><span id="line-680">    failedcall.sendResponseIfReady();</span>
-<span class="source-line-no">681</span><span id="line-681">  }</span>
-<span class="source-line-no">682</span><span id="line-682"></span>
-<span class="source-line-no">683</span><span id="line-683">  protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException {</span>
-<span class="source-line-no">684</span><span id="line-684">    ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1);</span>
-<span class="source-line-no">685</span><span id="line-685">    ServerCall.setExceptionResponse(e, msg, headerBuilder);</span>
-<span class="source-line-no">686</span><span id="line-686">    ByteBuffer headerBuf =</span>
-<span class="source-line-no">687</span><span id="line-687">      ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null);</span>
-<span class="source-line-no">688</span><span id="line-688">    BufferChain buf = new BufferChain(headerBuf);</span>
-<span class="source-line-no">689</span><span id="line-689">    return () -&gt; buf;</span>
-<span class="source-line-no">690</span><span id="line-690">  }</span>
-<span class="source-line-no">691</span><span id="line-691"></span>
-<span class="source-line-no">692</span><span id="line-692">  private void doBadPreambleHandling(String msg) throws IOException {</span>
-<span class="source-line-no">693</span><span id="line-693">    doBadPreambleHandling(msg, new FatalConnectionException(msg));</span>
+<span class="source-line-no">671</span><span id="line-671">    } finally {</span>
+<span class="source-line-no">672</span><span id="line-672">      if (span != null) {</span>
+<span class="source-line-no">673</span><span id="line-673">        span.end();</span>
+<span class="source-line-no">674</span><span id="line-674">      }</span>
+<span class="source-line-no">675</span><span id="line-675">    }</span>
+<span class="source-line-no">676</span><span id="line-676">  }</span>
+<span class="source-line-no">677</span><span id="line-677"></span>
+<span class="source-line-no">678</span><span id="line-678">  private void sendErrorResponseForCall(int id, long totalRequestSize, Span span, String msg,</span>
+<span class="source-line-no">679</span><span id="line-679">    Throwable responseThrowable) throws IOException {</span>
+<span class="source-line-no">680</span><span id="line-680">    ServerCall&lt;?&gt; failedcall = createCall(id, this.service, null, null, null, null,</span>
+<span class="source-line-no">681</span><span id="line-681">      totalRequestSize, null, 0, this.callCleanup);</span>
+<span class="source-line-no">682</span><span id="line-682">    failedcall.setResponse(null, null, responseThrowable, msg);</span>
+<span class="source-line-no">683</span><span id="line-683">    TraceUtil.setError(span, responseThrowable);</span>
+<span class="source-line-no">684</span><span id="line-684">    failedcall.sendResponseIfReady();</span>
+<span class="source-line-no">685</span><span id="line-685">  }</span>
+<span class="source-line-no">686</span><span id="line-686"></span>
+<span class="source-line-no">687</span><span id="line-687">  protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException {</span>
+<span class="source-line-no">688</span><span id="line-688">    ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1);</span>
+<span class="source-line-no">689</span><span id="line-689">    ServerCall.setExceptionResponse(e, msg, headerBuilder);</span>
+<span class="source-line-no">690</span><span id="line-690">    ByteBuffer headerBuf =</span>
+<span class="source-line-no">691</span><span id="line-691">      ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null);</span>
+<span class="source-line-no">692</span><span id="line-692">    BufferChain buf = new BufferChain(headerBuf);</span>
+<span class="source-line-no">693</span><span id="line-693">    return () -&gt; buf;</span>
 <span class="source-line-no">694</span><span id="line-694">  }</span>
 <span class="source-line-no">695</span><span id="line-695"></span>
-<span class="source-line-no">696</span><span id="line-696">  private void doBadPreambleHandling(String msg, Exception e) throws IOException {</span>
-<span class="source-line-no">697</span><span id="line-697">    RpcServer.LOG.warn(msg, e);</span>
-<span class="source-line-no">698</span><span id="line-698">    doRespond(getErrorResponse(msg, e));</span>
-<span class="source-line-no">699</span><span id="line-699">  }</span>
-<span class="source-line-no">700</span><span id="line-700"></span>
-<span class="source-line-no">701</span><span id="line-701">  private void doPreambleResponse(Message resp) throws IOException {</span>
-<span class="source-line-no">702</span><span id="line-702">    ResponseHeader header = ResponseHeader.newBuilder().setCallId(-1).build();</span>
-<span class="source-line-no">703</span><span id="line-703">    ByteBuffer buf = ServerCall.createHeaderAndMessageBytes(resp, header, 0, null);</span>
-<span class="source-line-no">704</span><span id="line-704">    BufferChain bufChain = new BufferChain(buf);</span>
-<span class="source-line-no">705</span><span id="line-705">    doRespond(() -&gt; bufChain);</span>
-<span class="source-line-no">706</span><span id="line-706">  }</span>
-<span class="source-line-no">707</span><span id="line-707"></span>
-<span class="source-line-no">708</span><span id="line-708">  private boolean doConnectionRegistryResponse() throws IOException {</span>
-<span class="source-line-no">709</span><span id="line-709">    if (!(rpcServer.server instanceof ConnectionRegistryEndpoint)) {</span>
-<span class="source-line-no">710</span><span id="line-710">      // should be in tests or some scenarios where we should not reach here</span>
-<span class="source-line-no">711</span><span id="line-711">      return false;</span>
-<span class="source-line-no">712</span><span id="line-712">    }</span>
-<span class="source-line-no">713</span><span id="line-713">    // on backup masters, this request may be blocked since we need to fetch it from filesystem,</span>
-<span class="source-line-no">714</span><span id="line-714">    // but since it is just backup master, it is not a critical problem</span>
-<span class="source-line-no">715</span><span id="line-715">    String clusterId = ((ConnectionRegistryEndpoint) rpcServer.server).getClusterId();</span>
-<span class="source-line-no">716</span><span id="line-716">    RpcServer.LOG.debug("Response connection registry, clusterId = '{}'", clusterId);</span>
-<span class="source-line-no">717</span><span id="line-717">    if (clusterId == null) {</span>
-<span class="source-line-no">718</span><span id="line-718">      // should be in tests or some scenarios where we should not reach here</span>
-<span class="source-line-no">719</span><span id="line-719">      return false;</span>
-<span class="source-line-no">720</span><span id="line-720">    }</span>
-<span class="source-line-no">721</span><span id="line-721">    GetConnectionRegistryResponse resp =</span>
-<span class="source-line-no">722</span><span id="line-722">      GetConnectionRegistryResponse.newBuilder().setClusterId(clusterId).build();</span>
-<span class="source-line-no">723</span><span id="line-723">    doPreambleResponse(resp);</span>
-<span class="source-line-no">724</span><span id="line-724">    return true;</span>
-<span class="source-line-no">725</span><span id="line-725">  }</span>
-<span class="source-line-no">726</span><span id="line-726"></span>
-<span class="source-line-no">727</span><span id="line-727">  private void doSecurityPreambleResponse() throws IOException {</span>
-<span class="source-line-no">728</span><span id="line-728">    if (rpcServer.isSecurityEnabled) {</span>
-<span class="source-line-no">729</span><span id="line-729">      SecurityPreamableResponse resp = SecurityPreamableResponse.newBuilder()</span>
-<span class="source-line-no">730</span><span id="line-730">        .setServerPrincipal(rpcServer.serverPrincipal).build();</span>
-<span class="source-line-no">731</span><span id="line-731">      doPreambleResponse(resp);</span>
-<span class="source-line-no">732</span><span id="line-732">    } else {</span>
-<span class="source-line-no">733</span><span id="line-733">      // security is not enabled, do not need a principal when connecting, throw a special exception</span>
-<span class="source-line-no">734</span><span id="line-734">      // to let client know it should just use simple authentication</span>
-<span class="source-line-no">735</span><span id="line-735">      doRespond(getErrorResponse("security is not enabled", new SecurityNotEnabledException()));</span>
-<span class="source-line-no">736</span><span id="line-736">    }</span>
-<span class="source-line-no">737</span><span id="line-737">  }</span>
-<span class="source-line-no">738</span><span id="line-738"></span>
-<span class="source-line-no">739</span><span id="line-739">  protected final void callCleanupIfNeeded() {</span>
-<span class="source-line-no">740</span><span id="line-740">    if (callCleanup != null) {</span>
-<span class="source-line-no">741</span><span id="line-741">      callCleanup.run();</span>
-<span class="source-line-no">742</span><span id="line-742">      callCleanup = null;</span>
-<span class="source-line-no">743</span><span id="line-743">    }</span>
-<span class="source-line-no">744</span><span id="line-744">  }</span>
-<span class="source-line-no">745</span><span id="line-745"></span>
-<span class="source-line-no">746</span><span id="line-746">  protected enum PreambleResponse {</span>
-<span class="source-line-no">747</span><span id="line-747">    SUCCEED, // successfully processed the rpc preamble header</span>
-<span class="source-line-no">748</span><span id="line-748">    CONTINUE, // the preamble header is for other purpose, wait for the rpc preamble header</span>
-<span class="source-line-no">749</span><span id="line-749">    CLOSE // close the rpc connection</span>
-<span class="source-line-no">750</span><span id="line-750">  }</span>
-<span class="source-line-no">751</span><span id="line-751"></span>
-<span class="source-line-no">752</span><span id="line-752">  protected final PreambleResponse processPreamble(ByteBuffer preambleBuffer) throws IOException {</span>
-<span class="source-line-no">753</span><span id="line-753">    assert preambleBuffer.remaining() == 6;</span>
-<span class="source-line-no">754</span><span id="line-754">    if (</span>
-<span class="source-line-no">755</span><span id="line-755">      ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
-<span class="source-line-no">756</span><span id="line-756">        RpcClient.REGISTRY_PREAMBLE_HEADER, 0, 6) &amp;&amp; doConnectionRegistryResponse()</span>
-<span class="source-line-no">757</span><span id="line-757">    ) {</span>
-<span class="source-line-no">758</span><span id="line-758">      return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">759</span><span id="line-759">    }</span>
-<span class="source-line-no">760</span><span id="line-760">    if (</span>
-<span class="source-line-no">761</span><span id="line-761">      ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
-<span class="source-line-no">762</span><span id="line-762">        RpcClient.SECURITY_PREAMBLE_HEADER, 0, 6)</span>
-<span class="source-line-no">763</span><span id="line-763">    ) {</span>
-<span class="source-line-no">764</span><span id="line-764">      doSecurityPreambleResponse();</span>
-<span class="source-line-no">765</span><span id="line-765">      return PreambleResponse.CONTINUE;</span>
-<span class="source-line-no">766</span><span id="line-766">    }</span>
-<span class="source-line-no">767</span><span id="line-767">    if (!ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 4, RPC_HEADER, 0, 4)) {</span>
-<span class="source-line-no">768</span><span id="line-768">      doBadPreambleHandling(</span>
-<span class="source-line-no">769</span><span id="line-769">        "Expected HEADER=" + Bytes.toStringBinary(RPC_HEADER) + " but received HEADER="</span>
-<span class="source-line-no">770</span><span id="line-770">          + Bytes.toStringBinary(</span>
-<span class="source-line-no">771</span><span id="line-771">            ByteBufferUtils.toBytes(preambleBuffer, preambleBuffer.position(), RPC_HEADER.length),</span>
-<span class="source-line-no">772</span><span id="line-772">            0, RPC_HEADER.length)</span>
-<span class="source-line-no">773</span><span id="line-773">          + " from " + toString());</span>
-<span class="source-line-no">774</span><span id="line-774">      return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">775</span><span id="line-775">    }</span>
-<span class="source-line-no">776</span><span id="line-776">    int version = preambleBuffer.get(preambleBuffer.position() + 4) &amp; 0xFF;</span>
-<span class="source-line-no">777</span><span id="line-777">    byte authByte = preambleBuffer.get(preambleBuffer.position() + 5);</span>
-<span class="source-line-no">778</span><span id="line-778">    if (version != RpcServer.CURRENT_VERSION) {</span>
-<span class="source-line-no">779</span><span id="line-779">      String msg = getFatalConnectionString(version, authByte);</span>
-<span class="source-line-no">780</span><span id="line-780">      doBadPreambleHandling(msg, new WrongVersionException(msg));</span>
-<span class="source-line-no">781</span><span id="line-781">      return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">782</span><span id="line-782">    }</span>
-<span class="source-line-no">783</span><span id="line-783"></span>
-<span class="source-line-no">784</span><span id="line-784">    this.provider = rpcServer.saslProviders.selectProvider(authByte);</span>
-<span class="source-line-no">785</span><span id="line-785">    if (this.provider == null) {</span>
-<span class="source-line-no">786</span><span id="line-786">      String msg = getFatalConnectionString(version, authByte);</span>
-<span class="source-line-no">787</span><span id="line-787">      doBadPreambleHandling(msg, new BadAuthException(msg));</span>
-<span class="source-line-no">788</span><span id="line-788">      return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">789</span><span id="line-789">    }</span>
-<span class="source-line-no">790</span><span id="line-790">    // TODO this is a wart while simple auth'n doesn't go through sasl.</span>
-<span class="source-line-no">791</span><span id="line-791">    if (this.rpcServer.isSecurityEnabled &amp;&amp; isSimpleAuthentication()) {</span>
-<span class="source-line-no">792</span><span id="line-792">      if (this.rpcServer.allowFallbackToSimpleAuth) {</span>
-<span class="source-line-no">793</span><span id="line-793">        this.rpcServer.metrics.authenticationFallback();</span>
-<span class="source-line-no">794</span><span id="line-794">        authenticatedWithFallback = true;</span>
-<span class="source-line-no">795</span><span id="line-795">      } else {</span>
-<span class="source-line-no">796</span><span id="line-796">        AccessDeniedException ae = new AccessDeniedException("Authentication is required");</span>
-<span class="source-line-no">797</span><span id="line-797">        doRespond(getErrorResponse(ae.getMessage(), ae));</span>
-<span class="source-line-no">798</span><span id="line-798">        return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">799</span><span id="line-799">      }</span>
-<span class="source-line-no">800</span><span id="line-800">    }</span>
-<span class="source-line-no">801</span><span id="line-801">    if (!this.rpcServer.isSecurityEnabled &amp;&amp; !isSimpleAuthentication()) {</span>
-<span class="source-line-no">802</span><span id="line-802">      doRawSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslUtil.SWITCH_TO_SIMPLE_AUTH), null,</span>
-<span class="source-line-no">803</span><span id="line-803">        null);</span>
-<span class="source-line-no">804</span><span id="line-804">      provider = rpcServer.saslProviders.getSimpleProvider();</span>
-<span class="source-line-no">805</span><span id="line-805">      // client has already sent the initial Sasl message and we</span>
-<span class="source-line-no">806</span><span id="line-806">      // should ignore it. Both client and server should fall back</span>
-<span class="source-line-no">807</span><span id="line-807">      // to simple auth from now on.</span>
-<span class="source-line-no">808</span><span id="line-808">      skipInitialSaslHandshake = true;</span>
-<span class="source-line-no">809</span><span id="line-809">    }</span>
-<span class="source-line-no">810</span><span id="line-810">    useSasl = !(provider instanceof SimpleSaslServerAuthenticationProvider);</span>
-<span class="source-line-no">811</span><span id="line-811">    return PreambleResponse.SUCCEED;</span>
-<span class="source-line-no">812</span><span id="line-812">  }</span>
-<span class="source-line-no">813</span><span id="line-813"></span>
-<span class="source-line-no">814</span><span id="line-814">  boolean isSimpleAuthentication() {</span>
-<span class="source-line-no">815</span><span id="line-815">    return Objects.requireNonNull(provider) instanceof SimpleSaslServerAuthenticationProvider;</span>
+<span class="source-line-no">696</span><span id="line-696">  private void doBadPreambleHandling(String msg) throws IOException {</span>
+<span class="source-line-no">697</span><span id="line-697">    doBadPreambleHandling(msg, new FatalConnectionException(msg));</span>
+<span class="source-line-no">698</span><span id="line-698">  }</span>
+<span class="source-line-no">699</span><span id="line-699"></span>
+<span class="source-line-no">700</span><span id="line-700">  private void doBadPreambleHandling(String msg, Exception e) throws IOException {</span>
+<span class="source-line-no">701</span><span id="line-701">    RpcServer.LOG.warn(msg, e);</span>
+<span class="source-line-no">702</span><span id="line-702">    doRespond(getErrorResponse(msg, e));</span>
+<span class="source-line-no">703</span><span id="line-703">  }</span>
+<span class="source-line-no">704</span><span id="line-704"></span>
+<span class="source-line-no">705</span><span id="line-705">  private void doPreambleResponse(Message resp) throws IOException {</span>
+<span class="source-line-no">706</span><span id="line-706">    ResponseHeader header = ResponseHeader.newBuilder().setCallId(-1).build();</span>
+<span class="source-line-no">707</span><span id="line-707">    ByteBuffer buf = ServerCall.createHeaderAndMessageBytes(resp, header, 0, null);</span>
+<span class="source-line-no">708</span><span id="line-708">    BufferChain bufChain = new BufferChain(buf);</span>
+<span class="source-line-no">709</span><span id="line-709">    doRespond(() -&gt; bufChain);</span>
+<span class="source-line-no">710</span><span id="line-710">  }</span>
+<span class="source-line-no">711</span><span id="line-711"></span>
+<span class="source-line-no">712</span><span id="line-712">  private boolean doConnectionRegistryResponse() throws IOException {</span>
+<span class="source-line-no">713</span><span id="line-713">    if (!(rpcServer.server instanceof ConnectionRegistryEndpoint)) {</span>
+<span class="source-line-no">714</span><span id="line-714">      // should be in tests or some scenarios where we should not reach here</span>
+<span class="source-line-no">715</span><span id="line-715">      return false;</span>
+<span class="source-line-no">716</span><span id="line-716">    }</span>
+<span class="source-line-no">717</span><span id="line-717">    // on backup masters, this request may be blocked since we need to fetch it from filesystem,</span>
+<span class="source-line-no">718</span><span id="line-718">    // but since it is just backup master, it is not a critical problem</span>
+<span class="source-line-no">719</span><span id="line-719">    String clusterId = ((ConnectionRegistryEndpoint) rpcServer.server).getClusterId();</span>
+<span class="source-line-no">720</span><span id="line-720">    RpcServer.LOG.debug("Response connection registry, clusterId = '{}'", clusterId);</span>
+<span class="source-line-no">721</span><span id="line-721">    if (clusterId == null) {</span>
+<span class="source-line-no">722</span><span id="line-722">      // should be in tests or some scenarios where we should not reach here</span>
+<span class="source-line-no">723</span><span id="line-723">      return false;</span>
+<span class="source-line-no">724</span><span id="line-724">    }</span>
+<span class="source-line-no">725</span><span id="line-725">    GetConnectionRegistryResponse resp =</span>
+<span class="source-line-no">726</span><span id="line-726">      GetConnectionRegistryResponse.newBuilder().setClusterId(clusterId).build();</span>
+<span class="source-line-no">727</span><span id="line-727">    doPreambleResponse(resp);</span>
+<span class="source-line-no">728</span><span id="line-728">    return true;</span>
+<span class="source-line-no">729</span><span id="line-729">  }</span>
+<span class="source-line-no">730</span><span id="line-730"></span>
+<span class="source-line-no">731</span><span id="line-731">  private void doSecurityPreambleResponse() throws IOException {</span>
+<span class="source-line-no">732</span><span id="line-732">    if (rpcServer.isSecurityEnabled) {</span>
+<span class="source-line-no">733</span><span id="line-733">      SecurityPreamableResponse resp = SecurityPreamableResponse.newBuilder()</span>
+<span class="source-line-no">734</span><span id="line-734">        .setServerPrincipal(rpcServer.serverPrincipal).build();</span>
+<span class="source-line-no">735</span><span id="line-735">      doPreambleResponse(resp);</span>
+<span class="source-line-no">736</span><span id="line-736">    } else {</span>
+<span class="source-line-no">737</span><span id="line-737">      // security is not enabled, do not need a principal when connecting, throw a special exception</span>
+<span class="source-line-no">738</span><span id="line-738">      // to let client know it should just use simple authentication</span>
+<span class="source-line-no">739</span><span id="line-739">      doRespond(getErrorResponse("security is not enabled", new SecurityNotEnabledException()));</span>
+<span class="source-line-no">740</span><span id="line-740">    }</span>
+<span class="source-line-no">741</span><span id="line-741">  }</span>
+<span class="source-line-no">742</span><span id="line-742"></span>
+<span class="source-line-no">743</span><span id="line-743">  protected final void callCleanupIfNeeded() {</span>
+<span class="source-line-no">744</span><span id="line-744">    if (callCleanup != null) {</span>
+<span class="source-line-no">745</span><span id="line-745">      callCleanup.run();</span>
+<span class="source-line-no">746</span><span id="line-746">      callCleanup = null;</span>
+<span class="source-line-no">747</span><span id="line-747">    }</span>
+<span class="source-line-no">748</span><span id="line-748">  }</span>
+<span class="source-line-no">749</span><span id="line-749"></span>
+<span class="source-line-no">750</span><span id="line-750">  protected enum PreambleResponse {</span>
+<span class="source-line-no">751</span><span id="line-751">    SUCCEED, // successfully processed the rpc preamble header</span>
+<span class="source-line-no">752</span><span id="line-752">    CONTINUE, // the preamble header is for other purpose, wait for the rpc preamble header</span>
+<span class="source-line-no">753</span><span id="line-753">    CLOSE // close the rpc connection</span>
+<span class="source-line-no">754</span><span id="line-754">  }</span>
+<span class="source-line-no">755</span><span id="line-755"></span>
+<span class="source-line-no">756</span><span id="line-756">  protected final PreambleResponse processPreamble(ByteBuffer preambleBuffer) throws IOException {</span>
+<span class="source-line-no">757</span><span id="line-757">    assert preambleBuffer.remaining() == 6;</span>
+<span class="source-line-no">758</span><span id="line-758">    if (</span>
+<span class="source-line-no">759</span><span id="line-759">      ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
+<span class="source-line-no">760</span><span id="line-760">        RpcClient.REGISTRY_PREAMBLE_HEADER, 0, 6) &amp;&amp; doConnectionRegistryResponse()</span>
+<span class="source-line-no">761</span><span id="line-761">    ) {</span>
+<span class="source-line-no">762</span><span id="line-762">      return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">763</span><span id="line-763">    }</span>
+<span class="source-line-no">764</span><span id="line-764">    if (</span>
+<span class="source-line-no">765</span><span id="line-765">      ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
+<span class="source-line-no">766</span><span id="line-766">        RpcClient.SECURITY_PREAMBLE_HEADER, 0, 6)</span>
+<span class="source-line-no">767</span><span id="line-767">    ) {</span>
+<span class="source-line-no">768</span><span id="line-768">      doSecurityPreambleResponse();</span>
+<span class="source-line-no">769</span><span id="line-769">      return PreambleResponse.CONTINUE;</span>
+<span class="source-line-no">770</span><span id="line-770">    }</span>
+<span class="source-line-no">771</span><span id="line-771">    if (!ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 4, RPC_HEADER, 0, 4)) {</span>
+<span class="source-line-no">772</span><span id="line-772">      doBadPreambleHandling(</span>
+<span class="source-line-no">773</span><span id="line-773">        "Expected HEADER=" + Bytes.toStringBinary(RPC_HEADER) + " but received HEADER="</span>
+<span class="source-line-no">774</span><span id="line-774">          + Bytes.toStringBinary(</span>
+<span class="source-line-no">775</span><span id="line-775">            ByteBufferUtils.toBytes(preambleBuffer, preambleBuffer.position(), RPC_HEADER.length),</span>
+<span class="source-line-no">776</span><span id="line-776">            0, RPC_HEADER.length)</span>
+<span class="source-line-no">777</span><span id="line-777">          + " from " + toString());</span>
+<span class="source-line-no">778</span><span id="line-778">      return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">779</span><span id="line-779">    }</span>
+<span class="source-line-no">780</span><span id="line-780">    int version = preambleBuffer.get(preambleBuffer.position() + 4) &amp; 0xFF;</span>
+<span class="source-line-no">781</span><span id="line-781">    byte authByte = preambleBuffer.get(preambleBuffer.position() + 5);</span>
+<span class="source-line-no">782</span><span id="line-782">    if (version != RpcServer.CURRENT_VERSION) {</span>
+<span class="source-line-no">783</span><span id="line-783">      String msg = getFatalConnectionString(version, authByte);</span>
+<span class="source-line-no">784</span><span id="line-784">      doBadPreambleHandling(msg, new WrongVersionException(msg));</span>
+<span class="source-line-no">785</span><span id="line-785">      return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">786</span><span id="line-786">    }</span>
+<span class="source-line-no">787</span><span id="line-787"></span>
+<span class="source-line-no">788</span><span id="line-788">    this.provider = rpcServer.saslProviders.selectProvider(authByte);</span>
+<span class="source-line-no">789</span><span id="line-789">    if (this.provider == null) {</span>
+<span class="source-line-no">790</span><span id="line-790">      String msg = getFatalConnectionString(version, authByte);</span>
+<span class="source-line-no">791</span><span id="line-791">      doBadPreambleHandling(msg, new BadAuthException(msg));</span>
+<span class="source-line-no">792</span><span id="line-792">      return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">793</span><span id="line-793">    }</span>
+<span class="source-line-no">794</span><span id="line-794">    // TODO this is a wart while simple auth'n doesn't go through sasl.</span>
+<span class="source-line-no">795</span><span id="line-795">    if (this.rpcServer.isSecurityEnabled &amp;&amp; isSimpleAuthentication()) {</span>
+<span class="source-line-no">796</span><span id="line-796">      if (this.rpcServer.allowFallbackToSimpleAuth) {</span>
+<span class="source-line-no">797</span><span id="line-797">        this.rpcServer.metrics.authenticationFallback();</span>
+<span class="source-line-no">798</span><span id="line-798">        authenticatedWithFallback = true;</span>
+<span class="source-line-no">799</span><span id="line-799">      } else {</span>
+<span class="source-line-no">800</span><span id="line-800">        AccessDeniedException ae = new AccessDeniedException("Authentication is required");</span>
+<span class="source-line-no">801</span><span id="line-801">        doRespond(getErrorResponse(ae.getMessage(), ae));</span>
+<span class="source-line-no">802</span><span id="line-802">        return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">803</span><span id="line-803">      }</span>
+<span class="source-line-no">804</span><span id="line-804">    }</span>
+<span class="source-line-no">805</span><span id="line-805">    if (!this.rpcServer.isSecurityEnabled &amp;&amp; !isSimpleAuthentication()) {</span>
+<span class="source-line-no">806</span><span id="line-806">      doRawSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslUtil.SWITCH_TO_SIMPLE_AUTH), null,</span>
+<span class="source-line-no">807</span><span id="line-807">        null);</span>
+<span class="source-line-no">808</span><span id="line-808">      provider = rpcServer.saslProviders.getSimpleProvider();</span>
+<span class="source-line-no">809</span><span id="line-809">      // client has already sent the initial Sasl message and we</span>
+<span class="source-line-no">810</span><span id="line-810">      // should ignore it. Both client and server should fall back</span>
+<span class="source-line-no">811</span><span id="line-811">      // to simple auth from now on.</span>
+<span class="source-line-no">812</span><span id="line-812">      skipInitialSaslHandshake = true;</span>
+<span class="source-line-no">813</span><span id="line-813">    }</span>
+<span class="source-line-no">814</span><span id="line-814">    useSasl = !(provider instanceof SimpleSaslServerAuthenticationProvider);</span>
+<span class="source-line-no">815</span><span id="line-815">    return PreambleResponse.SUCCEED;</span>
 <span class="source-line-no">816</span><span id="line-816">  }</span>
 <span class="source-line-no">817</span><span id="line-817"></span>
-<span class="source-line-no">818</span><span id="line-818">  public abstract boolean isConnectionOpen();</span>
-<span class="source-line-no">819</span><span id="line-819"></span>
-<span class="source-line-no">820</span><span id="line-820">  public abstract ServerCall&lt;?&gt; createCall(int id, BlockingService service, MethodDescriptor md,</span>
-<span class="source-line-no">821</span><span id="line-821">    RequestHeader header, Message param, ExtendedCellScanner cellScanner, long size,</span>
-<span class="source-line-no">822</span><span id="line-822">    InetAddress remoteAddress, int timeout, CallCleanup reqCleanup);</span>
+<span class="source-line-no">818</span><span id="line-818">  boolean isSimpleAuthentication() {</span>
+<span class="source-line-no">819</span><span id="line-819">    return Objects.requireNonNull(provider) instanceof SimpleSaslServerAuthenticationProvider;</span>
+<span class="source-line-no">820</span><span id="line-820">  }</span>
+<span class="source-line-no">821</span><span id="line-821"></span>
+<span class="source-line-no">822</span><span id="line-822">  public abstract boolean isConnectionOpen();</span>
 <span class="source-line-no">823</span><span id="line-823"></span>
-<span class="source-line-no">824</span><span id="line-824">  private static class ByteBuffByteInput extends ByteInput {</span>
-<span class="source-line-no">825</span><span id="line-825"></span>
-<span class="source-line-no">826</span><span id="line-826">    private ByteBuff buf;</span>
-<span class="source-line-no">827</span><span id="line-827">    private int length;</span>
-<span class="source-line-no">828</span><span id="line-828"></span>
-<span class="source-line-no">829</span><span id="line-829">    ByteBuffByteInput(ByteBuff buf, int length) {</span>
-<span class="source-line-no">830</span><span id="line-830">      this.buf = buf;</span>
-<span class="source-line-no">831</span><span id="line-831">      this.length = length;</span>
-<span class="source-line-no">832</span><span id="line-832">    }</span>
-<span class="source-line-no">833</span><span id="line-833"></span>
-<span class="source-line-no">834</span><span id="line-834">    @Override</span>
-<span class="source-line-no">835</span><span id="line-835">    public byte read(int offset) {</span>
-<span class="source-line-no">836</span><span id="line-836">      return this.buf.get(offset);</span>
-<span class="source-line-no">837</span><span id="line-837">    }</span>
-<span class="source-line-no">838</span><span id="line-838"></span>
-<span class="source-line-no">839</span><span id="line-839">    @Override</span>
-<span class="source-line-no">840</span><span id="line-840">    public int read(int offset, byte[] out, int outOffset, int len) {</span>
-<span class="source-line-no">841</span><span id="line-841">      this.buf.get(offset, out, outOffset, len);</span>
-<span class="source-line-no">842</span><span id="line-842">      return len;</span>
-<span class="source-line-no">843</span><span id="line-843">    }</span>
-<span class="source-line-no">844</span><span id="line-844"></span>
-<span class="source-line-no">845</span><span id="line-845">    @Override</span>
-<span class="source-line-no">846</span><span id="line-846">    public int read(int offset, ByteBuffer out) {</span>
-<span class="source-line-no">847</span><span id="line-847">      int len = out.remaining();</span>
-<span class="source-line-no">848</span><span id="line-848">      this.buf.get(out, offset, len);</span>
-<span class="source-line-no">849</span><span id="line-849">      return len;</span>
-<span class="source-line-no">850</span><span id="line-850">    }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852">    @Override</span>
-<span class="source-line-no">853</span><span id="line-853">    public long readLong(int offset) {</span>
-<span class="source-line-no">854</span><span id="line-854">      return this.buf.getLong(offset);</span>
-<span class="source-line-no">855</span><span id="line-855">    }</span>
-<span class="source-line-no">856</span><span id="line-856"></span>
-<span class="source-line-no">857</span><span id="line-857">    @Override</span>
-<span class="source-line-no">858</span><span id="line-858">    public int size() {</span>
-<span class="source-line-no">859</span><span id="line-859">      return this.length;</span>
-<span class="source-line-no">860</span><span id="line-860">    }</span>
-<span class="source-line-no">861</span><span id="line-861"></span>
-<span class="source-line-no">862</span><span id="line-862">  }</span>
-<span class="source-line-no">863</span><span id="line-863">}</span>
+<span class="source-line-no">824</span><span id="line-824">  public abstract ServerCall&lt;?&gt; createCall(int id, BlockingService service, MethodDescriptor md,</span>
+<span class="source-line-no">825</span><span id="line-825">    RequestHeader header, Message param, ExtendedCellScanner cellScanner, long size,</span>
+<span class="source-line-no">826</span><span id="line-826">    InetAddress remoteAddress, int timeout, CallCleanup reqCleanup);</span>
+<span class="source-line-no">827</span><span id="line-827"></span>
+<span class="source-line-no">828</span><span id="line-828">  private static class ByteBuffByteInput extends ByteInput {</span>
+<span class="source-line-no">829</span><span id="line-829"></span>
+<span class="source-line-no">830</span><span id="line-830">    private ByteBuff buf;</span>
+<span class="source-line-no">831</span><span id="line-831">    private int length;</span>
+<span class="source-line-no">832</span><span id="line-832"></span>
+<span class="source-line-no">833</span><span id="line-833">    ByteBuffByteInput(ByteBuff buf, int length) {</span>
+<span class="source-line-no">834</span><span id="line-834">      this.buf = buf;</span>
+<span class="source-line-no">835</span><span id="line-835">      this.length = length;</span>
+<span class="source-line-no">836</span><span id="line-836">    }</span>
+<span class="source-line-no">837</span><span id="line-837"></span>
+<span class="source-line-no">838</span><span id="line-838">    @Override</span>
+<span class="source-line-no">839</span><span id="line-839">    public byte read(int offset) {</span>
+<span class="source-line-no">840</span><span id="line-840">      return this.buf.get(offset);</span>
+<span class="source-line-no">841</span><span id="line-841">    }</span>
+<span class="source-line-no">842</span><span id="line-842"></span>
+<span class="source-line-no">843</span><span id="line-843">    @Override</span>
+<span class="source-line-no">844</span><span id="line-844">    public int read(int offset, byte[] out, int outOffset, int len) {</span>
+<span class="source-line-no">845</span><span id="line-845">      this.buf.get(offset, out, outOffset, len);</span>
+<span class="source-line-no">846</span><span id="line-846">      return len;</span>
+<span class="source-line-no">847</span><span id="line-847">    }</span>
+<span class="source-line-no">848</span><span id="line-848"></span>
+<span class="source-line-no">849</span><span id="line-849">    @Override</span>
+<span class="source-line-no">850</span><span id="line-850">    public int read(int offset, ByteBuffer out) {</span>
+<span class="source-line-no">851</span><span id="line-851">      int len = out.remaining();</span>
+<span class="source-line-no">852</span><span id="line-852">      this.buf.get(out, offset, len);</span>
+<span class="source-line-no">853</span><span id="line-853">      return len;</span>
+<span class="source-line-no">854</span><span id="line-854">    }</span>
+<span class="source-line-no">855</span><span id="line-855"></span>
+<span class="source-line-no">856</span><span id="line-856">    @Override</span>
+<span class="source-line-no">857</span><span id="line-857">    public long readLong(int offset) {</span>
+<span class="source-line-no">858</span><span id="line-858">      return this.buf.getLong(offset);</span>
+<span class="source-line-no">859</span><span id="line-859">    }</span>
+<span class="source-line-no">860</span><span id="line-860"></span>
+<span class="source-line-no">861</span><span id="line-861">    @Override</span>
+<span class="source-line-no">862</span><span id="line-862">    public int size() {</span>
+<span class="source-line-no">863</span><span id="line-863">      return this.length;</span>
+<span class="source-line-no">864</span><span id="line-864">    }</span>
+<span class="source-line-no">865</span><span id="line-865"></span>
+<span class="source-line-no">866</span><span id="line-866">  }</span>
+<span class="source-line-no">867</span><span id="line-867">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/HRegionServer.html b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/HRegionServer.html
index d1f86cfea30..23bf408aba5 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/HRegionServer.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/HRegionServer.html
@@ -1685,2084 +1685,2088 @@
 <span class="source-line-no">1672</span><span id="line-1672">        .setHostName(clientMetrics.getHostName())</span>
 <span class="source-line-no">1673</span><span id="line-1673">        .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
 <span class="source-line-no">1674</span><span id="line-1674">        .setFilteredRequestsCount(clientMetrics.getFilteredReadRequests())</span>
-<span class="source-line-no">1675</span><span id="line-1675">        .setReadRequestsCount(clientMetrics.getReadRequestsCount()).build())</span>
-<span class="source-line-no">1676</span><span id="line-1676">      .forEach(userLoadBldr::addClientMetrics);</span>
-<span class="source-line-no">1677</span><span id="line-1677">    return userLoadBldr.build();</span>
-<span class="source-line-no">1678</span><span id="line-1678">  }</span>
-<span class="source-line-no">1679</span><span id="line-1679"></span>
-<span class="source-line-no">1680</span><span id="line-1680">  public RegionLoad createRegionLoad(final String encodedRegionName) throws IOException {</span>
-<span class="source-line-no">1681</span><span id="line-1681">    HRegion r = onlineRegions.get(encodedRegionName);</span>
-<span class="source-line-no">1682</span><span id="line-1682">    return r != null ? createRegionLoad(r, null, null) : null;</span>
-<span class="source-line-no">1683</span><span id="line-1683">  }</span>
-<span class="source-line-no">1684</span><span id="line-1684"></span>
-<span class="source-line-no">1685</span><span id="line-1685">  /**</span>
-<span class="source-line-no">1686</span><span id="line-1686">   * Inner class that runs on a long period checking if regions need compaction.</span>
-<span class="source-line-no">1687</span><span id="line-1687">   */</span>
-<span class="source-line-no">1688</span><span id="line-1688">  private static class CompactionChecker extends ScheduledChore {</span>
-<span class="source-line-no">1689</span><span id="line-1689">    private final HRegionServer instance;</span>
-<span class="source-line-no">1690</span><span id="line-1690">    private final int majorCompactPriority;</span>
-<span class="source-line-no">1691</span><span id="line-1691">    private final static int DEFAULT_PRIORITY = Integer.MAX_VALUE;</span>
-<span class="source-line-no">1692</span><span id="line-1692">    // Iteration is 1-based rather than 0-based so we don't check for compaction</span>
-<span class="source-line-no">1693</span><span id="line-1693">    // immediately upon region server startup</span>
-<span class="source-line-no">1694</span><span id="line-1694">    private long iteration = 1;</span>
-<span class="source-line-no">1695</span><span id="line-1695"></span>
-<span class="source-line-no">1696</span><span id="line-1696">    CompactionChecker(final HRegionServer h, final int sleepTime, final Stoppable stopper) {</span>
-<span class="source-line-no">1697</span><span id="line-1697">      super("CompactionChecker", stopper, sleepTime);</span>
-<span class="source-line-no">1698</span><span id="line-1698">      this.instance = h;</span>
-<span class="source-line-no">1699</span><span id="line-1699">      LOG.info(this.getName() + " runs every " + Duration.ofMillis(sleepTime));</span>
-<span class="source-line-no">1700</span><span id="line-1700"></span>
-<span class="source-line-no">1701</span><span id="line-1701">      /*</span>
-<span class="source-line-no">1702</span><span id="line-1702">       * MajorCompactPriority is configurable. If not set, the compaction will use default priority.</span>
-<span class="source-line-no">1703</span><span id="line-1703">       */</span>
-<span class="source-line-no">1704</span><span id="line-1704">      this.majorCompactPriority = this.instance.conf</span>
-<span class="source-line-no">1705</span><span id="line-1705">        .getInt("hbase.regionserver.compactionChecker.majorCompactPriority", DEFAULT_PRIORITY);</span>
-<span class="source-line-no">1706</span><span id="line-1706">    }</span>
-<span class="source-line-no">1707</span><span id="line-1707"></span>
-<span class="source-line-no">1708</span><span id="line-1708">    @Override</span>
-<span class="source-line-no">1709</span><span id="line-1709">    protected void chore() {</span>
-<span class="source-line-no">1710</span><span id="line-1710">      for (HRegion hr : this.instance.onlineRegions.values()) {</span>
-<span class="source-line-no">1711</span><span id="line-1711">        // If region is read only or compaction is disabled at table level, there's no need to</span>
-<span class="source-line-no">1712</span><span id="line-1712">        // iterate through region's stores</span>
-<span class="source-line-no">1713</span><span id="line-1713">        if (hr == null || hr.isReadOnly() || !hr.getTableDescriptor().isCompactionEnabled()) {</span>
-<span class="source-line-no">1714</span><span id="line-1714">          continue;</span>
-<span class="source-line-no">1715</span><span id="line-1715">        }</span>
-<span class="source-line-no">1716</span><span id="line-1716"></span>
-<span class="source-line-no">1717</span><span id="line-1717">        for (HStore s : hr.stores.values()) {</span>
-<span class="source-line-no">1718</span><span id="line-1718">          try {</span>
-<span class="source-line-no">1719</span><span id="line-1719">            long multiplier = s.getCompactionCheckMultiplier();</span>
-<span class="source-line-no">1720</span><span id="line-1720">            assert multiplier &gt; 0;</span>
-<span class="source-line-no">1721</span><span id="line-1721">            if (iteration % multiplier != 0) {</span>
-<span class="source-line-no">1722</span><span id="line-1722">              continue;</span>
-<span class="source-line-no">1723</span><span id="line-1723">            }</span>
-<span class="source-line-no">1724</span><span id="line-1724">            if (s.needsCompaction()) {</span>
-<span class="source-line-no">1725</span><span id="line-1725">              // Queue a compaction. Will recognize if major is needed.</span>
-<span class="source-line-no">1726</span><span id="line-1726">              this.instance.compactSplitThread.requestSystemCompaction(hr, s,</span>
-<span class="source-line-no">1727</span><span id="line-1727">                getName() + " requests compaction");</span>
-<span class="source-line-no">1728</span><span id="line-1728">            } else if (s.shouldPerformMajorCompaction()) {</span>
-<span class="source-line-no">1729</span><span id="line-1729">              s.triggerMajorCompaction();</span>
-<span class="source-line-no">1730</span><span id="line-1730">              if (</span>
-<span class="source-line-no">1731</span><span id="line-1731">                majorCompactPriority == DEFAULT_PRIORITY</span>
-<span class="source-line-no">1732</span><span id="line-1732">                  || majorCompactPriority &gt; hr.getCompactPriority()</span>
-<span class="source-line-no">1733</span><span id="line-1733">              ) {</span>
-<span class="source-line-no">1734</span><span id="line-1734">                this.instance.compactSplitThread.requestCompaction(hr, s,</span>
-<span class="source-line-no">1735</span><span id="line-1735">                  getName() + " requests major compaction; use default priority", Store.NO_PRIORITY,</span>
-<span class="source-line-no">1736</span><span id="line-1736">                  CompactionLifeCycleTracker.DUMMY, null);</span>
-<span class="source-line-no">1737</span><span id="line-1737">              } else {</span>
+<span class="source-line-no">1675</span><span id="line-1675">        .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
+<span class="source-line-no">1676</span><span id="line-1676">        .setHostAddress(clientMetrics.getHostAddress()).setUserName(clientMetrics.getUserName())</span>
+<span class="source-line-no">1677</span><span id="line-1677">        .setClientVersion(clientMetrics.getClientVersion())</span>
+<span class="source-line-no">1678</span><span id="line-1678">        .setServiceName(clientMetrics.getServiceName())</span>
+<span class="source-line-no">1679</span><span id="line-1679">        .setClientVersion(clientMetrics.getClientVersion()).build())</span>
+<span class="source-line-no">1680</span><span id="line-1680">      .forEach(userLoadBldr::addClientMetrics);</span>
+<span class="source-line-no">1681</span><span id="line-1681">    return userLoadBldr.build();</span>
+<span class="source-line-no">1682</span><span id="line-1682">  }</span>
+<span class="source-line-no">1683</span><span id="line-1683"></span>
+<span class="source-line-no">1684</span><span id="line-1684">  public RegionLoad createRegionLoad(final String encodedRegionName) throws IOException {</span>
+<span class="source-line-no">1685</span><span id="line-1685">    HRegion r = onlineRegions.get(encodedRegionName);</span>
+<span class="source-line-no">1686</span><span id="line-1686">    return r != null ? createRegionLoad(r, null, null) : null;</span>
+<span class="source-line-no">1687</span><span id="line-1687">  }</span>
+<span class="source-line-no">1688</span><span id="line-1688"></span>
+<span class="source-line-no">1689</span><span id="line-1689">  /**</span>
+<span class="source-line-no">1690</span><span id="line-1690">   * Inner class that runs on a long period checking if regions need compaction.</span>
+<span class="source-line-no">1691</span><span id="line-1691">   */</span>
+<span class="source-line-no">1692</span><span id="line-1692">  private static class CompactionChecker extends ScheduledChore {</span>
+<span class="source-line-no">1693</span><span id="line-1693">    private final HRegionServer instance;</span>
+<span class="source-line-no">1694</span><span id="line-1694">    private final int majorCompactPriority;</span>
+<span class="source-line-no">1695</span><span id="line-1695">    private final static int DEFAULT_PRIORITY = Integer.MAX_VALUE;</span>
+<span class="source-line-no">1696</span><span id="line-1696">    // Iteration is 1-based rather than 0-based so we don't check for compaction</span>
+<span class="source-line-no">1697</span><span id="line-1697">    // immediately upon region server startup</span>
+<span class="source-line-no">1698</span><span id="line-1698">    private long iteration = 1;</span>
+<span class="source-line-no">1699</span><span id="line-1699"></span>
+<span class="source-line-no">1700</span><span id="line-1700">    CompactionChecker(final HRegionServer h, final int sleepTime, final Stoppable stopper) {</span>
+<span class="source-line-no">1701</span><span id="line-1701">      super("CompactionChecker", stopper, sleepTime);</span>
+<span class="source-line-no">1702</span><span id="line-1702">      this.instance = h;</span>
+<span class="source-line-no">1703</span><span id="line-1703">      LOG.info(this.getName() + " runs every " + Duration.ofMillis(sleepTime));</span>
+<span class="source-line-no">1704</span><span id="line-1704"></span>
+<span class="source-line-no">1705</span><span id="line-1705">      /*</span>
+<span class="source-line-no">1706</span><span id="line-1706">       * MajorCompactPriority is configurable. If not set, the compaction will use default priority.</span>
+<span class="source-line-no">1707</span><span id="line-1707">       */</span>
+<span class="source-line-no">1708</span><span id="line-1708">      this.majorCompactPriority = this.instance.conf</span>
+<span class="source-line-no">1709</span><span id="line-1709">        .getInt("hbase.regionserver.compactionChecker.majorCompactPriority", DEFAULT_PRIORITY);</span>
+<span class="source-line-no">1710</span><span id="line-1710">    }</span>
+<span class="source-line-no">1711</span><span id="line-1711"></span>
+<span class="source-line-no">1712</span><span id="line-1712">    @Override</span>
+<span class="source-line-no">1713</span><span id="line-1713">    protected void chore() {</span>
+<span class="source-line-no">1714</span><span id="line-1714">      for (HRegion hr : this.instance.onlineRegions.values()) {</span>
+<span class="source-line-no">1715</span><span id="line-1715">        // If region is read only or compaction is disabled at table level, there's no need to</span>
+<span class="source-line-no">1716</span><span id="line-1716">        // iterate through region's stores</span>
+<span class="source-line-no">1717</span><span id="line-1717">        if (hr == null || hr.isReadOnly() || !hr.getTableDescriptor().isCompactionEnabled()) {</span>
+<span class="source-line-no">1718</span><span id="line-1718">          continue;</span>
+<span class="source-line-no">1719</span><span id="line-1719">        }</span>
+<span class="source-line-no">1720</span><span id="line-1720"></span>
+<span class="source-line-no">1721</span><span id="line-1721">        for (HStore s : hr.stores.values()) {</span>
+<span class="source-line-no">1722</span><span id="line-1722">          try {</span>
+<span class="source-line-no">1723</span><span id="line-1723">            long multiplier = s.getCompactionCheckMultiplier();</span>
+<span class="source-line-no">1724</span><span id="line-1724">            assert multiplier &gt; 0;</span>
+<span class="source-line-no">1725</span><span id="line-1725">            if (iteration % multiplier != 0) {</span>
+<span class="source-line-no">1726</span><span id="line-1726">              continue;</span>
+<span class="source-line-no">1727</span><span id="line-1727">            }</span>
+<span class="source-line-no">1728</span><span id="line-1728">            if (s.needsCompaction()) {</span>
+<span class="source-line-no">1729</span><span id="line-1729">              // Queue a compaction. Will recognize if major is needed.</span>
+<span class="source-line-no">1730</span><span id="line-1730">              this.instance.compactSplitThread.requestSystemCompaction(hr, s,</span>
+<span class="source-line-no">1731</span><span id="line-1731">                getName() + " requests compaction");</span>
+<span class="source-line-no">1732</span><span id="line-1732">            } else if (s.shouldPerformMajorCompaction()) {</span>
+<span class="source-line-no">1733</span><span id="line-1733">              s.triggerMajorCompaction();</span>
+<span class="source-line-no">1734</span><span id="line-1734">              if (</span>
+<span class="source-line-no">1735</span><span id="line-1735">                majorCompactPriority == DEFAULT_PRIORITY</span>
+<span class="source-line-no">1736</span><span id="line-1736">                  || majorCompactPriority &gt; hr.getCompactPriority()</span>
+<span class="source-line-no">1737</span><span id="line-1737">              ) {</span>
 <span class="source-line-no">1738</span><span id="line-1738">                this.instance.compactSplitThread.requestCompaction(hr, s,</span>
-<span class="source-line-no">1739</span><span id="line-1739">                  getName() + " requests major compaction; use configured priority",</span>
-<span class="source-line-no">1740</span><span id="line-1740">                  this.majorCompactPriority, CompactionLifeCycleTracker.DUMMY, null);</span>
-<span class="source-line-no">1741</span><span id="line-1741">              }</span>
-<span class="source-line-no">1742</span><span id="line-1742">            }</span>
-<span class="source-line-no">1743</span><span id="line-1743">          } catch (IOException e) {</span>
-<span class="source-line-no">1744</span><span id="line-1744">            LOG.warn("Failed major compaction check on " + hr, e);</span>
-<span class="source-line-no">1745</span><span id="line-1745">          }</span>
-<span class="source-line-no">1746</span><span id="line-1746">        }</span>
-<span class="source-line-no">1747</span><span id="line-1747">      }</span>
-<span class="source-line-no">1748</span><span id="line-1748">      iteration = (iteration == Long.MAX_VALUE) ? 0 : (iteration + 1);</span>
-<span class="source-line-no">1749</span><span id="line-1749">    }</span>
-<span class="source-line-no">1750</span><span id="line-1750">  }</span>
-<span class="source-line-no">1751</span><span id="line-1751"></span>
-<span class="source-line-no">1752</span><span id="line-1752">  private static class PeriodicMemStoreFlusher extends ScheduledChore {</span>
-<span class="source-line-no">1753</span><span id="line-1753">    private final HRegionServer server;</span>
-<span class="source-line-no">1754</span><span id="line-1754">    private final static int RANGE_OF_DELAY = 5 * 60; // 5 min in seconds</span>
-<span class="source-line-no">1755</span><span id="line-1755">    private final static int MIN_DELAY_TIME = 0; // millisec</span>
-<span class="source-line-no">1756</span><span id="line-1756">    private final long rangeOfDelayMs;</span>
-<span class="source-line-no">1757</span><span id="line-1757"></span>
-<span class="source-line-no">1758</span><span id="line-1758">    PeriodicMemStoreFlusher(int cacheFlushInterval, final HRegionServer server) {</span>
-<span class="source-line-no">1759</span><span id="line-1759">      super("MemstoreFlusherChore", server, cacheFlushInterval);</span>
-<span class="source-line-no">1760</span><span id="line-1760">      this.server = server;</span>
+<span class="source-line-no">1739</span><span id="line-1739">                  getName() + " requests major compaction; use default priority", Store.NO_PRIORITY,</span>
+<span class="source-line-no">1740</span><span id="line-1740">                  CompactionLifeCycleTracker.DUMMY, null);</span>
+<span class="source-line-no">1741</span><span id="line-1741">              } else {</span>
+<span class="source-line-no">1742</span><span id="line-1742">                this.instance.compactSplitThread.requestCompaction(hr, s,</span>
+<span class="source-line-no">1743</span><span id="line-1743">                  getName() + " requests major compaction; use configured priority",</span>
+<span class="source-line-no">1744</span><span id="line-1744">                  this.majorCompactPriority, CompactionLifeCycleTracker.DUMMY, null);</span>
+<span class="source-line-no">1745</span><span id="line-1745">              }</span>
+<span class="source-line-no">1746</span><span id="line-1746">            }</span>
+<span class="source-line-no">1747</span><span id="line-1747">          } catch (IOException e) {</span>
+<span class="source-line-no">1748</span><span id="line-1748">            LOG.warn("Failed major compaction check on " + hr, e);</span>
+<span class="source-line-no">1749</span><span id="line-1749">          }</span>
+<span class="source-line-no">1750</span><span id="line-1750">        }</span>
+<span class="source-line-no">1751</span><span id="line-1751">      }</span>
+<span class="source-line-no">1752</span><span id="line-1752">      iteration = (iteration == Long.MAX_VALUE) ? 0 : (iteration + 1);</span>
+<span class="source-line-no">1753</span><span id="line-1753">    }</span>
+<span class="source-line-no">1754</span><span id="line-1754">  }</span>
+<span class="source-line-no">1755</span><span id="line-1755"></span>
+<span class="source-line-no">1756</span><span id="line-1756">  private static class PeriodicMemStoreFlusher extends ScheduledChore {</span>
+<span class="source-line-no">1757</span><span id="line-1757">    private final HRegionServer server;</span>
+<span class="source-line-no">1758</span><span id="line-1758">    private final static int RANGE_OF_DELAY = 5 * 60; // 5 min in seconds</span>
+<span class="source-line-no">1759</span><span id="line-1759">    private final static int MIN_DELAY_TIME = 0; // millisec</span>
+<span class="source-line-no">1760</span><span id="line-1760">    private final long rangeOfDelayMs;</span>
 <span class="source-line-no">1761</span><span id="line-1761"></span>
-<span class="source-line-no">1762</span><span id="line-1762">      final long configuredRangeOfDelay = server.getConfiguration()</span>
-<span class="source-line-no">1763</span><span id="line-1763">        .getInt("hbase.regionserver.periodicmemstoreflusher.rangeofdelayseconds", RANGE_OF_DELAY);</span>
-<span class="source-line-no">1764</span><span id="line-1764">      this.rangeOfDelayMs = TimeUnit.SECONDS.toMillis(configuredRangeOfDelay);</span>
-<span class="source-line-no">1765</span><span id="line-1765">    }</span>
-<span class="source-line-no">1766</span><span id="line-1766"></span>
-<span class="source-line-no">1767</span><span id="line-1767">    @Override</span>
-<span class="source-line-no">1768</span><span id="line-1768">    protected void chore() {</span>
-<span class="source-line-no">1769</span><span id="line-1769">      final StringBuilder whyFlush = new StringBuilder();</span>
-<span class="source-line-no">1770</span><span id="line-1770">      for (HRegion r : this.server.onlineRegions.values()) {</span>
-<span class="source-line-no">1771</span><span id="line-1771">        if (r == null) {</span>
-<span class="source-line-no">1772</span><span id="line-1772">          continue;</span>
-<span class="source-line-no">1773</span><span id="line-1773">        }</span>
-<span class="source-line-no">1774</span><span id="line-1774">        if (r.shouldFlush(whyFlush)) {</span>
-<span class="source-line-no">1775</span><span id="line-1775">          FlushRequester requester = server.getFlushRequester();</span>
-<span class="source-line-no">1776</span><span id="line-1776">          if (requester != null) {</span>
-<span class="source-line-no">1777</span><span id="line-1777">            long delay = ThreadLocalRandom.current().nextLong(rangeOfDelayMs) + MIN_DELAY_TIME;</span>
-<span class="source-line-no">1778</span><span id="line-1778">            // Throttle the flushes by putting a delay. If we don't throttle, and there</span>
-<span class="source-line-no">1779</span><span id="line-1779">            // is a balanced write-load on the regions in a table, we might end up</span>
-<span class="source-line-no">1780</span><span id="line-1780">            // overwhelming the filesystem with too many flushes at once.</span>
-<span class="source-line-no">1781</span><span id="line-1781">            if (requester.requestDelayedFlush(r, delay)) {</span>
-<span class="source-line-no">1782</span><span id="line-1782">              LOG.info("{} requesting flush of {} because {} after random delay {} ms", getName(),</span>
-<span class="source-line-no">1783</span><span id="line-1783">                r.getRegionInfo().getRegionNameAsString(), whyFlush.toString(), delay);</span>
-<span class="source-line-no">1784</span><span id="line-1784">            }</span>
-<span class="source-line-no">1785</span><span id="line-1785">          }</span>
-<span class="source-line-no">1786</span><span id="line-1786">        }</span>
-<span class="source-line-no">1787</span><span id="line-1787">      }</span>
-<span class="source-line-no">1788</span><span id="line-1788">    }</span>
-<span class="source-line-no">1789</span><span id="line-1789">  }</span>
-<span class="source-line-no">1790</span><span id="line-1790"></span>
-<span class="source-line-no">1791</span><span id="line-1791">  /**</span>
-<span class="source-line-no">1792</span><span id="line-1792">   * Report the status of the server. A server is online once all the startup is completed (setting</span>
-<span class="source-line-no">1793</span><span id="line-1793">   * up filesystem, starting executorService threads, etc.). This method is designed mostly to be</span>
-<span class="source-line-no">1794</span><span id="line-1794">   * useful in tests.</span>
-<span class="source-line-no">1795</span><span id="line-1795">   * @return true if online, false if not.</span>
-<span class="source-line-no">1796</span><span id="line-1796">   */</span>
-<span class="source-line-no">1797</span><span id="line-1797">  public boolean isOnline() {</span>
-<span class="source-line-no">1798</span><span id="line-1798">    return online.get();</span>
-<span class="source-line-no">1799</span><span id="line-1799">  }</span>
-<span class="source-line-no">1800</span><span id="line-1800"></span>
-<span class="source-line-no">1801</span><span id="line-1801">  /**</span>
-<span class="source-line-no">1802</span><span id="line-1802">   * Setup WAL log and replication if enabled. Replication setup is done in here because it wants to</span>
-<span class="source-line-no">1803</span><span id="line-1803">   * be hooked up to WAL.</span>
-<span class="source-line-no">1804</span><span id="line-1804">   */</span>
-<span class="source-line-no">1805</span><span id="line-1805">  private void setupWALAndReplication() throws IOException {</span>
-<span class="source-line-no">1806</span><span id="line-1806">    WALFactory factory = new WALFactory(conf, serverName, this);</span>
-<span class="source-line-no">1807</span><span id="line-1807">    // TODO Replication make assumptions here based on the default filesystem impl</span>
-<span class="source-line-no">1808</span><span id="line-1808">    Path oldLogDir = new Path(walRootDir, HConstants.HREGION_OLDLOGDIR_NAME);</span>
-<span class="source-line-no">1809</span><span id="line-1809">    String logName = AbstractFSWALProvider.getWALDirectoryName(this.serverName.toString());</span>
-<span class="source-line-no">1810</span><span id="line-1810"></span>
-<span class="source-line-no">1811</span><span id="line-1811">    Path logDir = new Path(walRootDir, logName);</span>
-<span class="source-line-no">1812</span><span id="line-1812">    LOG.debug("logDir={}", logDir);</span>
-<span class="source-line-no">1813</span><span id="line-1813">    if (this.walFs.exists(logDir)) {</span>
-<span class="source-line-no">1814</span><span id="line-1814">      throw new RegionServerRunningException(</span>
-<span class="source-line-no">1815</span><span id="line-1815">        "Region server has already created directory at " + this.serverName.toString());</span>
-<span class="source-line-no">1816</span><span id="line-1816">    }</span>
-<span class="source-line-no">1817</span><span id="line-1817">    // Create wal directory here and we will never create it again in other places. This is</span>
-<span class="source-line-no">1818</span><span id="line-1818">    // important to make sure that our fencing way takes effect. See HBASE-29797 for more details.</span>
-<span class="source-line-no">1819</span><span id="line-1819">    if (!this.walFs.mkdirs(logDir)) {</span>
-<span class="source-line-no">1820</span><span id="line-1820">      throw new IOException("Can not create wal directory " + logDir);</span>
-<span class="source-line-no">1821</span><span id="line-1821">    }</span>
-<span class="source-line-no">1822</span><span id="line-1822">    // Instantiate replication if replication enabled. Pass it the log directories.</span>
-<span class="source-line-no">1823</span><span id="line-1823">    createNewReplicationInstance(conf, this, this.walFs, logDir, oldLogDir, factory);</span>
-<span class="source-line-no">1824</span><span id="line-1824"></span>
-<span class="source-line-no">1825</span><span id="line-1825">    WALActionsListener walEventListener = getWALEventTrackerListener(conf);</span>
-<span class="source-line-no">1826</span><span id="line-1826">    if (walEventListener != null &amp;&amp; factory.getWALProvider() != null) {</span>
-<span class="source-line-no">1827</span><span id="line-1827">      factory.getWALProvider().addWALActionsListener(walEventListener);</span>
-<span class="source-line-no">1828</span><span id="line-1828">    }</span>
-<span class="source-line-no">1829</span><span id="line-1829">    this.walFactory = factory;</span>
-<span class="source-line-no">1830</span><span id="line-1830">  }</span>
-<span class="source-line-no">1831</span><span id="line-1831"></span>
-<span class="source-line-no">1832</span><span id="line-1832">  private WALActionsListener getWALEventTrackerListener(Configuration conf) {</span>
-<span class="source-line-no">1833</span><span id="line-1833">    if (conf.getBoolean(WAL_EVENT_TRACKER_ENABLED_KEY, WAL_EVENT_TRACKER_ENABLED_DEFAULT)) {</span>
-<span class="source-line-no">1834</span><span id="line-1834">      WALEventTrackerListener listener =</span>
-<span class="source-line-no">1835</span><span id="line-1835">        new WALEventTrackerListener(conf, getNamedQueueRecorder(), getServerName());</span>
-<span class="source-line-no">1836</span><span id="line-1836">      return listener;</span>
-<span class="source-line-no">1837</span><span id="line-1837">    }</span>
-<span class="source-line-no">1838</span><span id="line-1838">    return null;</span>
-<span class="source-line-no">1839</span><span id="line-1839">  }</span>
-<span class="source-line-no">1840</span><span id="line-1840"></span>
-<span class="source-line-no">1841</span><span id="line-1841">  /**</span>
-<span class="source-line-no">1842</span><span id="line-1842">   * Start up replication source and sink handlers.</span>
-<span class="source-line-no">1843</span><span id="line-1843">   */</span>
-<span class="source-line-no">1844</span><span id="line-1844">  private void startReplicationService() throws IOException {</span>
-<span class="source-line-no">1845</span><span id="line-1845">    if (sameReplicationSourceAndSink &amp;&amp; this.replicationSourceHandler != null) {</span>
-<span class="source-line-no">1846</span><span id="line-1846">      this.replicationSourceHandler.startReplicationService();</span>
-<span class="source-line-no">1847</span><span id="line-1847">    } else {</span>
-<span class="source-line-no">1848</span><span id="line-1848">      if (this.replicationSourceHandler != null) {</span>
-<span class="source-line-no">1849</span><span id="line-1849">        this.replicationSourceHandler.startReplicationService();</span>
-<span class="source-line-no">1850</span><span id="line-1850">      }</span>
-<span class="source-line-no">1851</span><span id="line-1851">      if (this.replicationSinkHandler != null) {</span>
-<span class="source-line-no">1852</span><span id="line-1852">        this.replicationSinkHandler.startReplicationService();</span>
-<span class="source-line-no">1853</span><span id="line-1853">      }</span>
-<span class="source-line-no">1854</span><span id="line-1854">    }</span>
-<span class="source-line-no">1855</span><span id="line-1855">  }</span>
-<span class="source-line-no">1856</span><span id="line-1856"></span>
-<span class="source-line-no">1857</span><span id="line-1857">  /** Returns Master address tracker instance. */</span>
-<span class="source-line-no">1858</span><span id="line-1858">  public MasterAddressTracker getMasterAddressTracker() {</span>
-<span class="source-line-no">1859</span><span id="line-1859">    return this.masterAddressTracker;</span>
-<span class="source-line-no">1860</span><span id="line-1860">  }</span>
-<span class="source-line-no">1861</span><span id="line-1861"></span>
-<span class="source-line-no">1862</span><span id="line-1862">  /**</span>
-<span class="source-line-no">1863</span><span id="line-1863">   * Start maintenance Threads, Server, Worker and lease checker threads. Start all threads we need</span>
-<span class="source-line-no">1864</span><span id="line-1864">   * to run. This is called after we've successfully registered with the Master. Install an</span>
-<span class="source-line-no">1865</span><span id="line-1865">   * UncaughtExceptionHandler that calls abort of RegionServer if we get an unhandled exception. We</span>
-<span class="source-line-no">1866</span><span id="line-1866">   * cannot set the handler on all threads. Server's internal Listener thread is off limits. For</span>
-<span class="source-line-no">1867</span><span id="line-1867">   * Server, if an OOME, it waits a while then retries. Meantime, a flush or a compaction that tries</span>
-<span class="source-line-no">1868</span><span id="line-1868">   * to run should trigger same critical condition and the shutdown will run. On its way out, this</span>
-<span class="source-line-no">1869</span><span id="line-1869">   * server will shut down Server. Leases are sort of inbetween. It has an internal thread that</span>
-<span class="source-line-no">1870</span><span id="line-1870">   * while it inherits from Chore, it keeps its own internal stop mechanism so needs to be stopped</span>
-<span class="source-line-no">1871</span><span id="line-1871">   * by this hosting server. Worker logs the exception and exits.</span>
-<span class="source-line-no">1872</span><span id="line-1872">   */</span>
-<span class="source-line-no">1873</span><span id="line-1873">  private void startServices() throws IOException {</span>
-<span class="source-line-no">1874</span><span id="line-1874">    if (!isStopped() &amp;&amp; !isAborted()) {</span>
-<span class="source-line-no">1875</span><span id="line-1875">      initializeThreads();</span>
-<span class="source-line-no">1876</span><span id="line-1876">    }</span>
-<span class="source-line-no">1877</span><span id="line-1877">    this.secureBulkLoadManager = new SecureBulkLoadManager(this.conf, asyncClusterConnection);</span>
-<span class="source-line-no">1878</span><span id="line-1878">    this.secureBulkLoadManager.start();</span>
-<span class="source-line-no">1879</span><span id="line-1879"></span>
-<span class="source-line-no">1880</span><span id="line-1880">    // Health checker thread.</span>
-<span class="source-line-no">1881</span><span id="line-1881">    if (isHealthCheckerConfigured()) {</span>
-<span class="source-line-no">1882</span><span id="line-1882">      int sleepTime = this.conf.getInt(HConstants.HEALTH_CHORE_WAKE_FREQ,</span>
-<span class="source-line-no">1883</span><span id="line-1883">        HConstants.DEFAULT_THREAD_WAKE_FREQUENCY);</span>
-<span class="source-line-no">1884</span><span id="line-1884">      healthCheckChore = new HealthCheckChore(sleepTime, this, getConfiguration());</span>
-<span class="source-line-no">1885</span><span id="line-1885">    }</span>
-<span class="source-line-no">1886</span><span id="line-1886">    // Executor status collect thread.</span>
-<span class="source-line-no">1887</span><span id="line-1887">    if (</span>
-<span class="source-line-no">1888</span><span id="line-1888">      this.conf.getBoolean(HConstants.EXECUTOR_STATUS_COLLECT_ENABLED,</span>
-<span class="source-line-no">1889</span><span id="line-1889">        HConstants.DEFAULT_EXECUTOR_STATUS_COLLECT_ENABLED)</span>
-<span class="source-line-no">1890</span><span id="line-1890">    ) {</span>
-<span class="source-line-no">1891</span><span id="line-1891">      int sleepTime =</span>
-<span class="source-line-no">1892</span><span id="line-1892">        this.conf.getInt(ExecutorStatusChore.WAKE_FREQ, ExecutorStatusChore.DEFAULT_WAKE_FREQ);</span>
-<span class="source-line-no">1893</span><span id="line-1893">      executorStatusChore = new ExecutorStatusChore(sleepTime, this, this.getExecutorService(),</span>
-<span class="source-line-no">1894</span><span id="line-1894">        this.metricsRegionServer.getMetricsSource());</span>
-<span class="source-line-no">1895</span><span id="line-1895">    }</span>
-<span class="source-line-no">1896</span><span id="line-1896"></span>
-<span class="source-line-no">1897</span><span id="line-1897">    this.walRoller = new LogRoller(this);</span>
-<span class="source-line-no">1898</span><span id="line-1898">    this.flushThroughputController = FlushThroughputControllerFactory.create(this, conf);</span>
-<span class="source-line-no">1899</span><span id="line-1899">    this.procedureResultReporter = new RemoteProcedureResultReporter(this);</span>
+<span class="source-line-no">1762</span><span id="line-1762">    PeriodicMemStoreFlusher(int cacheFlushInterval, final HRegionServer server) {</span>
+<span class="source-line-no">1763</span><span id="line-1763">      super("MemstoreFlusherChore", server, cacheFlushInterval);</span>
+<span class="source-line-no">1764</span><span id="line-1764">      this.server = server;</span>
+<span class="source-line-no">1765</span><span id="line-1765"></span>
+<span class="source-line-no">1766</span><span id="line-1766">      final long configuredRangeOfDelay = server.getConfiguration()</span>
+<span class="source-line-no">1767</span><span id="line-1767">        .getInt("hbase.regionserver.periodicmemstoreflusher.rangeofdelayseconds", RANGE_OF_DELAY);</span>
+<span class="source-line-no">1768</span><span id="line-1768">      this.rangeOfDelayMs = TimeUnit.SECONDS.toMillis(configuredRangeOfDelay);</span>
+<span class="source-line-no">1769</span><span id="line-1769">    }</span>
+<span class="source-line-no">1770</span><span id="line-1770"></span>
+<span class="source-line-no">1771</span><span id="line-1771">    @Override</span>
+<span class="source-line-no">1772</span><span id="line-1772">    protected void chore() {</span>
+<span class="source-line-no">1773</span><span id="line-1773">      final StringBuilder whyFlush = new StringBuilder();</span>
+<span class="source-line-no">1774</span><span id="line-1774">      for (HRegion r : this.server.onlineRegions.values()) {</span>
+<span class="source-line-no">1775</span><span id="line-1775">        if (r == null) {</span>
+<span class="source-line-no">1776</span><span id="line-1776">          continue;</span>
+<span class="source-line-no">1777</span><span id="line-1777">        }</span>
+<span class="source-line-no">1778</span><span id="line-1778">        if (r.shouldFlush(whyFlush)) {</span>
+<span class="source-line-no">1779</span><span id="line-1779">          FlushRequester requester = server.getFlushRequester();</span>
+<span class="source-line-no">1780</span><span id="line-1780">          if (requester != null) {</span>
+<span class="source-line-no">1781</span><span id="line-1781">            long delay = ThreadLocalRandom.current().nextLong(rangeOfDelayMs) + MIN_DELAY_TIME;</span>
+<span class="source-line-no">1782</span><span id="line-1782">            // Throttle the flushes by putting a delay. If we don't throttle, and there</span>
+<span class="source-line-no">1783</span><span id="line-1783">            // is a balanced write-load on the regions in a table, we might end up</span>
+<span class="source-line-no">1784</span><span id="line-1784">            // overwhelming the filesystem with too many flushes at once.</span>
+<span class="source-line-no">1785</span><span id="line-1785">            if (requester.requestDelayedFlush(r, delay)) {</span>
+<span class="source-line-no">1786</span><span id="line-1786">              LOG.info("{} requesting flush of {} because {} after random delay {} ms", getName(),</span>
+<span class="source-line-no">1787</span><span id="line-1787">                r.getRegionInfo().getRegionNameAsString(), whyFlush.toString(), delay);</span>
+<span class="source-line-no">1788</span><span id="line-1788">            }</span>
+<span class="source-line-no">1789</span><span id="line-1789">          }</span>
+<span class="source-line-no">1790</span><span id="line-1790">        }</span>
+<span class="source-line-no">1791</span><span id="line-1791">      }</span>
+<span class="source-line-no">1792</span><span id="line-1792">    }</span>
+<span class="source-line-no">1793</span><span id="line-1793">  }</span>
+<span class="source-line-no">1794</span><span id="line-1794"></span>
+<span class="source-line-no">1795</span><span id="line-1795">  /**</span>
+<span class="source-line-no">1796</span><span id="line-1796">   * Report the status of the server. A server is online once all the startup is completed (setting</span>
+<span class="source-line-no">1797</span><span id="line-1797">   * up filesystem, starting executorService threads, etc.). This method is designed mostly to be</span>
+<span class="source-line-no">1798</span><span id="line-1798">   * useful in tests.</span>
+<span class="source-line-no">1799</span><span id="line-1799">   * @return true if online, false if not.</span>
+<span class="source-line-no">1800</span><span id="line-1800">   */</span>
+<span class="source-line-no">1801</span><span id="line-1801">  public boolean isOnline() {</span>
+<span class="source-line-no">1802</span><span id="line-1802">    return online.get();</span>
+<span class="source-line-no">1803</span><span id="line-1803">  }</span>
+<span class="source-line-no">1804</span><span id="line-1804"></span>
+<span class="source-line-no">1805</span><span id="line-1805">  /**</span>
+<span class="source-line-no">1806</span><span id="line-1806">   * Setup WAL log and replication if enabled. Replication setup is done in here because it wants to</span>
+<span class="source-line-no">1807</span><span id="line-1807">   * be hooked up to WAL.</span>
+<span class="source-line-no">1808</span><span id="line-1808">   */</span>
+<span class="source-line-no">1809</span><span id="line-1809">  private void setupWALAndReplication() throws IOException {</span>
+<span class="source-line-no">1810</span><span id="line-1810">    WALFactory factory = new WALFactory(conf, serverName, this);</span>
+<span class="source-line-no">1811</span><span id="line-1811">    // TODO Replication make assumptions here based on the default filesystem impl</span>
+<span class="source-line-no">1812</span><span id="line-1812">    Path oldLogDir = new Path(walRootDir, HConstants.HREGION_OLDLOGDIR_NAME);</span>
+<span class="source-line-no">1813</span><span id="line-1813">    String logName = AbstractFSWALProvider.getWALDirectoryName(this.serverName.toString());</span>
+<span class="source-line-no">1814</span><span id="line-1814"></span>
+<span class="source-line-no">1815</span><span id="line-1815">    Path logDir = new Path(walRootDir, logName);</span>
+<span class="source-line-no">1816</span><span id="line-1816">    LOG.debug("logDir={}", logDir);</span>
+<span class="source-line-no">1817</span><span id="line-1817">    if (this.walFs.exists(logDir)) {</span>
+<span class="source-line-no">1818</span><span id="line-1818">      throw new RegionServerRunningException(</span>
+<span class="source-line-no">1819</span><span id="line-1819">        "Region server has already created directory at " + this.serverName.toString());</span>
+<span class="source-line-no">1820</span><span id="line-1820">    }</span>
+<span class="source-line-no">1821</span><span id="line-1821">    // Create wal directory here and we will never create it again in other places. This is</span>
+<span class="source-line-no">1822</span><span id="line-1822">    // important to make sure that our fencing way takes effect. See HBASE-29797 for more details.</span>
+<span class="source-line-no">1823</span><span id="line-1823">    if (!this.walFs.mkdirs(logDir)) {</span>
+<span class="source-line-no">1824</span><span id="line-1824">      throw new IOException("Can not create wal directory " + logDir);</span>
+<span class="source-line-no">1825</span><span id="line-1825">    }</span>
+<span class="source-line-no">1826</span><span id="line-1826">    // Instantiate replication if replication enabled. Pass it the log directories.</span>
+<span class="source-line-no">1827</span><span id="line-1827">    createNewReplicationInstance(conf, this, this.walFs, logDir, oldLogDir, factory);</span>
+<span class="source-line-no">1828</span><span id="line-1828"></span>
+<span class="source-line-no">1829</span><span id="line-1829">    WALActionsListener walEventListener = getWALEventTrackerListener(conf);</span>
+<span class="source-line-no">1830</span><span id="line-1830">    if (walEventListener != null &amp;&amp; factory.getWALProvider() != null) {</span>
+<span class="source-line-no">1831</span><span id="line-1831">      factory.getWALProvider().addWALActionsListener(walEventListener);</span>
+<span class="source-line-no">1832</span><span id="line-1832">    }</span>
+<span class="source-line-no">1833</span><span id="line-1833">    this.walFactory = factory;</span>
+<span class="source-line-no">1834</span><span id="line-1834">  }</span>
+<span class="source-line-no">1835</span><span id="line-1835"></span>
+<span class="source-line-no">1836</span><span id="line-1836">  private WALActionsListener getWALEventTrackerListener(Configuration conf) {</span>
+<span class="source-line-no">1837</span><span id="line-1837">    if (conf.getBoolean(WAL_EVENT_TRACKER_ENABLED_KEY, WAL_EVENT_TRACKER_ENABLED_DEFAULT)) {</span>
+<span class="source-line-no">1838</span><span id="line-1838">      WALEventTrackerListener listener =</span>
+<span class="source-line-no">1839</span><span id="line-1839">        new WALEventTrackerListener(conf, getNamedQueueRecorder(), getServerName());</span>
+<span class="source-line-no">1840</span><span id="line-1840">      return listener;</span>
+<span class="source-line-no">1841</span><span id="line-1841">    }</span>
+<span class="source-line-no">1842</span><span id="line-1842">    return null;</span>
+<span class="source-line-no">1843</span><span id="line-1843">  }</span>
+<span class="source-line-no">1844</span><span id="line-1844"></span>
+<span class="source-line-no">1845</span><span id="line-1845">  /**</span>
+<span class="source-line-no">1846</span><span id="line-1846">   * Start up replication source and sink handlers.</span>
+<span class="source-line-no">1847</span><span id="line-1847">   */</span>
+<span class="source-line-no">1848</span><span id="line-1848">  private void startReplicationService() throws IOException {</span>
+<span class="source-line-no">1849</span><span id="line-1849">    if (sameReplicationSourceAndSink &amp;&amp; this.replicationSourceHandler != null) {</span>
+<span class="source-line-no">1850</span><span id="line-1850">      this.replicationSourceHandler.startReplicationService();</span>
+<span class="source-line-no">1851</span><span id="line-1851">    } else {</span>
+<span class="source-line-no">1852</span><span id="line-1852">      if (this.replicationSourceHandler != null) {</span>
+<span class="source-line-no">1853</span><span id="line-1853">        this.replicationSourceHandler.startReplicationService();</span>
+<span class="source-line-no">1854</span><span id="line-1854">      }</span>
+<span class="source-line-no">1855</span><span id="line-1855">      if (this.replicationSinkHandler != null) {</span>
+<span class="source-line-no">1856</span><span id="line-1856">        this.replicationSinkHandler.startReplicationService();</span>
+<span class="source-line-no">1857</span><span id="line-1857">      }</span>
+<span class="source-line-no">1858</span><span id="line-1858">    }</span>
+<span class="source-line-no">1859</span><span id="line-1859">  }</span>
+<span class="source-line-no">1860</span><span id="line-1860"></span>
+<span class="source-line-no">1861</span><span id="line-1861">  /** Returns Master address tracker instance. */</span>
+<span class="source-line-no">1862</span><span id="line-1862">  public MasterAddressTracker getMasterAddressTracker() {</span>
+<span class="source-line-no">1863</span><span id="line-1863">    return this.masterAddressTracker;</span>
+<span class="source-line-no">1864</span><span id="line-1864">  }</span>
+<span class="source-line-no">1865</span><span id="line-1865"></span>
+<span class="source-line-no">1866</span><span id="line-1866">  /**</span>
+<span class="source-line-no">1867</span><span id="line-1867">   * Start maintenance Threads, Server, Worker and lease checker threads. Start all threads we need</span>
+<span class="source-line-no">1868</span><span id="line-1868">   * to run. This is called after we've successfully registered with the Master. Install an</span>
+<span class="source-line-no">1869</span><span id="line-1869">   * UncaughtExceptionHandler that calls abort of RegionServer if we get an unhandled exception. We</span>
+<span class="source-line-no">1870</span><span id="line-1870">   * cannot set the handler on all threads. Server's internal Listener thread is off limits. For</span>
+<span class="source-line-no">1871</span><span id="line-1871">   * Server, if an OOME, it waits a while then retries. Meantime, a flush or a compaction that tries</span>
+<span class="source-line-no">1872</span><span id="line-1872">   * to run should trigger same critical condition and the shutdown will run. On its way out, this</span>
+<span class="source-line-no">1873</span><span id="line-1873">   * server will shut down Server. Leases are sort of inbetween. It has an internal thread that</span>
+<span class="source-line-no">1874</span><span id="line-1874">   * while it inherits from Chore, it keeps its own internal stop mechanism so needs to be stopped</span>
+<span class="source-line-no">1875</span><span id="line-1875">   * by this hosting server. Worker logs the exception and exits.</span>
+<span class="source-line-no">1876</span><span id="line-1876">   */</span>
+<span class="source-line-no">1877</span><span id="line-1877">  private void startServices() throws IOException {</span>
+<span class="source-line-no">1878</span><span id="line-1878">    if (!isStopped() &amp;&amp; !isAborted()) {</span>
+<span class="source-line-no">1879</span><span id="line-1879">      initializeThreads();</span>
+<span class="source-line-no">1880</span><span id="line-1880">    }</span>
+<span class="source-line-no">1881</span><span id="line-1881">    this.secureBulkLoadManager = new SecureBulkLoadManager(this.conf, asyncClusterConnection);</span>
+<span class="source-line-no">1882</span><span id="line-1882">    this.secureBulkLoadManager.start();</span>
+<span class="source-line-no">1883</span><span id="line-1883"></span>
+<span class="source-line-no">1884</span><span id="line-1884">    // Health checker thread.</span>
+<span class="source-line-no">1885</span><span id="line-1885">    if (isHealthCheckerConfigured()) {</span>
+<span class="source-line-no">1886</span><span id="line-1886">      int sleepTime = this.conf.getInt(HConstants.HEALTH_CHORE_WAKE_FREQ,</span>
+<span class="source-line-no">1887</span><span id="line-1887">        HConstants.DEFAULT_THREAD_WAKE_FREQUENCY);</span>
+<span class="source-line-no">1888</span><span id="line-1888">      healthCheckChore = new HealthCheckChore(sleepTime, this, getConfiguration());</span>
+<span class="source-line-no">1889</span><span id="line-1889">    }</span>
+<span class="source-line-no">1890</span><span id="line-1890">    // Executor status collect thread.</span>
+<span class="source-line-no">1891</span><span id="line-1891">    if (</span>
+<span class="source-line-no">1892</span><span id="line-1892">      this.conf.getBoolean(HConstants.EXECUTOR_STATUS_COLLECT_ENABLED,</span>
+<span class="source-line-no">1893</span><span id="line-1893">        HConstants.DEFAULT_EXECUTOR_STATUS_COLLECT_ENABLED)</span>
+<span class="source-line-no">1894</span><span id="line-1894">    ) {</span>
+<span class="source-line-no">1895</span><span id="line-1895">      int sleepTime =</span>
+<span class="source-line-no">1896</span><span id="line-1896">        this.conf.getInt(ExecutorStatusChore.WAKE_FREQ, ExecutorStatusChore.DEFAULT_WAKE_FREQ);</span>
+<span class="source-line-no">1897</span><span id="line-1897">      executorStatusChore = new ExecutorStatusChore(sleepTime, this, this.getExecutorService(),</span>
+<span class="source-line-no">1898</span><span id="line-1898">        this.metricsRegionServer.getMetricsSource());</span>
+<span class="source-line-no">1899</span><span id="line-1899">    }</span>
 <span class="source-line-no">1900</span><span id="line-1900"></span>
-<span class="source-line-no">1901</span><span id="line-1901">    // Create the CompactedFileDischarger chore executorService. This chore helps to</span>
-<span class="source-line-no">1902</span><span id="line-1902">    // remove the compacted files that will no longer be used in reads.</span>
-<span class="source-line-no">1903</span><span id="line-1903">    // Default is 2 mins. The default value for TTLCleaner is 5 mins so we set this to</span>
-<span class="source-line-no">1904</span><span id="line-1904">    // 2 mins so that compacted files can be archived before the TTLCleaner runs</span>
-<span class="source-line-no">1905</span><span id="line-1905">    int cleanerInterval = conf.getInt("hbase.hfile.compaction.discharger.interval", 2 * 60 * 1000);</span>
-<span class="source-line-no">1906</span><span id="line-1906">    this.compactedFileDischarger = new CompactedHFilesDischarger(cleanerInterval, this, this);</span>
-<span class="source-line-no">1907</span><span id="line-1907">    choreService.scheduleChore(compactedFileDischarger);</span>
-<span class="source-line-no">1908</span><span id="line-1908"></span>
-<span class="source-line-no">1909</span><span id="line-1909">    // Start executor services</span>
-<span class="source-line-no">1910</span><span id="line-1910">    final int openRegionThreads = conf.getInt("hbase.regionserver.executor.openregion.threads", 3);</span>
-<span class="source-line-no">1911</span><span id="line-1911">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1912</span><span id="line-1912">      .setExecutorType(ExecutorType.RS_OPEN_REGION).setCorePoolSize(openRegionThreads));</span>
-<span class="source-line-no">1913</span><span id="line-1913">    final int openMetaThreads = conf.getInt("hbase.regionserver.executor.openmeta.threads", 1);</span>
-<span class="source-line-no">1914</span><span id="line-1914">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1915</span><span id="line-1915">      .setExecutorType(ExecutorType.RS_OPEN_META).setCorePoolSize(openMetaThreads));</span>
-<span class="source-line-no">1916</span><span id="line-1916">    final int openPriorityRegionThreads =</span>
-<span class="source-line-no">1917</span><span id="line-1917">      conf.getInt("hbase.regionserver.executor.openpriorityregion.threads", 3);</span>
-<span class="source-line-no">1918</span><span id="line-1918">    executorService.startExecutorService(</span>
-<span class="source-line-no">1919</span><span id="line-1919">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_OPEN_PRIORITY_REGION)</span>
-<span class="source-line-no">1920</span><span id="line-1920">        .setCorePoolSize(openPriorityRegionThreads));</span>
-<span class="source-line-no">1921</span><span id="line-1921">    final int closeRegionThreads =</span>
-<span class="source-line-no">1922</span><span id="line-1922">      conf.getInt("hbase.regionserver.executor.closeregion.threads", 3);</span>
-<span class="source-line-no">1923</span><span id="line-1923">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1924</span><span id="line-1924">      .setExecutorType(ExecutorType.RS_CLOSE_REGION).setCorePoolSize(closeRegionThreads));</span>
-<span class="source-line-no">1925</span><span id="line-1925">    final int closeMetaThreads = conf.getInt("hbase.regionserver.executor.closemeta.threads", 1);</span>
-<span class="source-line-no">1926</span><span id="line-1926">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1927</span><span id="line-1927">      .setExecutorType(ExecutorType.RS_CLOSE_META).setCorePoolSize(closeMetaThreads));</span>
-<span class="source-line-no">1928</span><span id="line-1928">    if (conf.getBoolean(StoreScanner.STORESCANNER_PARALLEL_SEEK_ENABLE, false)) {</span>
-<span class="source-line-no">1929</span><span id="line-1929">      final int storeScannerParallelSeekThreads =</span>
-<span class="source-line-no">1930</span><span id="line-1930">        conf.getInt("hbase.storescanner.parallel.seek.threads", 10);</span>
-<span class="source-line-no">1931</span><span id="line-1931">      executorService.startExecutorService(</span>
-<span class="source-line-no">1932</span><span id="line-1932">        executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_PARALLEL_SEEK)</span>
-<span class="source-line-no">1933</span><span id="line-1933">          .setCorePoolSize(storeScannerParallelSeekThreads).setAllowCoreThreadTimeout(true));</span>
-<span class="source-line-no">1934</span><span id="line-1934">    }</span>
-<span class="source-line-no">1935</span><span id="line-1935">    final int logReplayOpsThreads =</span>
-<span class="source-line-no">1936</span><span id="line-1936">      conf.getInt(HBASE_SPLIT_WAL_MAX_SPLITTER, DEFAULT_HBASE_SPLIT_WAL_MAX_SPLITTER);</span>
-<span class="source-line-no">1937</span><span id="line-1937">    executorService.startExecutorService(</span>
-<span class="source-line-no">1938</span><span id="line-1938">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_LOG_REPLAY_OPS)</span>
-<span class="source-line-no">1939</span><span id="line-1939">        .setCorePoolSize(logReplayOpsThreads).setAllowCoreThreadTimeout(true));</span>
-<span class="source-line-no">1940</span><span id="line-1940">    // Start the threads for compacted files discharger</span>
-<span class="source-line-no">1941</span><span id="line-1941">    final int compactionDischargerThreads =</span>
-<span class="source-line-no">1942</span><span id="line-1942">      conf.getInt(CompactionConfiguration.HBASE_HFILE_COMPACTION_DISCHARGER_THREAD_COUNT, 10);</span>
-<span class="source-line-no">1943</span><span id="line-1943">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1944</span><span id="line-1944">      .setExecutorType(ExecutorType.RS_COMPACTED_FILES_DISCHARGER)</span>
-<span class="source-line-no">1945</span><span id="line-1945">      .setCorePoolSize(compactionDischargerThreads));</span>
-<span class="source-line-no">1946</span><span id="line-1946">    if (ServerRegionReplicaUtil.isRegionReplicaWaitForPrimaryFlushEnabled(conf)) {</span>
-<span class="source-line-no">1947</span><span id="line-1947">      final int regionReplicaFlushThreads =</span>
-<span class="source-line-no">1948</span><span id="line-1948">        conf.getInt("hbase.regionserver.region.replica.flusher.threads",</span>
-<span class="source-line-no">1949</span><span id="line-1949">          conf.getInt("hbase.regionserver.executor.openregion.threads", 3));</span>
-<span class="source-line-no">1950</span><span id="line-1950">      executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1951</span><span id="line-1951">        .setExecutorType(ExecutorType.RS_REGION_REPLICA_FLUSH_OPS)</span>
-<span class="source-line-no">1952</span><span id="line-1952">        .setCorePoolSize(regionReplicaFlushThreads));</span>
-<span class="source-line-no">1953</span><span id="line-1953">    }</span>
-<span class="source-line-no">1954</span><span id="line-1954">    final int refreshPeerThreads =</span>
-<span class="source-line-no">1955</span><span id="line-1955">      conf.getInt("hbase.regionserver.executor.refresh.peer.threads", 2);</span>
-<span class="source-line-no">1956</span><span id="line-1956">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1957</span><span id="line-1957">      .setExecutorType(ExecutorType.RS_REFRESH_PEER).setCorePoolSize(refreshPeerThreads));</span>
-<span class="source-line-no">1958</span><span id="line-1958">    final int replaySyncReplicationWALThreads =</span>
-<span class="source-line-no">1959</span><span id="line-1959">      conf.getInt("hbase.regionserver.executor.replay.sync.replication.wal.threads", 1);</span>
+<span class="source-line-no">1901</span><span id="line-1901">    this.walRoller = new LogRoller(this);</span>
+<span class="source-line-no">1902</span><span id="line-1902">    this.flushThroughputController = FlushThroughputControllerFactory.create(this, conf);</span>
+<span class="source-line-no">1903</span><span id="line-1903">    this.procedureResultReporter = new RemoteProcedureResultReporter(this);</span>
+<span class="source-line-no">1904</span><span id="line-1904"></span>
+<span class="source-line-no">1905</span><span id="line-1905">    // Create the CompactedFileDischarger chore executorService. This chore helps to</span>
+<span class="source-line-no">1906</span><span id="line-1906">    // remove the compacted files that will no longer be used in reads.</span>
+<span class="source-line-no">1907</span><span id="line-1907">    // Default is 2 mins. The default value for TTLCleaner is 5 mins so we set this to</span>
+<span class="source-line-no">1908</span><span id="line-1908">    // 2 mins so that compacted files can be archived before the TTLCleaner runs</span>
+<span class="source-line-no">1909</span><span id="line-1909">    int cleanerInterval = conf.getInt("hbase.hfile.compaction.discharger.interval", 2 * 60 * 1000);</span>
+<span class="source-line-no">1910</span><span id="line-1910">    this.compactedFileDischarger = new CompactedHFilesDischarger(cleanerInterval, this, this);</span>
+<span class="source-line-no">1911</span><span id="line-1911">    choreService.scheduleChore(compactedFileDischarger);</span>
+<span class="source-line-no">1912</span><span id="line-1912"></span>
+<span class="source-line-no">1913</span><span id="line-1913">    // Start executor services</span>
+<span class="source-line-no">1914</span><span id="line-1914">    final int openRegionThreads = conf.getInt("hbase.regionserver.executor.openregion.threads", 3);</span>
+<span class="source-line-no">1915</span><span id="line-1915">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1916</span><span id="line-1916">      .setExecutorType(ExecutorType.RS_OPEN_REGION).setCorePoolSize(openRegionThreads));</span>
+<span class="source-line-no">1917</span><span id="line-1917">    final int openMetaThreads = conf.getInt("hbase.regionserver.executor.openmeta.threads", 1);</span>
+<span class="source-line-no">1918</span><span id="line-1918">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1919</span><span id="line-1919">      .setExecutorType(ExecutorType.RS_OPEN_META).setCorePoolSize(openMetaThreads));</span>
+<span class="source-line-no">1920</span><span id="line-1920">    final int openPriorityRegionThreads =</span>
+<span class="source-line-no">1921</span><span id="line-1921">      conf.getInt("hbase.regionserver.executor.openpriorityregion.threads", 3);</span>
+<span class="source-line-no">1922</span><span id="line-1922">    executorService.startExecutorService(</span>
+<span class="source-line-no">1923</span><span id="line-1923">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_OPEN_PRIORITY_REGION)</span>
+<span class="source-line-no">1924</span><span id="line-1924">        .setCorePoolSize(openPriorityRegionThreads));</span>
+<span class="source-line-no">1925</span><span id="line-1925">    final int closeRegionThreads =</span>
+<span class="source-line-no">1926</span><span id="line-1926">      conf.getInt("hbase.regionserver.executor.closeregion.threads", 3);</span>
+<span class="source-line-no">1927</span><span id="line-1927">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1928</span><span id="line-1928">      .setExecutorType(ExecutorType.RS_CLOSE_REGION).setCorePoolSize(closeRegionThreads));</span>
+<span class="source-line-no">1929</span><span id="line-1929">    final int closeMetaThreads = conf.getInt("hbase.regionserver.executor.closemeta.threads", 1);</span>
+<span class="source-line-no">1930</span><span id="line-1930">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1931</span><span id="line-1931">      .setExecutorType(ExecutorType.RS_CLOSE_META).setCorePoolSize(closeMetaThreads));</span>
+<span class="source-line-no">1932</span><span id="line-1932">    if (conf.getBoolean(StoreScanner.STORESCANNER_PARALLEL_SEEK_ENABLE, false)) {</span>
+<span class="source-line-no">1933</span><span id="line-1933">      final int storeScannerParallelSeekThreads =</span>
+<span class="source-line-no">1934</span><span id="line-1934">        conf.getInt("hbase.storescanner.parallel.seek.threads", 10);</span>
+<span class="source-line-no">1935</span><span id="line-1935">      executorService.startExecutorService(</span>
+<span class="source-line-no">1936</span><span id="line-1936">        executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_PARALLEL_SEEK)</span>
+<span class="source-line-no">1937</span><span id="line-1937">          .setCorePoolSize(storeScannerParallelSeekThreads).setAllowCoreThreadTimeout(true));</span>
+<span class="source-line-no">1938</span><span id="line-1938">    }</span>
+<span class="source-line-no">1939</span><span id="line-1939">    final int logReplayOpsThreads =</span>
+<span class="source-line-no">1940</span><span id="line-1940">      conf.getInt(HBASE_SPLIT_WAL_MAX_SPLITTER, DEFAULT_HBASE_SPLIT_WAL_MAX_SPLITTER);</span>
+<span class="source-line-no">1941</span><span id="line-1941">    executorService.startExecutorService(</span>
+<span class="source-line-no">1942</span><span id="line-1942">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_LOG_REPLAY_OPS)</span>
+<span class="source-line-no">1943</span><span id="line-1943">        .setCorePoolSize(logReplayOpsThreads).setAllowCoreThreadTimeout(true));</span>
+<span class="source-line-no">1944</span><span id="line-1944">    // Start the threads for compacted files discharger</span>
+<span class="source-line-no">1945</span><span id="line-1945">    final int compactionDischargerThreads =</span>
+<span class="source-line-no">1946</span><span id="line-1946">      conf.getInt(CompactionConfiguration.HBASE_HFILE_COMPACTION_DISCHARGER_THREAD_COUNT, 10);</span>
+<span class="source-line-no">1947</span><span id="line-1947">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1948</span><span id="line-1948">      .setExecutorType(ExecutorType.RS_COMPACTED_FILES_DISCHARGER)</span>
+<span class="source-line-no">1949</span><span id="line-1949">      .setCorePoolSize(compactionDischargerThreads));</span>
+<span class="source-line-no">1950</span><span id="line-1950">    if (ServerRegionReplicaUtil.isRegionReplicaWaitForPrimaryFlushEnabled(conf)) {</span>
+<span class="source-line-no">1951</span><span id="line-1951">      final int regionReplicaFlushThreads =</span>
+<span class="source-line-no">1952</span><span id="line-1952">        conf.getInt("hbase.regionserver.region.replica.flusher.threads",</span>
+<span class="source-line-no">1953</span><span id="line-1953">          conf.getInt("hbase.regionserver.executor.openregion.threads", 3));</span>
+<span class="source-line-no">1954</span><span id="line-1954">      executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1955</span><span id="line-1955">        .setExecutorType(ExecutorType.RS_REGION_REPLICA_FLUSH_OPS)</span>
+<span class="source-line-no">1956</span><span id="line-1956">        .setCorePoolSize(regionReplicaFlushThreads));</span>
+<span class="source-line-no">1957</span><span id="line-1957">    }</span>
+<span class="source-line-no">1958</span><span id="line-1958">    final int refreshPeerThreads =</span>
+<span class="source-line-no">1959</span><span id="line-1959">      conf.getInt("hbase.regionserver.executor.refresh.peer.threads", 2);</span>
 <span class="source-line-no">1960</span><span id="line-1960">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1961</span><span id="line-1961">      .setExecutorType(ExecutorType.RS_REPLAY_SYNC_REPLICATION_WAL)</span>
-<span class="source-line-no">1962</span><span id="line-1962">      .setCorePoolSize(replaySyncReplicationWALThreads));</span>
-<span class="source-line-no">1963</span><span id="line-1963">    final int switchRpcThrottleThreads =</span>
-<span class="source-line-no">1964</span><span id="line-1964">      conf.getInt("hbase.regionserver.executor.switch.rpc.throttle.threads", 1);</span>
-<span class="source-line-no">1965</span><span id="line-1965">    executorService.startExecutorService(</span>
-<span class="source-line-no">1966</span><span id="line-1966">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_SWITCH_RPC_THROTTLE)</span>
-<span class="source-line-no">1967</span><span id="line-1967">        .setCorePoolSize(switchRpcThrottleThreads));</span>
-<span class="source-line-no">1968</span><span id="line-1968">    final int claimReplicationQueueThreads =</span>
-<span class="source-line-no">1969</span><span id="line-1969">      conf.getInt("hbase.regionserver.executor.claim.replication.queue.threads", 1);</span>
-<span class="source-line-no">1970</span><span id="line-1970">    executorService.startExecutorService(</span>
-<span class="source-line-no">1971</span><span id="line-1971">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_CLAIM_REPLICATION_QUEUE)</span>
-<span class="source-line-no">1972</span><span id="line-1972">        .setCorePoolSize(claimReplicationQueueThreads));</span>
-<span class="source-line-no">1973</span><span id="line-1973">    final int rsSnapshotOperationThreads =</span>
-<span class="source-line-no">1974</span><span id="line-1974">      conf.getInt("hbase.regionserver.executor.snapshot.operations.threads", 3);</span>
-<span class="source-line-no">1975</span><span id="line-1975">    executorService.startExecutorService(</span>
-<span class="source-line-no">1976</span><span id="line-1976">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_SNAPSHOT_OPERATIONS)</span>
-<span class="source-line-no">1977</span><span id="line-1977">        .setCorePoolSize(rsSnapshotOperationThreads));</span>
-<span class="source-line-no">1978</span><span id="line-1978">    final int rsFlushOperationThreads =</span>
-<span class="source-line-no">1979</span><span id="line-1979">      conf.getInt("hbase.regionserver.executor.flush.operations.threads", 3);</span>
-<span class="source-line-no">1980</span><span id="line-1980">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1981</span><span id="line-1981">      .setExecutorType(ExecutorType.RS_FLUSH_OPERATIONS).setCorePoolSize(rsFlushOperationThreads));</span>
-<span class="source-line-no">1982</span><span id="line-1982">    final int rsRefreshQuotasThreads =</span>
-<span class="source-line-no">1983</span><span id="line-1983">      conf.getInt("hbase.regionserver.executor.refresh.quotas.threads", 1);</span>
-<span class="source-line-no">1984</span><span id="line-1984">    executorService.startExecutorService(</span>
-<span class="source-line-no">1985</span><span id="line-1985">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_RELOAD_QUOTAS_OPERATIONS)</span>
-<span class="source-line-no">1986</span><span id="line-1986">        .setCorePoolSize(rsRefreshQuotasThreads));</span>
-<span class="source-line-no">1987</span><span id="line-1987">    final int logRollThreads = conf.getInt("hbase.regionserver.executor.log.roll.threads", 1);</span>
-<span class="source-line-no">1988</span><span id="line-1988">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1989</span><span id="line-1989">      .setExecutorType(ExecutorType.RS_LOG_ROLL).setCorePoolSize(logRollThreads));</span>
-<span class="source-line-no">1990</span><span id="line-1990">    final int rsRefreshHFilesThreads =</span>
-<span class="source-line-no">1991</span><span id="line-1991">      conf.getInt("hbase.regionserver.executor.refresh.hfiles.threads", 3);</span>
+<span class="source-line-no">1961</span><span id="line-1961">      .setExecutorType(ExecutorType.RS_REFRESH_PEER).setCorePoolSize(refreshPeerThreads));</span>
+<span class="source-line-no">1962</span><span id="line-1962">    final int replaySyncReplicationWALThreads =</span>
+<span class="source-line-no">1963</span><span id="line-1963">      conf.getInt("hbase.regionserver.executor.replay.sync.replication.wal.threads", 1);</span>
+<span class="source-line-no">1964</span><span id="line-1964">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1965</span><span id="line-1965">      .setExecutorType(ExecutorType.RS_REPLAY_SYNC_REPLICATION_WAL)</span>
+<span class="source-line-no">1966</span><span id="line-1966">      .setCorePoolSize(replaySyncReplicationWALThreads));</span>
+<span class="source-line-no">1967</span><span id="line-1967">    final int switchRpcThrottleThreads =</span>
+<span class="source-line-no">1968</span><span id="line-1968">      conf.getInt("hbase.regionserver.executor.switch.rpc.throttle.threads", 1);</span>
+<span class="source-line-no">1969</span><span id="line-1969">    executorService.startExecutorService(</span>
+<span class="source-line-no">1970</span><span id="line-1970">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_SWITCH_RPC_THROTTLE)</span>
+<span class="source-line-no">1971</span><span id="line-1971">        .setCorePoolSize(switchRpcThrottleThreads));</span>
+<span class="source-line-no">1972</span><span id="line-1972">    final int claimReplicationQueueThreads =</span>
+<span class="source-line-no">1973</span><span id="line-1973">      conf.getInt("hbase.regionserver.executor.claim.replication.queue.threads", 1);</span>
+<span class="source-line-no">1974</span><span id="line-1974">    executorService.startExecutorService(</span>
+<span class="source-line-no">1975</span><span id="line-1975">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_CLAIM_REPLICATION_QUEUE)</span>
+<span class="source-line-no">1976</span><span id="line-1976">        .setCorePoolSize(claimReplicationQueueThreads));</span>
+<span class="source-line-no">1977</span><span id="line-1977">    final int rsSnapshotOperationThreads =</span>
+<span class="source-line-no">1978</span><span id="line-1978">      conf.getInt("hbase.regionserver.executor.snapshot.operations.threads", 3);</span>
+<span class="source-line-no">1979</span><span id="line-1979">    executorService.startExecutorService(</span>
+<span class="source-line-no">1980</span><span id="line-1980">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_SNAPSHOT_OPERATIONS)</span>
+<span class="source-line-no">1981</span><span id="line-1981">        .setCorePoolSize(rsSnapshotOperationThreads));</span>
+<span class="source-line-no">1982</span><span id="line-1982">    final int rsFlushOperationThreads =</span>
+<span class="source-line-no">1983</span><span id="line-1983">      conf.getInt("hbase.regionserver.executor.flush.operations.threads", 3);</span>
+<span class="source-line-no">1984</span><span id="line-1984">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1985</span><span id="line-1985">      .setExecutorType(ExecutorType.RS_FLUSH_OPERATIONS).setCorePoolSize(rsFlushOperationThreads));</span>
+<span class="source-line-no">1986</span><span id="line-1986">    final int rsRefreshQuotasThreads =</span>
+<span class="source-line-no">1987</span><span id="line-1987">      conf.getInt("hbase.regionserver.executor.refresh.quotas.threads", 1);</span>
+<span class="source-line-no">1988</span><span id="line-1988">    executorService.startExecutorService(</span>
+<span class="source-line-no">1989</span><span id="line-1989">      executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_RELOAD_QUOTAS_OPERATIONS)</span>
+<span class="source-line-no">1990</span><span id="line-1990">        .setCorePoolSize(rsRefreshQuotasThreads));</span>
+<span class="source-line-no">1991</span><span id="line-1991">    final int logRollThreads = conf.getInt("hbase.regionserver.executor.log.roll.threads", 1);</span>
 <span class="source-line-no">1992</span><span id="line-1992">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1993</span><span id="line-1993">      .setExecutorType(ExecutorType.RS_REFRESH_HFILES).setCorePoolSize(rsRefreshHFilesThreads));</span>
-<span class="source-line-no">1994</span><span id="line-1994"></span>
-<span class="source-line-no">1995</span><span id="line-1995">    Threads.setDaemonThreadRunning(this.walRoller, getName() + ".logRoller",</span>
-<span class="source-line-no">1996</span><span id="line-1996">      uncaughtExceptionHandler);</span>
-<span class="source-line-no">1997</span><span id="line-1997">    if (this.cacheFlusher != null) {</span>
-<span class="source-line-no">1998</span><span id="line-1998">      this.cacheFlusher.start(uncaughtExceptionHandler);</span>
-<span class="source-line-no">1999</span><span id="line-1999">    }</span>
-<span class="source-line-no">2000</span><span id="line-2000">    Threads.setDaemonThreadRunning(this.procedureResultReporter,</span>
-<span class="source-line-no">2001</span><span id="line-2001">      getName() + ".procedureResultReporter", uncaughtExceptionHandler);</span>
-<span class="source-line-no">2002</span><span id="line-2002"></span>
-<span class="source-line-no">2003</span><span id="line-2003">    if (this.compactionChecker != null) {</span>
-<span class="source-line-no">2004</span><span id="line-2004">      choreService.scheduleChore(compactionChecker);</span>
-<span class="source-line-no">2005</span><span id="line-2005">    }</span>
-<span class="source-line-no">2006</span><span id="line-2006">    if (this.periodicFlusher != null) {</span>
-<span class="source-line-no">2007</span><span id="line-2007">      choreService.scheduleChore(periodicFlusher);</span>
-<span class="source-line-no">2008</span><span id="line-2008">    }</span>
-<span class="source-line-no">2009</span><span id="line-2009">    if (this.healthCheckChore != null) {</span>
-<span class="source-line-no">2010</span><span id="line-2010">      choreService.scheduleChore(healthCheckChore);</span>
-<span class="source-line-no">2011</span><span id="line-2011">    }</span>
-<span class="source-line-no">2012</span><span id="line-2012">    if (this.executorStatusChore != null) {</span>
-<span class="source-line-no">2013</span><span id="line-2013">      choreService.scheduleChore(executorStatusChore);</span>
-<span class="source-line-no">2014</span><span id="line-2014">    }</span>
-<span class="source-line-no">2015</span><span id="line-2015">    if (this.nonceManagerChore != null) {</span>
-<span class="source-line-no">2016</span><span id="line-2016">      choreService.scheduleChore(nonceManagerChore);</span>
-<span class="source-line-no">2017</span><span id="line-2017">    }</span>
-<span class="source-line-no">2018</span><span id="line-2018">    if (this.storefileRefresher != null) {</span>
-<span class="source-line-no">2019</span><span id="line-2019">      choreService.scheduleChore(storefileRefresher);</span>
-<span class="source-line-no">2020</span><span id="line-2020">    }</span>
-<span class="source-line-no">2021</span><span id="line-2021">    if (this.fsUtilizationChore != null) {</span>
-<span class="source-line-no">2022</span><span id="line-2022">      choreService.scheduleChore(fsUtilizationChore);</span>
-<span class="source-line-no">2023</span><span id="line-2023">    }</span>
-<span class="source-line-no">2024</span><span id="line-2024">    if (this.namedQueueServiceChore != null) {</span>
-<span class="source-line-no">2025</span><span id="line-2025">      choreService.scheduleChore(namedQueueServiceChore);</span>
-<span class="source-line-no">2026</span><span id="line-2026">    }</span>
-<span class="source-line-no">2027</span><span id="line-2027">    if (this.brokenStoreFileCleaner != null) {</span>
-<span class="source-line-no">2028</span><span id="line-2028">      choreService.scheduleChore(brokenStoreFileCleaner);</span>
-<span class="source-line-no">2029</span><span id="line-2029">    }</span>
-<span class="source-line-no">2030</span><span id="line-2030">    if (this.rsMobFileCleanerChore != null) {</span>
-<span class="source-line-no">2031</span><span id="line-2031">      choreService.scheduleChore(rsMobFileCleanerChore);</span>
-<span class="source-line-no">2032</span><span id="line-2032">    }</span>
-<span class="source-line-no">2033</span><span id="line-2033">    if (replicationMarkerChore != null) {</span>
-<span class="source-line-no">2034</span><span id="line-2034">      LOG.info("Starting replication marker chore");</span>
-<span class="source-line-no">2035</span><span id="line-2035">      choreService.scheduleChore(replicationMarkerChore);</span>
+<span class="source-line-no">1993</span><span id="line-1993">      .setExecutorType(ExecutorType.RS_LOG_ROLL).setCorePoolSize(logRollThreads));</span>
+<span class="source-line-no">1994</span><span id="line-1994">    final int rsRefreshHFilesThreads =</span>
+<span class="source-line-no">1995</span><span id="line-1995">      conf.getInt("hbase.regionserver.executor.refresh.hfiles.threads", 3);</span>
+<span class="source-line-no">1996</span><span id="line-1996">    executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1997</span><span id="line-1997">      .setExecutorType(ExecutorType.RS_REFRESH_HFILES).setCorePoolSize(rsRefreshHFilesThreads));</span>
+<span class="source-line-no">1998</span><span id="line-1998"></span>
+<span class="source-line-no">1999</span><span id="line-1999">    Threads.setDaemonThreadRunning(this.walRoller, getName() + ".logRoller",</span>
+<span class="source-line-no">2000</span><span id="line-2000">      uncaughtExceptionHandler);</span>
+<span class="source-line-no">2001</span><span id="line-2001">    if (this.cacheFlusher != null) {</span>
+<span class="source-line-no">2002</span><span id="line-2002">      this.cacheFlusher.start(uncaughtExceptionHandler);</span>
+<span class="source-line-no">2003</span><span id="line-2003">    }</span>
+<span class="source-line-no">2004</span><span id="line-2004">    Threads.setDaemonThreadRunning(this.procedureResultReporter,</span>
+<span class="source-line-no">2005</span><span id="line-2005">      getName() + ".procedureResultReporter", uncaughtExceptionHandler);</span>
+<span class="source-line-no">2006</span><span id="line-2006"></span>
+<span class="source-line-no">2007</span><span id="line-2007">    if (this.compactionChecker != null) {</span>
+<span class="source-line-no">2008</span><span id="line-2008">      choreService.scheduleChore(compactionChecker);</span>
+<span class="source-line-no">2009</span><span id="line-2009">    }</span>
+<span class="source-line-no">2010</span><span id="line-2010">    if (this.periodicFlusher != null) {</span>
+<span class="source-line-no">2011</span><span id="line-2011">      choreService.scheduleChore(periodicFlusher);</span>
+<span class="source-line-no">2012</span><span id="line-2012">    }</span>
+<span class="source-line-no">2013</span><span id="line-2013">    if (this.healthCheckChore != null) {</span>
+<span class="source-line-no">2014</span><span id="line-2014">      choreService.scheduleChore(healthCheckChore);</span>
+<span class="source-line-no">2015</span><span id="line-2015">    }</span>
+<span class="source-line-no">2016</span><span id="line-2016">    if (this.executorStatusChore != null) {</span>
+<span class="source-line-no">2017</span><span id="line-2017">      choreService.scheduleChore(executorStatusChore);</span>
+<span class="source-line-no">2018</span><span id="line-2018">    }</span>
+<span class="source-line-no">2019</span><span id="line-2019">    if (this.nonceManagerChore != null) {</span>
+<span class="source-line-no">2020</span><span id="line-2020">      choreService.scheduleChore(nonceManagerChore);</span>
+<span class="source-line-no">2021</span><span id="line-2021">    }</span>
+<span class="source-line-no">2022</span><span id="line-2022">    if (this.storefileRefresher != null) {</span>
+<span class="source-line-no">2023</span><span id="line-2023">      choreService.scheduleChore(storefileRefresher);</span>
+<span class="source-line-no">2024</span><span id="line-2024">    }</span>
+<span class="source-line-no">2025</span><span id="line-2025">    if (this.fsUtilizationChore != null) {</span>
+<span class="source-line-no">2026</span><span id="line-2026">      choreService.scheduleChore(fsUtilizationChore);</span>
+<span class="source-line-no">2027</span><span id="line-2027">    }</span>
+<span class="source-line-no">2028</span><span id="line-2028">    if (this.namedQueueServiceChore != null) {</span>
+<span class="source-line-no">2029</span><span id="line-2029">      choreService.scheduleChore(namedQueueServiceChore);</span>
+<span class="source-line-no">2030</span><span id="line-2030">    }</span>
+<span class="source-line-no">2031</span><span id="line-2031">    if (this.brokenStoreFileCleaner != null) {</span>
+<span class="source-line-no">2032</span><span id="line-2032">      choreService.scheduleChore(brokenStoreFileCleaner);</span>
+<span class="source-line-no">2033</span><span id="line-2033">    }</span>
+<span class="source-line-no">2034</span><span id="line-2034">    if (this.rsMobFileCleanerChore != null) {</span>
+<span class="source-line-no">2035</span><span id="line-2035">      choreService.scheduleChore(rsMobFileCleanerChore);</span>
 <span class="source-line-no">2036</span><span id="line-2036">    }</span>
-<span class="source-line-no">2037</span><span id="line-2037"></span>
-<span class="source-line-no">2038</span><span id="line-2038">    // Leases is not a Thread. Internally it runs a daemon thread. If it gets</span>
-<span class="source-line-no">2039</span><span id="line-2039">    // an unhandled exception, it will just exit.</span>
-<span class="source-line-no">2040</span><span id="line-2040">    Threads.setDaemonThreadRunning(this.leaseManager, getName() + ".leaseChecker",</span>
-<span class="source-line-no">2041</span><span id="line-2041">      uncaughtExceptionHandler);</span>
-<span class="source-line-no">2042</span><span id="line-2042"></span>
-<span class="source-line-no">2043</span><span id="line-2043">    // Create the log splitting worker and start it</span>
-<span class="source-line-no">2044</span><span id="line-2044">    // set a smaller retries to fast fail otherwise splitlogworker could be blocked for</span>
-<span class="source-line-no">2045</span><span id="line-2045">    // quite a while inside Connection layer. The worker won't be available for other</span>
-<span class="source-line-no">2046</span><span id="line-2046">    // tasks even after current task is preempted after a split task times out.</span>
-<span class="source-line-no">2047</span><span id="line-2047">    Configuration sinkConf = HBaseConfiguration.create(conf);</span>
-<span class="source-line-no">2048</span><span id="line-2048">    sinkConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,</span>
-<span class="source-line-no">2049</span><span id="line-2049">      conf.getInt("hbase.log.replay.retries.number", 8)); // 8 retries take about 23 seconds</span>
-<span class="source-line-no">2050</span><span id="line-2050">    sinkConf.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY,</span>
-<span class="source-line-no">2051</span><span id="line-2051">      conf.getInt("hbase.log.replay.rpc.timeout", 30000)); // default 30 seconds</span>
-<span class="source-line-no">2052</span><span id="line-2052">    sinkConf.setInt(HConstants.HBASE_CLIENT_SERVERSIDE_RETRIES_MULTIPLIER, 1);</span>
-<span class="source-line-no">2053</span><span id="line-2053">    if (</span>
-<span class="source-line-no">2054</span><span id="line-2054">      this.csm != null</span>
-<span class="source-line-no">2055</span><span id="line-2055">        &amp;&amp; conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK)</span>
-<span class="source-line-no">2056</span><span id="line-2056">    ) {</span>
-<span class="source-line-no">2057</span><span id="line-2057">      // SplitLogWorker needs csm. If none, don't start this.</span>
-<span class="source-line-no">2058</span><span id="line-2058">      this.splitLogWorker = new SplitLogWorker(sinkConf, this, this, walFactory);</span>
-<span class="source-line-no">2059</span><span id="line-2059">      splitLogWorker.start();</span>
-<span class="source-line-no">2060</span><span id="line-2060">      LOG.debug("SplitLogWorker started");</span>
-<span class="source-line-no">2061</span><span id="line-2061">    }</span>
-<span class="source-line-no">2062</span><span id="line-2062"></span>
-<span class="source-line-no">2063</span><span id="line-2063">    // Memstore services.</span>
-<span class="source-line-no">2064</span><span id="line-2064">    startHeapMemoryManager();</span>
-<span class="source-line-no">2065</span><span id="line-2065">    // Call it after starting HeapMemoryManager.</span>
-<span class="source-line-no">2066</span><span id="line-2066">    initializeMemStoreChunkCreator(hMemManager);</span>
-<span class="source-line-no">2067</span><span id="line-2067">  }</span>
-<span class="source-line-no">2068</span><span id="line-2068"></span>
-<span class="source-line-no">2069</span><span id="line-2069">  private void initializeThreads() {</span>
-<span class="source-line-no">2070</span><span id="line-2070">    // Cache flushing thread.</span>
-<span class="source-line-no">2071</span><span id="line-2071">    this.cacheFlusher = new MemStoreFlusher(conf, this);</span>
+<span class="source-line-no">2037</span><span id="line-2037">    if (replicationMarkerChore != null) {</span>
+<span class="source-line-no">2038</span><span id="line-2038">      LOG.info("Starting replication marker chore");</span>
+<span class="source-line-no">2039</span><span id="line-2039">      choreService.scheduleChore(replicationMarkerChore);</span>
+<span class="source-line-no">2040</span><span id="line-2040">    }</span>
+<span class="source-line-no">2041</span><span id="line-2041"></span>
+<span class="source-line-no">2042</span><span id="line-2042">    // Leases is not a Thread. Internally it runs a daemon thread. If it gets</span>
+<span class="source-line-no">2043</span><span id="line-2043">    // an unhandled exception, it will just exit.</span>
+<span class="source-line-no">2044</span><span id="line-2044">    Threads.setDaemonThreadRunning(this.leaseManager, getName() + ".leaseChecker",</span>
+<span class="source-line-no">2045</span><span id="line-2045">      uncaughtExceptionHandler);</span>
+<span class="source-line-no">2046</span><span id="line-2046"></span>
+<span class="source-line-no">2047</span><span id="line-2047">    // Create the log splitting worker and start it</span>
+<span class="source-line-no">2048</span><span id="line-2048">    // set a smaller retries to fast fail otherwise splitlogworker could be blocked for</span>
+<span class="source-line-no">2049</span><span id="line-2049">    // quite a while inside Connection layer. The worker won't be available for other</span>
+<span class="source-line-no">2050</span><span id="line-2050">    // tasks even after current task is preempted after a split task times out.</span>
+<span class="source-line-no">2051</span><span id="line-2051">    Configuration sinkConf = HBaseConfiguration.create(conf);</span>
+<span class="source-line-no">2052</span><span id="line-2052">    sinkConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,</span>
+<span class="source-line-no">2053</span><span id="line-2053">      conf.getInt("hbase.log.replay.retries.number", 8)); // 8 retries take about 23 seconds</span>
+<span class="source-line-no">2054</span><span id="line-2054">    sinkConf.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY,</span>
+<span class="source-line-no">2055</span><span id="line-2055">      conf.getInt("hbase.log.replay.rpc.timeout", 30000)); // default 30 seconds</span>
+<span class="source-line-no">2056</span><span id="line-2056">    sinkConf.setInt(HConstants.HBASE_CLIENT_SERVERSIDE_RETRIES_MULTIPLIER, 1);</span>
+<span class="source-line-no">2057</span><span id="line-2057">    if (</span>
+<span class="source-line-no">2058</span><span id="line-2058">      this.csm != null</span>
+<span class="source-line-no">2059</span><span id="line-2059">        &amp;&amp; conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK)</span>
+<span class="source-line-no">2060</span><span id="line-2060">    ) {</span>
+<span class="source-line-no">2061</span><span id="line-2061">      // SplitLogWorker needs csm. If none, don't start this.</span>
+<span class="source-line-no">2062</span><span id="line-2062">      this.splitLogWorker = new SplitLogWorker(sinkConf, this, this, walFactory);</span>
+<span class="source-line-no">2063</span><span id="line-2063">      splitLogWorker.start();</span>
+<span class="source-line-no">2064</span><span id="line-2064">      LOG.debug("SplitLogWorker started");</span>
+<span class="source-line-no">2065</span><span id="line-2065">    }</span>
+<span class="source-line-no">2066</span><span id="line-2066"></span>
+<span class="source-line-no">2067</span><span id="line-2067">    // Memstore services.</span>
+<span class="source-line-no">2068</span><span id="line-2068">    startHeapMemoryManager();</span>
+<span class="source-line-no">2069</span><span id="line-2069">    // Call it after starting HeapMemoryManager.</span>
+<span class="source-line-no">2070</span><span id="line-2070">    initializeMemStoreChunkCreator(hMemManager);</span>
+<span class="source-line-no">2071</span><span id="line-2071">  }</span>
 <span class="source-line-no">2072</span><span id="line-2072"></span>
-<span class="source-line-no">2073</span><span id="line-2073">    // Compaction thread</span>
-<span class="source-line-no">2074</span><span id="line-2074">    this.compactSplitThread = new CompactSplit(this);</span>
-<span class="source-line-no">2075</span><span id="line-2075"></span>
-<span class="source-line-no">2076</span><span id="line-2076">    // Prefetch Notifier</span>
-<span class="source-line-no">2077</span><span id="line-2077">    this.prefetchExecutorNotifier = new PrefetchExecutorNotifier(conf);</span>
-<span class="source-line-no">2078</span><span id="line-2078"></span>
-<span class="source-line-no">2079</span><span id="line-2079">    // Background thread to check for compactions; needed if region has not gotten updates</span>
-<span class="source-line-no">2080</span><span id="line-2080">    // in a while. It will take care of not checking too frequently on store-by-store basis.</span>
-<span class="source-line-no">2081</span><span id="line-2081">    this.compactionChecker = new CompactionChecker(this, this.compactionCheckFrequency, this);</span>
-<span class="source-line-no">2082</span><span id="line-2082">    this.periodicFlusher = new PeriodicMemStoreFlusher(this.flushCheckFrequency, this);</span>
-<span class="source-line-no">2083</span><span id="line-2083">    this.leaseManager = new LeaseManager(this.threadWakeFrequency);</span>
-<span class="source-line-no">2084</span><span id="line-2084"></span>
-<span class="source-line-no">2085</span><span id="line-2085">    final boolean isSlowLogTableEnabled = conf.getBoolean(HConstants.SLOW_LOG_SYS_TABLE_ENABLED_KEY,</span>
-<span class="source-line-no">2086</span><span id="line-2086">      HConstants.DEFAULT_SLOW_LOG_SYS_TABLE_ENABLED_KEY);</span>
-<span class="source-line-no">2087</span><span id="line-2087">    final boolean walEventTrackerEnabled =</span>
-<span class="source-line-no">2088</span><span id="line-2088">      conf.getBoolean(WAL_EVENT_TRACKER_ENABLED_KEY, WAL_EVENT_TRACKER_ENABLED_DEFAULT);</span>
-<span class="source-line-no">2089</span><span id="line-2089"></span>
-<span class="source-line-no">2090</span><span id="line-2090">    if (isSlowLogTableEnabled || walEventTrackerEnabled) {</span>
-<span class="source-line-no">2091</span><span id="line-2091">      // default chore duration: 10 min</span>
-<span class="source-line-no">2092</span><span id="line-2092">      // After &lt;version number&gt;, we will remove hbase.slowlog.systable.chore.duration conf property</span>
-<span class="source-line-no">2093</span><span id="line-2093">      final int slowLogChoreDuration = conf.getInt(HConstants.SLOW_LOG_SYS_TABLE_CHORE_DURATION_KEY,</span>
-<span class="source-line-no">2094</span><span id="line-2094">        DEFAULT_SLOW_LOG_SYS_TABLE_CHORE_DURATION);</span>
-<span class="source-line-no">2095</span><span id="line-2095"></span>
-<span class="source-line-no">2096</span><span id="line-2096">      final int namedQueueChoreDuration =</span>
-<span class="source-line-no">2097</span><span id="line-2097">        conf.getInt(NAMED_QUEUE_CHORE_DURATION_KEY, NAMED_QUEUE_CHORE_DURATION_DEFAULT);</span>
-<span class="source-line-no">2098</span><span id="line-2098">      // Considering min of slowLogChoreDuration and namedQueueChoreDuration</span>
-<span class="source-line-no">2099</span><span id="line-2099">      int choreDuration = Math.min(slowLogChoreDuration, namedQueueChoreDuration);</span>
-<span class="source-line-no">2100</span><span id="line-2100"></span>
-<span class="source-line-no">2101</span><span id="line-2101">      namedQueueServiceChore = new NamedQueueServiceChore(this, choreDuration,</span>
-<span class="source-line-no">2102</span><span id="line-2102">        this.namedQueueRecorder, this.getConnection());</span>
-<span class="source-line-no">2103</span><span id="line-2103">    }</span>
+<span class="source-line-no">2073</span><span id="line-2073">  private void initializeThreads() {</span>
+<span class="source-line-no">2074</span><span id="line-2074">    // Cache flushing thread.</span>
+<span class="source-line-no">2075</span><span id="line-2075">    this.cacheFlusher = new MemStoreFlusher(conf, this);</span>
+<span class="source-line-no">2076</span><span id="line-2076"></span>
+<span class="source-line-no">2077</span><span id="line-2077">    // Compaction thread</span>
+<span class="source-line-no">2078</span><span id="line-2078">    this.compactSplitThread = new CompactSplit(this);</span>
+<span class="source-line-no">2079</span><span id="line-2079"></span>
+<span class="source-line-no">2080</span><span id="line-2080">    // Prefetch Notifier</span>
+<span class="source-line-no">2081</span><span id="line-2081">    this.prefetchExecutorNotifier = new PrefetchExecutorNotifier(conf);</span>
+<span class="source-line-no">2082</span><span id="line-2082"></span>
+<span class="source-line-no">2083</span><span id="line-2083">    // Background thread to check for compactions; needed if region has not gotten updates</span>
+<span class="source-line-no">2084</span><span id="line-2084">    // in a while. It will take care of not checking too frequently on store-by-store basis.</span>
+<span class="source-line-no">2085</span><span id="line-2085">    this.compactionChecker = new CompactionChecker(this, this.compactionCheckFrequency, this);</span>
+<span class="source-line-no">2086</span><span id="line-2086">    this.periodicFlusher = new PeriodicMemStoreFlusher(this.flushCheckFrequency, this);</span>
+<span class="source-line-no">2087</span><span id="line-2087">    this.leaseManager = new LeaseManager(this.threadWakeFrequency);</span>
+<span class="source-line-no">2088</span><span id="line-2088"></span>
+<span class="source-line-no">2089</span><span id="line-2089">    final boolean isSlowLogTableEnabled = conf.getBoolean(HConstants.SLOW_LOG_SYS_TABLE_ENABLED_KEY,</span>
+<span class="source-line-no">2090</span><span id="line-2090">      HConstants.DEFAULT_SLOW_LOG_SYS_TABLE_ENABLED_KEY);</span>
+<span class="source-line-no">2091</span><span id="line-2091">    final boolean walEventTrackerEnabled =</span>
+<span class="source-line-no">2092</span><span id="line-2092">      conf.getBoolean(WAL_EVENT_TRACKER_ENABLED_KEY, WAL_EVENT_TRACKER_ENABLED_DEFAULT);</span>
+<span class="source-line-no">2093</span><span id="line-2093"></span>
+<span class="source-line-no">2094</span><span id="line-2094">    if (isSlowLogTableEnabled || walEventTrackerEnabled) {</span>
+<span class="source-line-no">2095</span><span id="line-2095">      // default chore duration: 10 min</span>
+<span class="source-line-no">2096</span><span id="line-2096">      // After &lt;version number&gt;, we will remove hbase.slowlog.systable.chore.duration conf property</span>
+<span class="source-line-no">2097</span><span id="line-2097">      final int slowLogChoreDuration = conf.getInt(HConstants.SLOW_LOG_SYS_TABLE_CHORE_DURATION_KEY,</span>
+<span class="source-line-no">2098</span><span id="line-2098">        DEFAULT_SLOW_LOG_SYS_TABLE_CHORE_DURATION);</span>
+<span class="source-line-no">2099</span><span id="line-2099"></span>
+<span class="source-line-no">2100</span><span id="line-2100">      final int namedQueueChoreDuration =</span>
+<span class="source-line-no">2101</span><span id="line-2101">        conf.getInt(NAMED_QUEUE_CHORE_DURATION_KEY, NAMED_QUEUE_CHORE_DURATION_DEFAULT);</span>
+<span class="source-line-no">2102</span><span id="line-2102">      // Considering min of slowLogChoreDuration and namedQueueChoreDuration</span>
+<span class="source-line-no">2103</span><span id="line-2103">      int choreDuration = Math.min(slowLogChoreDuration, namedQueueChoreDuration);</span>
 <span class="source-line-no">2104</span><span id="line-2104"></span>
-<span class="source-line-no">2105</span><span id="line-2105">    if (this.nonceManager != null) {</span>
-<span class="source-line-no">2106</span><span id="line-2106">      // Create the scheduled chore that cleans up nonces.</span>
-<span class="source-line-no">2107</span><span id="line-2107">      nonceManagerChore = this.nonceManager.createCleanupScheduledChore(this);</span>
-<span class="source-line-no">2108</span><span id="line-2108">    }</span>
-<span class="source-line-no">2109</span><span id="line-2109"></span>
-<span class="source-line-no">2110</span><span id="line-2110">    // Setup the Quota Manager</span>
-<span class="source-line-no">2111</span><span id="line-2111">    rsQuotaManager = new RegionServerRpcQuotaManager(this);</span>
-<span class="source-line-no">2112</span><span id="line-2112">    configurationManager.registerObserver(rsQuotaManager);</span>
-<span class="source-line-no">2113</span><span id="line-2113">    rsSpaceQuotaManager = new RegionServerSpaceQuotaManager(this);</span>
-<span class="source-line-no">2114</span><span id="line-2114"></span>
-<span class="source-line-no">2115</span><span id="line-2115">    if (QuotaUtil.isQuotaEnabled(conf)) {</span>
-<span class="source-line-no">2116</span><span id="line-2116">      this.fsUtilizationChore = new FileSystemUtilizationChore(this);</span>
-<span class="source-line-no">2117</span><span id="line-2117">    }</span>
+<span class="source-line-no">2105</span><span id="line-2105">      namedQueueServiceChore = new NamedQueueServiceChore(this, choreDuration,</span>
+<span class="source-line-no">2106</span><span id="line-2106">        this.namedQueueRecorder, this.getConnection());</span>
+<span class="source-line-no">2107</span><span id="line-2107">    }</span>
+<span class="source-line-no">2108</span><span id="line-2108"></span>
+<span class="source-line-no">2109</span><span id="line-2109">    if (this.nonceManager != null) {</span>
+<span class="source-line-no">2110</span><span id="line-2110">      // Create the scheduled chore that cleans up nonces.</span>
+<span class="source-line-no">2111</span><span id="line-2111">      nonceManagerChore = this.nonceManager.createCleanupScheduledChore(this);</span>
+<span class="source-line-no">2112</span><span id="line-2112">    }</span>
+<span class="source-line-no">2113</span><span id="line-2113"></span>
+<span class="source-line-no">2114</span><span id="line-2114">    // Setup the Quota Manager</span>
+<span class="source-line-no">2115</span><span id="line-2115">    rsQuotaManager = new RegionServerRpcQuotaManager(this);</span>
+<span class="source-line-no">2116</span><span id="line-2116">    configurationManager.registerObserver(rsQuotaManager);</span>
+<span class="source-line-no">2117</span><span id="line-2117">    rsSpaceQuotaManager = new RegionServerSpaceQuotaManager(this);</span>
 <span class="source-line-no">2118</span><span id="line-2118"></span>
-<span class="source-line-no">2119</span><span id="line-2119">    boolean onlyMetaRefresh = false;</span>
-<span class="source-line-no">2120</span><span id="line-2120">    int storefileRefreshPeriod =</span>
-<span class="source-line-no">2121</span><span id="line-2121">      conf.getInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD,</span>
-<span class="source-line-no">2122</span><span id="line-2122">        StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);</span>
-<span class="source-line-no">2123</span><span id="line-2123">    if (storefileRefreshPeriod == 0) {</span>
-<span class="source-line-no">2124</span><span id="line-2124">      storefileRefreshPeriod =</span>
-<span class="source-line-no">2125</span><span id="line-2125">        conf.getInt(StorefileRefresherChore.REGIONSERVER_META_STOREFILE_REFRESH_PERIOD,</span>
-<span class="source-line-no">2126</span><span id="line-2126">          StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);</span>
-<span class="source-line-no">2127</span><span id="line-2127">      onlyMetaRefresh = true;</span>
-<span class="source-line-no">2128</span><span id="line-2128">    }</span>
-<span class="source-line-no">2129</span><span id="line-2129">    if (storefileRefreshPeriod &gt; 0) {</span>
-<span class="source-line-no">2130</span><span id="line-2130">      this.storefileRefresher =</span>
-<span class="source-line-no">2131</span><span id="line-2131">        new StorefileRefresherChore(storefileRefreshPeriod, onlyMetaRefresh, this, this);</span>
+<span class="source-line-no">2119</span><span id="line-2119">    if (QuotaUtil.isQuotaEnabled(conf)) {</span>
+<span class="source-line-no">2120</span><span id="line-2120">      this.fsUtilizationChore = new FileSystemUtilizationChore(this);</span>
+<span class="source-line-no">2121</span><span id="line-2121">    }</span>
+<span class="source-line-no">2122</span><span id="line-2122"></span>
+<span class="source-line-no">2123</span><span id="line-2123">    boolean onlyMetaRefresh = false;</span>
+<span class="source-line-no">2124</span><span id="line-2124">    int storefileRefreshPeriod =</span>
+<span class="source-line-no">2125</span><span id="line-2125">      conf.getInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD,</span>
+<span class="source-line-no">2126</span><span id="line-2126">        StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);</span>
+<span class="source-line-no">2127</span><span id="line-2127">    if (storefileRefreshPeriod == 0) {</span>
+<span class="source-line-no">2128</span><span id="line-2128">      storefileRefreshPeriod =</span>
+<span class="source-line-no">2129</span><span id="line-2129">        conf.getInt(StorefileRefresherChore.REGIONSERVER_META_STOREFILE_REFRESH_PERIOD,</span>
+<span class="source-line-no">2130</span><span id="line-2130">          StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);</span>
+<span class="source-line-no">2131</span><span id="line-2131">      onlyMetaRefresh = true;</span>
 <span class="source-line-no">2132</span><span id="line-2132">    }</span>
-<span class="source-line-no">2133</span><span id="line-2133"></span>
-<span class="source-line-no">2134</span><span id="line-2134">    int brokenStoreFileCleanerPeriod =</span>
-<span class="source-line-no">2135</span><span id="line-2135">      conf.getInt(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_PERIOD,</span>
-<span class="source-line-no">2136</span><span id="line-2136">        BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_PERIOD);</span>
-<span class="source-line-no">2137</span><span id="line-2137">    int brokenStoreFileCleanerDelay =</span>
-<span class="source-line-no">2138</span><span id="line-2138">      conf.getInt(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_DELAY,</span>
-<span class="source-line-no">2139</span><span id="line-2139">        BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_DELAY);</span>
-<span class="source-line-no">2140</span><span id="line-2140">    double brokenStoreFileCleanerDelayJitter =</span>
-<span class="source-line-no">2141</span><span id="line-2141">      conf.getDouble(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_DELAY_JITTER,</span>
-<span class="source-line-no">2142</span><span id="line-2142">        BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_DELAY_JITTER);</span>
-<span class="source-line-no">2143</span><span id="line-2143">    double jitterRate =</span>
-<span class="source-line-no">2144</span><span id="line-2144">      (ThreadLocalRandom.current().nextDouble() - 0.5D) * brokenStoreFileCleanerDelayJitter;</span>
-<span class="source-line-no">2145</span><span id="line-2145">    long jitterValue = Math.round(brokenStoreFileCleanerDelay * jitterRate);</span>
-<span class="source-line-no">2146</span><span id="line-2146">    this.brokenStoreFileCleaner =</span>
-<span class="source-line-no">2147</span><span id="line-2147">      new BrokenStoreFileCleaner((int) (brokenStoreFileCleanerDelay + jitterValue),</span>
-<span class="source-line-no">2148</span><span id="line-2148">        brokenStoreFileCleanerPeriod, this, conf, this);</span>
-<span class="source-line-no">2149</span><span id="line-2149"></span>
-<span class="source-line-no">2150</span><span id="line-2150">    this.rsMobFileCleanerChore = new RSMobFileCleanerChore(this);</span>
-<span class="source-line-no">2151</span><span id="line-2151"></span>
-<span class="source-line-no">2152</span><span id="line-2152">    registerConfigurationObservers();</span>
-<span class="source-line-no">2153</span><span id="line-2153">    initializeReplicationMarkerChore();</span>
-<span class="source-line-no">2154</span><span id="line-2154">  }</span>
+<span class="source-line-no">2133</span><span id="line-2133">    if (storefileRefreshPeriod &gt; 0) {</span>
+<span class="source-line-no">2134</span><span id="line-2134">      this.storefileRefresher =</span>
+<span class="source-line-no">2135</span><span id="line-2135">        new StorefileRefresherChore(storefileRefreshPeriod, onlyMetaRefresh, this, this);</span>
+<span class="source-line-no">2136</span><span id="line-2136">    }</span>
+<span class="source-line-no">2137</span><span id="line-2137"></span>
+<span class="source-line-no">2138</span><span id="line-2138">    int brokenStoreFileCleanerPeriod =</span>
+<span class="source-line-no">2139</span><span id="line-2139">      conf.getInt(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_PERIOD,</span>
+<span class="source-line-no">2140</span><span id="line-2140">        BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_PERIOD);</span>
+<span class="source-line-no">2141</span><span id="line-2141">    int brokenStoreFileCleanerDelay =</span>
+<span class="source-line-no">2142</span><span id="line-2142">      conf.getInt(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_DELAY,</span>
+<span class="source-line-no">2143</span><span id="line-2143">        BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_DELAY);</span>
+<span class="source-line-no">2144</span><span id="line-2144">    double brokenStoreFileCleanerDelayJitter =</span>
+<span class="source-line-no">2145</span><span id="line-2145">      conf.getDouble(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_DELAY_JITTER,</span>
+<span class="source-line-no">2146</span><span id="line-2146">        BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_DELAY_JITTER);</span>
+<span class="source-line-no">2147</span><span id="line-2147">    double jitterRate =</span>
+<span class="source-line-no">2148</span><span id="line-2148">      (ThreadLocalRandom.current().nextDouble() - 0.5D) * brokenStoreFileCleanerDelayJitter;</span>
+<span class="source-line-no">2149</span><span id="line-2149">    long jitterValue = Math.round(brokenStoreFileCleanerDelay * jitterRate);</span>
+<span class="source-line-no">2150</span><span id="line-2150">    this.brokenStoreFileCleaner =</span>
+<span class="source-line-no">2151</span><span id="line-2151">      new BrokenStoreFileCleaner((int) (brokenStoreFileCleanerDelay + jitterValue),</span>
+<span class="source-line-no">2152</span><span id="line-2152">        brokenStoreFileCleanerPeriod, this, conf, this);</span>
+<span class="source-line-no">2153</span><span id="line-2153"></span>
+<span class="source-line-no">2154</span><span id="line-2154">    this.rsMobFileCleanerChore = new RSMobFileCleanerChore(this);</span>
 <span class="source-line-no">2155</span><span id="line-2155"></span>
-<span class="source-line-no">2156</span><span id="line-2156">  private void registerConfigurationObservers() {</span>
-<span class="source-line-no">2157</span><span id="line-2157">    // Register Replication if possible, as now we support recreating replication peer storage, for</span>
-<span class="source-line-no">2158</span><span id="line-2158">    // migrating across different replication peer storages online</span>
-<span class="source-line-no">2159</span><span id="line-2159">    if (replicationSourceHandler instanceof ConfigurationObserver) {</span>
-<span class="source-line-no">2160</span><span id="line-2160">      configurationManager.registerObserver((ConfigurationObserver) replicationSourceHandler);</span>
-<span class="source-line-no">2161</span><span id="line-2161">    }</span>
-<span class="source-line-no">2162</span><span id="line-2162">    if (!sameReplicationSourceAndSink &amp;&amp; replicationSinkHandler instanceof ConfigurationObserver) {</span>
-<span class="source-line-no">2163</span><span id="line-2163">      configurationManager.registerObserver((ConfigurationObserver) replicationSinkHandler);</span>
-<span class="source-line-no">2164</span><span id="line-2164">    }</span>
-<span class="source-line-no">2165</span><span id="line-2165">    // Registering the compactSplitThread object with the ConfigurationManager.</span>
-<span class="source-line-no">2166</span><span id="line-2166">    configurationManager.registerObserver(this.compactSplitThread);</span>
-<span class="source-line-no">2167</span><span id="line-2167">    configurationManager.registerObserver(this.cacheFlusher);</span>
-<span class="source-line-no">2168</span><span id="line-2168">    configurationManager.registerObserver(this.rpcServices);</span>
-<span class="source-line-no">2169</span><span id="line-2169">    configurationManager.registerObserver(this.prefetchExecutorNotifier);</span>
-<span class="source-line-no">2170</span><span id="line-2170">    configurationManager.registerObserver(this);</span>
-<span class="source-line-no">2171</span><span id="line-2171">  }</span>
-<span class="source-line-no">2172</span><span id="line-2172"></span>
-<span class="source-line-no">2173</span><span id="line-2173">  /*</span>
-<span class="source-line-no">2174</span><span id="line-2174">   * Verify that server is healthy</span>
-<span class="source-line-no">2175</span><span id="line-2175">   */</span>
-<span class="source-line-no">2176</span><span id="line-2176">  private boolean isHealthy() {</span>
-<span class="source-line-no">2177</span><span id="line-2177">    if (!dataFsOk) {</span>
-<span class="source-line-no">2178</span><span id="line-2178">      // File system problem</span>
-<span class="source-line-no">2179</span><span id="line-2179">      return false;</span>
-<span class="source-line-no">2180</span><span id="line-2180">    }</span>
-<span class="source-line-no">2181</span><span id="line-2181">    // Verify that all threads are alive</span>
-<span class="source-line-no">2182</span><span id="line-2182">    boolean healthy = (this.leaseManager == null || this.leaseManager.isAlive())</span>
-<span class="source-line-no">2183</span><span id="line-2183">      &amp;&amp; (this.cacheFlusher == null || this.cacheFlusher.isAlive())</span>
-<span class="source-line-no">2184</span><span id="line-2184">      &amp;&amp; (this.walRoller == null || this.walRoller.isAlive())</span>
-<span class="source-line-no">2185</span><span id="line-2185">      &amp;&amp; (this.compactionChecker == null || this.compactionChecker.isScheduled())</span>
-<span class="source-line-no">2186</span><span id="line-2186">      &amp;&amp; (this.periodicFlusher == null || this.periodicFlusher.isScheduled());</span>
-<span class="source-line-no">2187</span><span id="line-2187">    if (!healthy) {</span>
-<span class="source-line-no">2188</span><span id="line-2188">      stop("One or more threads are no longer alive -- stop");</span>
-<span class="source-line-no">2189</span><span id="line-2189">    }</span>
-<span class="source-line-no">2190</span><span id="line-2190">    return healthy;</span>
-<span class="source-line-no">2191</span><span id="line-2191">  }</span>
-<span class="source-line-no">2192</span><span id="line-2192"></span>
-<span class="source-line-no">2193</span><span id="line-2193">  @Override</span>
-<span class="source-line-no">2194</span><span id="line-2194">  public List&lt;WAL&gt; getWALs() {</span>
-<span class="source-line-no">2195</span><span id="line-2195">    return walFactory.getWALs();</span>
-<span class="source-line-no">2196</span><span id="line-2196">  }</span>
-<span class="source-line-no">2197</span><span id="line-2197"></span>
-<span class="source-line-no">2198</span><span id="line-2198">  @Override</span>
-<span class="source-line-no">2199</span><span id="line-2199">  public WAL getWAL(RegionInfo regionInfo) throws IOException {</span>
-<span class="source-line-no">2200</span><span id="line-2200">    WAL wal = walFactory.getWAL(regionInfo);</span>
-<span class="source-line-no">2201</span><span id="line-2201">    if (this.walRoller != null) {</span>
-<span class="source-line-no">2202</span><span id="line-2202">      this.walRoller.addWAL(wal);</span>
-<span class="source-line-no">2203</span><span id="line-2203">    }</span>
-<span class="source-line-no">2204</span><span id="line-2204">    return wal;</span>
-<span class="source-line-no">2205</span><span id="line-2205">  }</span>
-<span class="source-line-no">2206</span><span id="line-2206"></span>
-<span class="source-line-no">2207</span><span id="line-2207">  public LogRoller getWalRoller() {</span>
-<span class="source-line-no">2208</span><span id="line-2208">    return walRoller;</span>
+<span class="source-line-no">2156</span><span id="line-2156">    registerConfigurationObservers();</span>
+<span class="source-line-no">2157</span><span id="line-2157">    initializeReplicationMarkerChore();</span>
+<span class="source-line-no">2158</span><span id="line-2158">  }</span>
+<span class="source-line-no">2159</span><span id="line-2159"></span>
+<span class="source-line-no">2160</span><span id="line-2160">  private void registerConfigurationObservers() {</span>
+<span class="source-line-no">2161</span><span id="line-2161">    // Register Replication if possible, as now we support recreating replication peer storage, for</span>
+<span class="source-line-no">2162</span><span id="line-2162">    // migrating across different replication peer storages online</span>
+<span class="source-line-no">2163</span><span id="line-2163">    if (replicationSourceHandler instanceof ConfigurationObserver) {</span>
+<span class="source-line-no">2164</span><span id="line-2164">      configurationManager.registerObserver((ConfigurationObserver) replicationSourceHandler);</span>
+<span class="source-line-no">2165</span><span id="line-2165">    }</span>
+<span class="source-line-no">2166</span><span id="line-2166">    if (!sameReplicationSourceAndSink &amp;&amp; replicationSinkHandler instanceof ConfigurationObserver) {</span>
+<span class="source-line-no">2167</span><span id="line-2167">      configurationManager.registerObserver((ConfigurationObserver) replicationSinkHandler);</span>
+<span class="source-line-no">2168</span><span id="line-2168">    }</span>
+<span class="source-line-no">2169</span><span id="line-2169">    // Registering the compactSplitThread object with the ConfigurationManager.</span>
+<span class="source-line-no">2170</span><span id="line-2170">    configurationManager.registerObserver(this.compactSplitThread);</span>
+<span class="source-line-no">2171</span><span id="line-2171">    configurationManager.registerObserver(this.cacheFlusher);</span>
+<span class="source-line-no">2172</span><span id="line-2172">    configurationManager.registerObserver(this.rpcServices);</span>
+<span class="source-line-no">2173</span><span id="line-2173">    configurationManager.registerObserver(this.prefetchExecutorNotifier);</span>
+<span class="source-line-no">2174</span><span id="line-2174">    configurationManager.registerObserver(this);</span>
+<span class="source-line-no">2175</span><span id="line-2175">  }</span>
+<span class="source-line-no">2176</span><span id="line-2176"></span>
+<span class="source-line-no">2177</span><span id="line-2177">  /*</span>
+<span class="source-line-no">2178</span><span id="line-2178">   * Verify that server is healthy</span>
+<span class="source-line-no">2179</span><span id="line-2179">   */</span>
+<span class="source-line-no">2180</span><span id="line-2180">  private boolean isHealthy() {</span>
+<span class="source-line-no">2181</span><span id="line-2181">    if (!dataFsOk) {</span>
+<span class="source-line-no">2182</span><span id="line-2182">      // File system problem</span>
+<span class="source-line-no">2183</span><span id="line-2183">      return false;</span>
+<span class="source-line-no">2184</span><span id="line-2184">    }</span>
+<span class="source-line-no">2185</span><span id="line-2185">    // Verify that all threads are alive</span>
+<span class="source-line-no">2186</span><span id="line-2186">    boolean healthy = (this.leaseManager == null || this.leaseManager.isAlive())</span>
+<span class="source-line-no">2187</span><span id="line-2187">      &amp;&amp; (this.cacheFlusher == null || this.cacheFlusher.isAlive())</span>
+<span class="source-line-no">2188</span><span id="line-2188">      &amp;&amp; (this.walRoller == null || this.walRoller.isAlive())</span>
+<span class="source-line-no">2189</span><span id="line-2189">      &amp;&amp; (this.compactionChecker == null || this.compactionChecker.isScheduled())</span>
+<span class="source-line-no">2190</span><span id="line-2190">      &amp;&amp; (this.periodicFlusher == null || this.periodicFlusher.isScheduled());</span>
+<span class="source-line-no">2191</span><span id="line-2191">    if (!healthy) {</span>
+<span class="source-line-no">2192</span><span id="line-2192">      stop("One or more threads are no longer alive -- stop");</span>
+<span class="source-line-no">2193</span><span id="line-2193">    }</span>
+<span class="source-line-no">2194</span><span id="line-2194">    return healthy;</span>
+<span class="source-line-no">2195</span><span id="line-2195">  }</span>
+<span class="source-line-no">2196</span><span id="line-2196"></span>
+<span class="source-line-no">2197</span><span id="line-2197">  @Override</span>
+<span class="source-line-no">2198</span><span id="line-2198">  public List&lt;WAL&gt; getWALs() {</span>
+<span class="source-line-no">2199</span><span id="line-2199">    return walFactory.getWALs();</span>
+<span class="source-line-no">2200</span><span id="line-2200">  }</span>
+<span class="source-line-no">2201</span><span id="line-2201"></span>
+<span class="source-line-no">2202</span><span id="line-2202">  @Override</span>
+<span class="source-line-no">2203</span><span id="line-2203">  public WAL getWAL(RegionInfo regionInfo) throws IOException {</span>
+<span class="source-line-no">2204</span><span id="line-2204">    WAL wal = walFactory.getWAL(regionInfo);</span>
+<span class="source-line-no">2205</span><span id="line-2205">    if (this.walRoller != null) {</span>
+<span class="source-line-no">2206</span><span id="line-2206">      this.walRoller.addWAL(wal);</span>
+<span class="source-line-no">2207</span><span id="line-2207">    }</span>
+<span class="source-line-no">2208</span><span id="line-2208">    return wal;</span>
 <span class="source-line-no">2209</span><span id="line-2209">  }</span>
 <span class="source-line-no">2210</span><span id="line-2210"></span>
-<span class="source-line-no">2211</span><span id="line-2211">  public WALFactory getWalFactory() {</span>
-<span class="source-line-no">2212</span><span id="line-2212">    return walFactory;</span>
+<span class="source-line-no">2211</span><span id="line-2211">  public LogRoller getWalRoller() {</span>
+<span class="source-line-no">2212</span><span id="line-2212">    return walRoller;</span>
 <span class="source-line-no">2213</span><span id="line-2213">  }</span>
 <span class="source-line-no">2214</span><span id="line-2214"></span>
-<span class="source-line-no">2215</span><span id="line-2215">  @Override</span>
-<span class="source-line-no">2216</span><span id="line-2216">  public void stop(final String msg) {</span>
-<span class="source-line-no">2217</span><span id="line-2217">    stop(msg, false, RpcServer.getRequestUser().orElse(null));</span>
-<span class="source-line-no">2218</span><span id="line-2218">  }</span>
-<span class="source-line-no">2219</span><span id="line-2219"></span>
-<span class="source-line-no">2220</span><span id="line-2220">  /**</span>
-<span class="source-line-no">2221</span><span id="line-2221">   * Stops the regionserver.</span>
-<span class="source-line-no">2222</span><span id="line-2222">   * @param msg   Status message</span>
-<span class="source-line-no">2223</span><span id="line-2223">   * @param force True if this is a regionserver abort</span>
-<span class="source-line-no">2224</span><span id="line-2224">   * @param user  The user executing the stop request, or null if no user is associated</span>
-<span class="source-line-no">2225</span><span id="line-2225">   */</span>
-<span class="source-line-no">2226</span><span id="line-2226">  public void stop(final String msg, final boolean force, final User user) {</span>
-<span class="source-line-no">2227</span><span id="line-2227">    if (!this.stopped) {</span>
-<span class="source-line-no">2228</span><span id="line-2228">      LOG.info("***** STOPPING region server '{}' *****", this);</span>
-<span class="source-line-no">2229</span><span id="line-2229">      if (this.rsHost != null) {</span>
-<span class="source-line-no">2230</span><span id="line-2230">        // when forced via abort don't allow CPs to override</span>
-<span class="source-line-no">2231</span><span id="line-2231">        try {</span>
-<span class="source-line-no">2232</span><span id="line-2232">          this.rsHost.preStop(msg, user);</span>
-<span class="source-line-no">2233</span><span id="line-2233">        } catch (IOException ioe) {</span>
-<span class="source-line-no">2234</span><span id="line-2234">          if (!force) {</span>
-<span class="source-line-no">2235</span><span id="line-2235">            LOG.warn("The region server did not stop", ioe);</span>
-<span class="source-line-no">2236</span><span id="line-2236">            return;</span>
-<span class="source-line-no">2237</span><span id="line-2237">          }</span>
-<span class="source-line-no">2238</span><span id="line-2238">          LOG.warn("Skipping coprocessor exception on preStop() due to forced shutdown", ioe);</span>
-<span class="source-line-no">2239</span><span id="line-2239">        }</span>
-<span class="source-line-no">2240</span><span id="line-2240">      }</span>
-<span class="source-line-no">2241</span><span id="line-2241">      this.stopped = true;</span>
-<span class="source-line-no">2242</span><span id="line-2242">      LOG.info("STOPPED: " + msg);</span>
-<span class="source-line-no">2243</span><span id="line-2243">      // Wakes run() if it is sleeping</span>
-<span class="source-line-no">2244</span><span id="line-2244">      sleeper.skipSleepCycle();</span>
-<span class="source-line-no">2245</span><span id="line-2245">    }</span>
-<span class="source-line-no">2246</span><span id="line-2246">  }</span>
-<span class="source-line-no">2247</span><span id="line-2247"></span>
-<span class="source-line-no">2248</span><span id="line-2248">  public void waitForServerOnline() {</span>
-<span class="source-line-no">2249</span><span id="line-2249">    while (!isStopped() &amp;&amp; !isOnline()) {</span>
-<span class="source-line-no">2250</span><span id="line-2250">      synchronized (online) {</span>
-<span class="source-line-no">2251</span><span id="line-2251">        try {</span>
-<span class="source-line-no">2252</span><span id="line-2252">          online.wait(msgInterval);</span>
-<span class="source-line-no">2253</span><span id="line-2253">        } catch (InterruptedException ie) {</span>
-<span class="source-line-no">2254</span><span id="line-2254">          Thread.currentThread().interrupt();</span>
-<span class="source-line-no">2255</span><span id="line-2255">          break;</span>
-<span class="source-line-no">2256</span><span id="line-2256">        }</span>
-<span class="source-line-no">2257</span><span id="line-2257">      }</span>
-<span class="source-line-no">2258</span><span id="line-2258">    }</span>
-<span class="source-line-no">2259</span><span id="line-2259">  }</span>
-<span class="source-line-no">2260</span><span id="line-2260"></span>
-<span class="source-line-no">2261</span><span id="line-2261">  @Override</span>
-<span class="source-line-no">2262</span><span id="line-2262">  public void postOpenDeployTasks(final PostOpenDeployContext context) throws IOException {</span>
-<span class="source-line-no">2263</span><span id="line-2263">    HRegion r = context.getRegion();</span>
-<span class="source-line-no">2264</span><span id="line-2264">    long openProcId = context.getOpenProcId();</span>
-<span class="source-line-no">2265</span><span id="line-2265">    long masterSystemTime = context.getMasterSystemTime();</span>
-<span class="source-line-no">2266</span><span id="line-2266">    long initiatingMasterActiveTime = context.getInitiatingMasterActiveTime();</span>
-<span class="source-line-no">2267</span><span id="line-2267">    rpcServices.checkOpen();</span>
-<span class="source-line-no">2268</span><span id="line-2268">    LOG.info("Post open deploy tasks for {}, pid={}, masterSystemTime={}",</span>
-<span class="source-line-no">2269</span><span id="line-2269">      r.getRegionInfo().getRegionNameAsString(), openProcId, masterSystemTime);</span>
-<span class="source-line-no">2270</span><span id="line-2270">    // Do checks to see if we need to compact (references or too many files)</span>
-<span class="source-line-no">2271</span><span id="line-2271">    // Skip compaction check if region is read only</span>
-<span class="source-line-no">2272</span><span id="line-2272">    if (!r.isReadOnly()) {</span>
-<span class="source-line-no">2273</span><span id="line-2273">      for (HStore s : r.stores.values()) {</span>
-<span class="source-line-no">2274</span><span id="line-2274">        if (s.hasReferences() || s.needsCompaction()) {</span>
-<span class="source-line-no">2275</span><span id="line-2275">          this.compactSplitThread.requestSystemCompaction(r, s, "Opening Region");</span>
-<span class="source-line-no">2276</span><span id="line-2276">        }</span>
-<span class="source-line-no">2277</span><span id="line-2277">      }</span>
-<span class="source-line-no">2278</span><span id="line-2278">    }</span>
-<span class="source-line-no">2279</span><span id="line-2279">    long openSeqNum = r.getOpenSeqNum();</span>
-<span class="source-line-no">2280</span><span id="line-2280">    if (openSeqNum == HConstants.NO_SEQNUM) {</span>
-<span class="source-line-no">2281</span><span id="line-2281">      // If we opened a region, we should have read some sequence number from it.</span>
-<span class="source-line-no">2282</span><span id="line-2282">      LOG.error(</span>
-<span class="source-line-no">2283</span><span id="line-2283">        "No sequence number found when opening " + r.getRegionInfo().getRegionNameAsString());</span>
-<span class="source-line-no">2284</span><span id="line-2284">      openSeqNum = 0;</span>
-<span class="source-line-no">2285</span><span id="line-2285">    }</span>
-<span class="source-line-no">2286</span><span id="line-2286"></span>
-<span class="source-line-no">2287</span><span id="line-2287">    // Notify master</span>
-<span class="source-line-no">2288</span><span id="line-2288">    if (</span>
-<span class="source-line-no">2289</span><span id="line-2289">      !reportRegionStateTransition(new RegionStateTransitionContext(TransitionCode.OPENED,</span>
-<span class="source-line-no">2290</span><span id="line-2290">        openSeqNum, openProcId, masterSystemTime, r.getRegionInfo(), initiatingMasterActiveTime))</span>
-<span class="source-line-no">2291</span><span id="line-2291">    ) {</span>
-<span class="source-line-no">2292</span><span id="line-2292">      throw new IOException(</span>
-<span class="source-line-no">2293</span><span id="line-2293">        "Failed to report opened region to master: " + r.getRegionInfo().getRegionNameAsString());</span>
-<span class="source-line-no">2294</span><span id="line-2294">    }</span>
-<span class="source-line-no">2295</span><span id="line-2295"></span>
-<span class="source-line-no">2296</span><span id="line-2296">    triggerFlushInPrimaryRegion(r);</span>
-<span class="source-line-no">2297</span><span id="line-2297"></span>
-<span class="source-line-no">2298</span><span id="line-2298">    LOG.debug("Finished post open deploy task for " + r.getRegionInfo().getRegionNameAsString());</span>
-<span class="source-line-no">2299</span><span id="line-2299">  }</span>
-<span class="source-line-no">2300</span><span id="line-2300"></span>
-<span class="source-line-no">2301</span><span id="line-2301">  /**</span>
-<span class="source-line-no">2302</span><span id="line-2302">   * Helper method for use in tests. Skip the region transition report when there's no master around</span>
-<span class="source-line-no">2303</span><span id="line-2303">   * to receive it.</span>
-<span class="source-line-no">2304</span><span id="line-2304">   */</span>
-<span class="source-line-no">2305</span><span id="line-2305">  private boolean skipReportingTransition(final RegionStateTransitionContext context) {</span>
-<span class="source-line-no">2306</span><span id="line-2306">    final TransitionCode code = context.getCode();</span>
-<span class="source-line-no">2307</span><span id="line-2307">    final long openSeqNum = context.getOpenSeqNum();</span>
-<span class="source-line-no">2308</span><span id="line-2308">    long masterSystemTime = context.getMasterSystemTime();</span>
-<span class="source-line-no">2309</span><span id="line-2309">    final RegionInfo[] hris = context.getHris();</span>
-<span class="source-line-no">2310</span><span id="line-2310"></span>
-<span class="source-line-no">2311</span><span id="line-2311">    if (code == TransitionCode.OPENED) {</span>
-<span class="source-line-no">2312</span><span id="line-2312">      Preconditions.checkArgument(hris != null &amp;&amp; hris.length == 1);</span>
-<span class="source-line-no">2313</span><span id="line-2313">      if (hris[0].isMetaRegion()) {</span>
-<span class="source-line-no">2314</span><span id="line-2314">        LOG.warn(</span>
-<span class="source-line-no">2315</span><span id="line-2315">          "meta table location is stored in master local store, so we can not skip reporting");</span>
-<span class="source-line-no">2316</span><span id="line-2316">        return false;</span>
-<span class="source-line-no">2317</span><span id="line-2317">      } else {</span>
-<span class="source-line-no">2318</span><span id="line-2318">        try {</span>
-<span class="source-line-no">2319</span><span id="line-2319">          MetaTableAccessor.updateRegionLocation(asyncClusterConnection.toConnection(), hris[0],</span>
-<span class="source-line-no">2320</span><span id="line-2320">            serverName, openSeqNum, masterSystemTime);</span>
-<span class="source-line-no">2321</span><span id="line-2321">        } catch (IOException e) {</span>
-<span class="source-line-no">2322</span><span id="line-2322">          LOG.info("Failed to update meta", e);</span>
-<span class="source-line-no">2323</span><span id="line-2323">          return false;</span>
-<span class="source-line-no">2324</span><span id="line-2324">        }</span>
-<span class="source-line-no">2325</span><span id="line-2325">      }</span>
-<span class="source-line-no">2326</span><span id="line-2326">    }</span>
-<span class="source-line-no">2327</span><span id="line-2327">    return true;</span>
-<span class="source-line-no">2328</span><span id="line-2328">  }</span>
-<span class="source-line-no">2329</span><span id="line-2329"></span>
-<span class="source-line-no">2330</span><span id="line-2330">  private ReportRegionStateTransitionRequest</span>
-<span class="source-line-no">2331</span><span id="line-2331">    createReportRegionStateTransitionRequest(final RegionStateTransitionContext context) {</span>
-<span class="source-line-no">2332</span><span id="line-2332">    final TransitionCode code = context.getCode();</span>
-<span class="source-line-no">2333</span><span id="line-2333">    final long openSeqNum = context.getOpenSeqNum();</span>
-<span class="source-line-no">2334</span><span id="line-2334">    final RegionInfo[] hris = context.getHris();</span>
-<span class="source-line-no">2335</span><span id="line-2335">    final long[] procIds = context.getProcIds();</span>
-<span class="source-line-no">2336</span><span id="line-2336"></span>
-<span class="source-line-no">2337</span><span id="line-2337">    ReportRegionStateTransitionRequest.Builder builder =</span>
-<span class="source-line-no">2338</span><span id="line-2338">      ReportRegionStateTransitionRequest.newBuilder();</span>
-<span class="source-line-no">2339</span><span id="line-2339">    builder.setServer(ProtobufUtil.toServerName(serverName));</span>
-<span class="source-line-no">2340</span><span id="line-2340">    RegionStateTransition.Builder transition = builder.addTransitionBuilder();</span>
-<span class="source-line-no">2341</span><span id="line-2341">    transition.setTransitionCode(code);</span>
-<span class="source-line-no">2342</span><span id="line-2342">    if (code == TransitionCode.OPENED &amp;&amp; openSeqNum &gt;= 0) {</span>
-<span class="source-line-no">2343</span><span id="line-2343">      transition.setOpenSeqNum(openSeqNum);</span>
-<span class="source-line-no">2344</span><span id="line-2344">    }</span>
-<span class="source-line-no">2345</span><span id="line-2345">    for (RegionInfo hri : hris) {</span>
-<span class="source-line-no">2346</span><span id="line-2346">      transition.addRegionInfo(ProtobufUtil.toRegionInfo(hri));</span>
-<span class="source-line-no">2347</span><span id="line-2347">    }</span>
-<span class="source-line-no">2348</span><span id="line-2348">    for (long procId : procIds) {</span>
-<span class="source-line-no">2349</span><span id="line-2349">      transition.addProcId(procId);</span>
-<span class="source-line-no">2350</span><span id="line-2350">    }</span>
-<span class="source-line-no">2351</span><span id="line-2351">    transition.setInitiatingMasterActiveTime(context.getInitiatingMasterActiveTime());</span>
-<span class="source-line-no">2352</span><span id="line-2352"></span>
-<span class="source-line-no">2353</span><span id="line-2353">    return builder.build();</span>
-<span class="source-line-no">2354</span><span id="line-2354">  }</span>
-<span class="source-line-no">2355</span><span id="line-2355"></span>
-<span class="source-line-no">2356</span><span id="line-2356">  @Override</span>
-<span class="source-line-no">2357</span><span id="line-2357">  public boolean reportRegionStateTransition(final RegionStateTransitionContext context) {</span>
-<span class="source-line-no">2358</span><span id="line-2358">    if (TEST_SKIP_REPORTING_TRANSITION) {</span>
-<span class="source-line-no">2359</span><span id="line-2359">      return skipReportingTransition(context);</span>
-<span class="source-line-no">2360</span><span id="line-2360">    }</span>
-<span class="source-line-no">2361</span><span id="line-2361">    final ReportRegionStateTransitionRequest request =</span>
-<span class="source-line-no">2362</span><span id="line-2362">      createReportRegionStateTransitionRequest(context);</span>
-<span class="source-line-no">2363</span><span id="line-2363"></span>
-<span class="source-line-no">2364</span><span id="line-2364">    int tries = 0;</span>
-<span class="source-line-no">2365</span><span id="line-2365">    long pauseTime = this.retryPauseTime;</span>
-<span class="source-line-no">2366</span><span id="line-2366">    // Keep looping till we get an error. We want to send reports even though server is going down.</span>
-<span class="source-line-no">2367</span><span id="line-2367">    // Only go down if clusterConnection is null. It is set to null almost as last thing as the</span>
-<span class="source-line-no">2368</span><span id="line-2368">    // HRegionServer does down.</span>
-<span class="source-line-no">2369</span><span id="line-2369">    while (this.asyncClusterConnection != null &amp;&amp; !this.asyncClusterConnection.isClosed()) {</span>
-<span class="source-line-no">2370</span><span id="line-2370">      RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">2371</span><span id="line-2371">      try {</span>
-<span class="source-line-no">2372</span><span id="line-2372">        if (rss == null) {</span>
-<span class="source-line-no">2373</span><span id="line-2373">          createRegionServerStatusStub();</span>
-<span class="source-line-no">2374</span><span id="line-2374">          continue;</span>
-<span class="source-line-no">2375</span><span id="line-2375">        }</span>
-<span class="source-line-no">2376</span><span id="line-2376">        ReportRegionStateTransitionResponse response =</span>
-<span class="source-line-no">2377</span><span id="line-2377">          rss.reportRegionStateTransition(null, request);</span>
-<span class="source-line-no">2378</span><span id="line-2378">        if (response.hasErrorMessage()) {</span>
-<span class="source-line-no">2379</span><span id="line-2379">          LOG.info("TRANSITION FAILED " + request + ": " + response.getErrorMessage());</span>
-<span class="source-line-no">2380</span><span id="line-2380">          break;</span>
-<span class="source-line-no">2381</span><span id="line-2381">        }</span>
-<span class="source-line-no">2382</span><span id="line-2382">        // Log if we had to retry else don't log unless TRACE. We want to</span>
-<span class="source-line-no">2383</span><span id="line-2383">        // know if were successful after an attempt showed in logs as failed.</span>
-<span class="source-line-no">2384</span><span id="line-2384">        if (tries &gt; 0 || LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">2385</span><span id="line-2385">          LOG.info("TRANSITION REPORTED " + request);</span>
-<span class="source-line-no">2386</span><span id="line-2386">        }</span>
-<span class="source-line-no">2387</span><span id="line-2387">        // NOTE: Return mid-method!!!</span>
-<span class="source-line-no">2388</span><span id="line-2388">        return true;</span>
-<span class="source-line-no">2389</span><span id="line-2389">      } catch (ServiceException se) {</span>
-<span class="source-line-no">2390</span><span id="line-2390">        IOException ioe = ProtobufUtil.getRemoteException(se);</span>
-<span class="source-line-no">2391</span><span id="line-2391">        boolean pause = ioe instanceof ServerNotRunningYetException</span>
-<span class="source-line-no">2392</span><span id="line-2392">          || ioe instanceof PleaseHoldException || ioe instanceof CallQueueTooBigException;</span>
-<span class="source-line-no">2393</span><span id="line-2393">        if (pause) {</span>
-<span class="source-line-no">2394</span><span id="line-2394">          // Do backoff else we flood the Master with requests.</span>
-<span class="source-line-no">2395</span><span id="line-2395">          pauseTime = ConnectionUtils.getPauseTime(this.retryPauseTime, tries);</span>
-<span class="source-line-no">2396</span><span id="line-2396">        } else {</span>
-<span class="source-line-no">2397</span><span id="line-2397">          pauseTime = this.retryPauseTime; // Reset.</span>
-<span class="source-line-no">2398</span><span id="line-2398">        }</span>
-<span class="source-line-no">2399</span><span id="line-2399">        LOG.info("Failed report transition " + TextFormat.shortDebugString(request) + "; retry (#"</span>
-<span class="source-line-no">2400</span><span id="line-2400">          + tries + ")"</span>
-<span class="source-line-no">2401</span><span id="line-2401">          + (pause</span>
-<span class="source-line-no">2402</span><span id="line-2402">            ? " after " + pauseTime + "ms delay (Master is coming online...)."</span>
-<span class="source-line-no">2403</span><span id="line-2403">            : " immediately."),</span>
-<span class="source-line-no">2404</span><span id="line-2404">          ioe);</span>
-<span class="source-line-no">2405</span><span id="line-2405">        if (pause) {</span>
-<span class="source-line-no">2406</span><span id="line-2406">          Threads.sleep(pauseTime);</span>
-<span class="source-line-no">2407</span><span id="line-2407">        }</span>
-<span class="source-line-no">2408</span><span id="line-2408">        tries++;</span>
-<span class="source-line-no">2409</span><span id="line-2409">        if (rssStub == rss) {</span>
-<span class="source-line-no">2410</span><span id="line-2410">          rssStub = null;</span>
+<span class="source-line-no">2215</span><span id="line-2215">  public WALFactory getWalFactory() {</span>
+<span class="source-line-no">2216</span><span id="line-2216">    return walFactory;</span>
+<span class="source-line-no">2217</span><span id="line-2217">  }</span>
+<span class="source-line-no">2218</span><span id="line-2218"></span>
+<span class="source-line-no">2219</span><span id="line-2219">  @Override</span>
+<span class="source-line-no">2220</span><span id="line-2220">  public void stop(final String msg) {</span>
+<span class="source-line-no">2221</span><span id="line-2221">    stop(msg, false, RpcServer.getRequestUser().orElse(null));</span>
+<span class="source-line-no">2222</span><span id="line-2222">  }</span>
+<span class="source-line-no">2223</span><span id="line-2223"></span>
+<span class="source-line-no">2224</span><span id="line-2224">  /**</span>
+<span class="source-line-no">2225</span><span id="line-2225">   * Stops the regionserver.</span>
+<span class="source-line-no">2226</span><span id="line-2226">   * @param msg   Status message</span>
+<span class="source-line-no">2227</span><span id="line-2227">   * @param force True if this is a regionserver abort</span>
+<span class="source-line-no">2228</span><span id="line-2228">   * @param user  The user executing the stop request, or null if no user is associated</span>
+<span class="source-line-no">2229</span><span id="line-2229">   */</span>
+<span class="source-line-no">2230</span><span id="line-2230">  public void stop(final String msg, final boolean force, final User user) {</span>
+<span class="source-line-no">2231</span><span id="line-2231">    if (!this.stopped) {</span>
+<span class="source-line-no">2232</span><span id="line-2232">      LOG.info("***** STOPPING region server '{}' *****", this);</span>
+<span class="source-line-no">2233</span><span id="line-2233">      if (this.rsHost != null) {</span>
+<span class="source-line-no">2234</span><span id="line-2234">        // when forced via abort don't allow CPs to override</span>
+<span class="source-line-no">2235</span><span id="line-2235">        try {</span>
+<span class="source-line-no">2236</span><span id="line-2236">          this.rsHost.preStop(msg, user);</span>
+<span class="source-line-no">2237</span><span id="line-2237">        } catch (IOException ioe) {</span>
+<span class="source-line-no">2238</span><span id="line-2238">          if (!force) {</span>
+<span class="source-line-no">2239</span><span id="line-2239">            LOG.warn("The region server did not stop", ioe);</span>
+<span class="source-line-no">2240</span><span id="line-2240">            return;</span>
+<span class="source-line-no">2241</span><span id="line-2241">          }</span>
+<span class="source-line-no">2242</span><span id="line-2242">          LOG.warn("Skipping coprocessor exception on preStop() due to forced shutdown", ioe);</span>
+<span class="source-line-no">2243</span><span id="line-2243">        }</span>
+<span class="source-line-no">2244</span><span id="line-2244">      }</span>
+<span class="source-line-no">2245</span><span id="line-2245">      this.stopped = true;</span>
+<span class="source-line-no">2246</span><span id="line-2246">      LOG.info("STOPPED: " + msg);</span>
+<span class="source-line-no">2247</span><span id="line-2247">      // Wakes run() if it is sleeping</span>
+<span class="source-line-no">2248</span><span id="line-2248">      sleeper.skipSleepCycle();</span>
+<span class="source-line-no">2249</span><span id="line-2249">    }</span>
+<span class="source-line-no">2250</span><span id="line-2250">  }</span>
+<span class="source-line-no">2251</span><span id="line-2251"></span>
+<span class="source-line-no">2252</span><span id="line-2252">  public void waitForServerOnline() {</span>
+<span class="source-line-no">2253</span><span id="line-2253">    while (!isStopped() &amp;&amp; !isOnline()) {</span>
+<span class="source-line-no">2254</span><span id="line-2254">      synchronized (online) {</span>
+<span class="source-line-no">2255</span><span id="line-2255">        try {</span>
+<span class="source-line-no">2256</span><span id="line-2256">          online.wait(msgInterval);</span>
+<span class="source-line-no">2257</span><span id="line-2257">        } catch (InterruptedException ie) {</span>
+<span class="source-line-no">2258</span><span id="line-2258">          Thread.currentThread().interrupt();</span>
+<span class="source-line-no">2259</span><span id="line-2259">          break;</span>
+<span class="source-line-no">2260</span><span id="line-2260">        }</span>
+<span class="source-line-no">2261</span><span id="line-2261">      }</span>
+<span class="source-line-no">2262</span><span id="line-2262">    }</span>
+<span class="source-line-no">2263</span><span id="line-2263">  }</span>
+<span class="source-line-no">2264</span><span id="line-2264"></span>
+<span class="source-line-no">2265</span><span id="line-2265">  @Override</span>
+<span class="source-line-no">2266</span><span id="line-2266">  public void postOpenDeployTasks(final PostOpenDeployContext context) throws IOException {</span>
+<span class="source-line-no">2267</span><span id="line-2267">    HRegion r = context.getRegion();</span>
+<span class="source-line-no">2268</span><span id="line-2268">    long openProcId = context.getOpenProcId();</span>
+<span class="source-line-no">2269</span><span id="line-2269">    long masterSystemTime = context.getMasterSystemTime();</span>
+<span class="source-line-no">2270</span><span id="line-2270">    long initiatingMasterActiveTime = context.getInitiatingMasterActiveTime();</span>
+<span class="source-line-no">2271</span><span id="line-2271">    rpcServices.checkOpen();</span>
+<span class="source-line-no">2272</span><span id="line-2272">    LOG.info("Post open deploy tasks for {}, pid={}, masterSystemTime={}",</span>
+<span class="source-line-no">2273</span><span id="line-2273">      r.getRegionInfo().getRegionNameAsString(), openProcId, masterSystemTime);</span>
+<span class="source-line-no">2274</span><span id="line-2274">    // Do checks to see if we need to compact (references or too many files)</span>
+<span class="source-line-no">2275</span><span id="line-2275">    // Skip compaction check if region is read only</span>
+<span class="source-line-no">2276</span><span id="line-2276">    if (!r.isReadOnly()) {</span>
+<span class="source-line-no">2277</span><span id="line-2277">      for (HStore s : r.stores.values()) {</span>
+<span class="source-line-no">2278</span><span id="line-2278">        if (s.hasReferences() || s.needsCompaction()) {</span>
+<span class="source-line-no">2279</span><span id="line-2279">          this.compactSplitThread.requestSystemCompaction(r, s, "Opening Region");</span>
+<span class="source-line-no">2280</span><span id="line-2280">        }</span>
+<span class="source-line-no">2281</span><span id="line-2281">      }</span>
+<span class="source-line-no">2282</span><span id="line-2282">    }</span>
+<span class="source-line-no">2283</span><span id="line-2283">    long openSeqNum = r.getOpenSeqNum();</span>
+<span class="source-line-no">2284</span><span id="line-2284">    if (openSeqNum == HConstants.NO_SEQNUM) {</span>
+<span class="source-line-no">2285</span><span id="line-2285">      // If we opened a region, we should have read some sequence number from it.</span>
+<span class="source-line-no">2286</span><span id="line-2286">      LOG.error(</span>
+<span class="source-line-no">2287</span><span id="line-2287">        "No sequence number found when opening " + r.getRegionInfo().getRegionNameAsString());</span>
+<span class="source-line-no">2288</span><span id="line-2288">      openSeqNum = 0;</span>
+<span class="source-line-no">2289</span><span id="line-2289">    }</span>
+<span class="source-line-no">2290</span><span id="line-2290"></span>
+<span class="source-line-no">2291</span><span id="line-2291">    // Notify master</span>
+<span class="source-line-no">2292</span><span id="line-2292">    if (</span>
+<span class="source-line-no">2293</span><span id="line-2293">      !reportRegionStateTransition(new RegionStateTransitionContext(TransitionCode.OPENED,</span>
+<span class="source-line-no">2294</span><span id="line-2294">        openSeqNum, openProcId, masterSystemTime, r.getRegionInfo(), initiatingMasterActiveTime))</span>
+<span class="source-line-no">2295</span><span id="line-2295">    ) {</span>
+<span class="source-line-no">2296</span><span id="line-2296">      throw new IOException(</span>
+<span class="source-line-no">2297</span><span id="line-2297">        "Failed to report opened region to master: " + r.getRegionInfo().getRegionNameAsString());</span>
+<span class="source-line-no">2298</span><span id="line-2298">    }</span>
+<span class="source-line-no">2299</span><span id="line-2299"></span>
+<span class="source-line-no">2300</span><span id="line-2300">    triggerFlushInPrimaryRegion(r);</span>
+<span class="source-line-no">2301</span><span id="line-2301"></span>
+<span class="source-line-no">2302</span><span id="line-2302">    LOG.debug("Finished post open deploy task for " + r.getRegionInfo().getRegionNameAsString());</span>
+<span class="source-line-no">2303</span><span id="line-2303">  }</span>
+<span class="source-line-no">2304</span><span id="line-2304"></span>
+<span class="source-line-no">2305</span><span id="line-2305">  /**</span>
+<span class="source-line-no">2306</span><span id="line-2306">   * Helper method for use in tests. Skip the region transition report when there's no master around</span>
+<span class="source-line-no">2307</span><span id="line-2307">   * to receive it.</span>
+<span class="source-line-no">2308</span><span id="line-2308">   */</span>
+<span class="source-line-no">2309</span><span id="line-2309">  private boolean skipReportingTransition(final RegionStateTransitionContext context) {</span>
+<span class="source-line-no">2310</span><span id="line-2310">    final TransitionCode code = context.getCode();</span>
+<span class="source-line-no">2311</span><span id="line-2311">    final long openSeqNum = context.getOpenSeqNum();</span>
+<span class="source-line-no">2312</span><span id="line-2312">    long masterSystemTime = context.getMasterSystemTime();</span>
+<span class="source-line-no">2313</span><span id="line-2313">    final RegionInfo[] hris = context.getHris();</span>
+<span class="source-line-no">2314</span><span id="line-2314"></span>
+<span class="source-line-no">2315</span><span id="line-2315">    if (code == TransitionCode.OPENED) {</span>
+<span class="source-line-no">2316</span><span id="line-2316">      Preconditions.checkArgument(hris != null &amp;&amp; hris.length == 1);</span>
+<span class="source-line-no">2317</span><span id="line-2317">      if (hris[0].isMetaRegion()) {</span>
+<span class="source-line-no">2318</span><span id="line-2318">        LOG.warn(</span>
+<span class="source-line-no">2319</span><span id="line-2319">          "meta table location is stored in master local store, so we can not skip reporting");</span>
+<span class="source-line-no">2320</span><span id="line-2320">        return false;</span>
+<span class="source-line-no">2321</span><span id="line-2321">      } else {</span>
+<span class="source-line-no">2322</span><span id="line-2322">        try {</span>
+<span class="source-line-no">2323</span><span id="line-2323">          MetaTableAccessor.updateRegionLocation(asyncClusterConnection.toConnection(), hris[0],</span>
+<span class="source-line-no">2324</span><span id="line-2324">            serverName, openSeqNum, masterSystemTime);</span>
+<span class="source-line-no">2325</span><span id="line-2325">        } catch (IOException e) {</span>
+<span class="source-line-no">2326</span><span id="line-2326">          LOG.info("Failed to update meta", e);</span>
+<span class="source-line-no">2327</span><span id="line-2327">          return false;</span>
+<span class="source-line-no">2328</span><span id="line-2328">        }</span>
+<span class="source-line-no">2329</span><span id="line-2329">      }</span>
+<span class="source-line-no">2330</span><span id="line-2330">    }</span>
+<span class="source-line-no">2331</span><span id="line-2331">    return true;</span>
+<span class="source-line-no">2332</span><span id="line-2332">  }</span>
+<span class="source-line-no">2333</span><span id="line-2333"></span>
+<span class="source-line-no">2334</span><span id="line-2334">  private ReportRegionStateTransitionRequest</span>
+<span class="source-line-no">2335</span><span id="line-2335">    createReportRegionStateTransitionRequest(final RegionStateTransitionContext context) {</span>
+<span class="source-line-no">2336</span><span id="line-2336">    final TransitionCode code = context.getCode();</span>
+<span class="source-line-no">2337</span><span id="line-2337">    final long openSeqNum = context.getOpenSeqNum();</span>
+<span class="source-line-no">2338</span><span id="line-2338">    final RegionInfo[] hris = context.getHris();</span>
+<span class="source-line-no">2339</span><span id="line-2339">    final long[] procIds = context.getProcIds();</span>
+<span class="source-line-no">2340</span><span id="line-2340"></span>
+<span class="source-line-no">2341</span><span id="line-2341">    ReportRegionStateTransitionRequest.Builder builder =</span>
+<span class="source-line-no">2342</span><span id="line-2342">      ReportRegionStateTransitionRequest.newBuilder();</span>
+<span class="source-line-no">2343</span><span id="line-2343">    builder.setServer(ProtobufUtil.toServerName(serverName));</span>
+<span class="source-line-no">2344</span><span id="line-2344">    RegionStateTransition.Builder transition = builder.addTransitionBuilder();</span>
+<span class="source-line-no">2345</span><span id="line-2345">    transition.setTransitionCode(code);</span>
+<span class="source-line-no">2346</span><span id="line-2346">    if (code == TransitionCode.OPENED &amp;&amp; openSeqNum &gt;= 0) {</span>
+<span class="source-line-no">2347</span><span id="line-2347">      transition.setOpenSeqNum(openSeqNum);</span>
+<span class="source-line-no">2348</span><span id="line-2348">    }</span>
+<span class="source-line-no">2349</span><span id="line-2349">    for (RegionInfo hri : hris) {</span>
+<span class="source-line-no">2350</span><span id="line-2350">      transition.addRegionInfo(ProtobufUtil.toRegionInfo(hri));</span>
+<span class="source-line-no">2351</span><span id="line-2351">    }</span>
+<span class="source-line-no">2352</span><span id="line-2352">    for (long procId : procIds) {</span>
+<span class="source-line-no">2353</span><span id="line-2353">      transition.addProcId(procId);</span>
+<span class="source-line-no">2354</span><span id="line-2354">    }</span>
+<span class="source-line-no">2355</span><span id="line-2355">    transition.setInitiatingMasterActiveTime(context.getInitiatingMasterActiveTime());</span>
+<span class="source-line-no">2356</span><span id="line-2356"></span>
+<span class="source-line-no">2357</span><span id="line-2357">    return builder.build();</span>
+<span class="source-line-no">2358</span><span id="line-2358">  }</span>
+<span class="source-line-no">2359</span><span id="line-2359"></span>
+<span class="source-line-no">2360</span><span id="line-2360">  @Override</span>
+<span class="source-line-no">2361</span><span id="line-2361">  public boolean reportRegionStateTransition(final RegionStateTransitionContext context) {</span>
+<span class="source-line-no">2362</span><span id="line-2362">    if (TEST_SKIP_REPORTING_TRANSITION) {</span>
+<span class="source-line-no">2363</span><span id="line-2363">      return skipReportingTransition(context);</span>
+<span class="source-line-no">2364</span><span id="line-2364">    }</span>
+<span class="source-line-no">2365</span><span id="line-2365">    final ReportRegionStateTransitionRequest request =</span>
+<span class="source-line-no">2366</span><span id="line-2366">      createReportRegionStateTransitionRequest(context);</span>
+<span class="source-line-no">2367</span><span id="line-2367"></span>
+<span class="source-line-no">2368</span><span id="line-2368">    int tries = 0;</span>
+<span class="source-line-no">2369</span><span id="line-2369">    long pauseTime = this.retryPauseTime;</span>
+<span class="source-line-no">2370</span><span id="line-2370">    // Keep looping till we get an error. We want to send reports even though server is going down.</span>
+<span class="source-line-no">2371</span><span id="line-2371">    // Only go down if clusterConnection is null. It is set to null almost as last thing as the</span>
+<span class="source-line-no">2372</span><span id="line-2372">    // HRegionServer does down.</span>
+<span class="source-line-no">2373</span><span id="line-2373">    while (this.asyncClusterConnection != null &amp;&amp; !this.asyncClusterConnection.isClosed()) {</span>
+<span class="source-line-no">2374</span><span id="line-2374">      RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">2375</span><span id="line-2375">      try {</span>
+<span class="source-line-no">2376</span><span id="line-2376">        if (rss == null) {</span>
+<span class="source-line-no">2377</span><span id="line-2377">          createRegionServerStatusStub();</span>
+<span class="source-line-no">2378</span><span id="line-2378">          continue;</span>
+<span class="source-line-no">2379</span><span id="line-2379">        }</span>
+<span class="source-line-no">2380</span><span id="line-2380">        ReportRegionStateTransitionResponse response =</span>
+<span class="source-line-no">2381</span><span id="line-2381">          rss.reportRegionStateTransition(null, request);</span>
+<span class="source-line-no">2382</span><span id="line-2382">        if (response.hasErrorMessage()) {</span>
+<span class="source-line-no">2383</span><span id="line-2383">          LOG.info("TRANSITION FAILED " + request + ": " + response.getErrorMessage());</span>
+<span class="source-line-no">2384</span><span id="line-2384">          break;</span>
+<span class="source-line-no">2385</span><span id="line-2385">        }</span>
+<span class="source-line-no">2386</span><span id="line-2386">        // Log if we had to retry else don't log unless TRACE. We want to</span>
+<span class="source-line-no">2387</span><span id="line-2387">        // know if were successful after an attempt showed in logs as failed.</span>
+<span class="source-line-no">2388</span><span id="line-2388">        if (tries &gt; 0 || LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">2389</span><span id="line-2389">          LOG.info("TRANSITION REPORTED " + request);</span>
+<span class="source-line-no">2390</span><span id="line-2390">        }</span>
+<span class="source-line-no">2391</span><span id="line-2391">        // NOTE: Return mid-method!!!</span>
+<span class="source-line-no">2392</span><span id="line-2392">        return true;</span>
+<span class="source-line-no">2393</span><span id="line-2393">      } catch (ServiceException se) {</span>
+<span class="source-line-no">2394</span><span id="line-2394">        IOException ioe = ProtobufUtil.getRemoteException(se);</span>
+<span class="source-line-no">2395</span><span id="line-2395">        boolean pause = ioe instanceof ServerNotRunningYetException</span>
+<span class="source-line-no">2396</span><span id="line-2396">          || ioe instanceof PleaseHoldException || ioe instanceof CallQueueTooBigException;</span>
+<span class="source-line-no">2397</span><span id="line-2397">        if (pause) {</span>
+<span class="source-line-no">2398</span><span id="line-2398">          // Do backoff else we flood the Master with requests.</span>
+<span class="source-line-no">2399</span><span id="line-2399">          pauseTime = ConnectionUtils.getPauseTime(this.retryPauseTime, tries);</span>
+<span class="source-line-no">2400</span><span id="line-2400">        } else {</span>
+<span class="source-line-no">2401</span><span id="line-2401">          pauseTime = this.retryPauseTime; // Reset.</span>
+<span class="source-line-no">2402</span><span id="line-2402">        }</span>
+<span class="source-line-no">2403</span><span id="line-2403">        LOG.info("Failed report transition " + TextFormat.shortDebugString(request) + "; retry (#"</span>
+<span class="source-line-no">2404</span><span id="line-2404">          + tries + ")"</span>
+<span class="source-line-no">2405</span><span id="line-2405">          + (pause</span>
+<span class="source-line-no">2406</span><span id="line-2406">            ? " after " + pauseTime + "ms delay (Master is coming online...)."</span>
+<span class="source-line-no">2407</span><span id="line-2407">            : " immediately."),</span>
+<span class="source-line-no">2408</span><span id="line-2408">          ioe);</span>
+<span class="source-line-no">2409</span><span id="line-2409">        if (pause) {</span>
+<span class="source-line-no">2410</span><span id="line-2410">          Threads.sleep(pauseTime);</span>
 <span class="source-line-no">2411</span><span id="line-2411">        }</span>
-<span class="source-line-no">2412</span><span id="line-2412">      }</span>
-<span class="source-line-no">2413</span><span id="line-2413">    }</span>
-<span class="source-line-no">2414</span><span id="line-2414">    return false;</span>
-<span class="source-line-no">2415</span><span id="line-2415">  }</span>
-<span class="source-line-no">2416</span><span id="line-2416"></span>
-<span class="source-line-no">2417</span><span id="line-2417">  /**</span>
-<span class="source-line-no">2418</span><span id="line-2418">   * Trigger a flush in the primary region replica if this region is a secondary replica. Does not</span>
-<span class="source-line-no">2419</span><span id="line-2419">   * block this thread. See RegionReplicaFlushHandler for details.</span>
-<span class="source-line-no">2420</span><span id="line-2420">   */</span>
-<span class="source-line-no">2421</span><span id="line-2421">  private void triggerFlushInPrimaryRegion(final HRegion region) {</span>
-<span class="source-line-no">2422</span><span id="line-2422">    if (ServerRegionReplicaUtil.isDefaultReplica(region.getRegionInfo())) {</span>
-<span class="source-line-no">2423</span><span id="line-2423">      return;</span>
-<span class="source-line-no">2424</span><span id="line-2424">    }</span>
-<span class="source-line-no">2425</span><span id="line-2425">    TableName tn = region.getTableDescriptor().getTableName();</span>
-<span class="source-line-no">2426</span><span id="line-2426">    if (</span>
-<span class="source-line-no">2427</span><span id="line-2427">      !ServerRegionReplicaUtil.isRegionReplicaReplicationEnabled(region.conf, tn)</span>
-<span class="source-line-no">2428</span><span id="line-2428">        || !ServerRegionReplicaUtil.isRegionReplicaWaitForPrimaryFlushEnabled(region.conf) ||</span>
-<span class="source-line-no">2429</span><span id="line-2429">        // If the memstore replication not setup, we do not have to wait for observing a flush event</span>
-<span class="source-line-no">2430</span><span id="line-2430">        // from primary before starting to serve reads, because gaps from replication is not</span>
-<span class="source-line-no">2431</span><span id="line-2431">        // applicable,this logic is from</span>
-<span class="source-line-no">2432</span><span id="line-2432">        // TableDescriptorBuilder.ModifyableTableDescriptor.setRegionMemStoreReplication by</span>
-<span class="source-line-no">2433</span><span id="line-2433">        // HBASE-13063</span>
-<span class="source-line-no">2434</span><span id="line-2434">        !region.getTableDescriptor().hasRegionMemStoreReplication()</span>
-<span class="source-line-no">2435</span><span id="line-2435">    ) {</span>
-<span class="source-line-no">2436</span><span id="line-2436">      region.setReadsEnabled(true);</span>
-<span class="source-line-no">2437</span><span id="line-2437">      return;</span>
-<span class="source-line-no">2438</span><span id="line-2438">    }</span>
-<span class="source-line-no">2439</span><span id="line-2439"></span>
-<span class="source-line-no">2440</span><span id="line-2440">    region.setReadsEnabled(false); // disable reads before marking the region as opened.</span>
-<span class="source-line-no">2441</span><span id="line-2441">    // RegionReplicaFlushHandler might reset this.</span>
-<span class="source-line-no">2442</span><span id="line-2442"></span>
-<span class="source-line-no">2443</span><span id="line-2443">    // Submit it to be handled by one of the handlers so that we do not block OpenRegionHandler</span>
-<span class="source-line-no">2444</span><span id="line-2444">    if (this.executorService != null) {</span>
-<span class="source-line-no">2445</span><span id="line-2445">      this.executorService.submit(new RegionReplicaFlushHandler(this, region));</span>
-<span class="source-line-no">2446</span><span id="line-2446">    } else {</span>
-<span class="source-line-no">2447</span><span id="line-2447">      LOG.info("Executor is null; not running flush of primary region replica for {}",</span>
-<span class="source-line-no">2448</span><span id="line-2448">        region.getRegionInfo());</span>
-<span class="source-line-no">2449</span><span id="line-2449">    }</span>
-<span class="source-line-no">2450</span><span id="line-2450">  }</span>
-<span class="source-line-no">2451</span><span id="line-2451"></span>
-<span class="source-line-no">2452</span><span id="line-2452">  @InterfaceAudience.Private</span>
-<span class="source-line-no">2453</span><span id="line-2453">  public RSRpcServices getRSRpcServices() {</span>
-<span class="source-line-no">2454</span><span id="line-2454">    return rpcServices;</span>
-<span class="source-line-no">2455</span><span id="line-2455">  }</span>
-<span class="source-line-no">2456</span><span id="line-2456"></span>
-<span class="source-line-no">2457</span><span id="line-2457">  /**</span>
-<span class="source-line-no">2458</span><span id="line-2458">   * Cause the server to exit without closing the regions it is serving, the log it is using and</span>
-<span class="source-line-no">2459</span><span id="line-2459">   * without notifying the master. Used unit testing and on catastrophic events such as HDFS is</span>
-<span class="source-line-no">2460</span><span id="line-2460">   * yanked out from under hbase or we OOME. the reason we are aborting the exception that caused</span>
-<span class="source-line-no">2461</span><span id="line-2461">   * the abort, or null</span>
-<span class="source-line-no">2462</span><span id="line-2462">   */</span>
-<span class="source-line-no">2463</span><span id="line-2463">  @Override</span>
-<span class="source-line-no">2464</span><span id="line-2464">  public void abort(String reason, Throwable cause) {</span>
-<span class="source-line-no">2465</span><span id="line-2465">    if (!setAbortRequested()) {</span>
-<span class="source-line-no">2466</span><span id="line-2466">      // Abort already in progress, ignore the new request.</span>
-<span class="source-line-no">2467</span><span id="line-2467">      LOG.debug("Abort already in progress. Ignoring the current request with reason: {}", reason);</span>
-<span class="source-line-no">2468</span><span id="line-2468">      return;</span>
-<span class="source-line-no">2469</span><span id="line-2469">    }</span>
-<span class="source-line-no">2470</span><span id="line-2470">    String msg = "***** ABORTING region server " + this + ": " + reason + " *****";</span>
-<span class="source-line-no">2471</span><span id="line-2471">    if (cause != null) {</span>
-<span class="source-line-no">2472</span><span id="line-2472">      LOG.error(HBaseMarkers.FATAL, msg, cause);</span>
-<span class="source-line-no">2473</span><span id="line-2473">    } else {</span>
-<span class="source-line-no">2474</span><span id="line-2474">      LOG.error(HBaseMarkers.FATAL, msg);</span>
-<span class="source-line-no">2475</span><span id="line-2475">    }</span>
-<span class="source-line-no">2476</span><span id="line-2476">    // HBASE-4014: show list of coprocessors that were loaded to help debug</span>
-<span class="source-line-no">2477</span><span id="line-2477">    // regionserver crashes.Note that we're implicitly using</span>
-<span class="source-line-no">2478</span><span id="line-2478">    // java.util.HashSet's toString() method to print the coprocessor names.</span>
-<span class="source-line-no">2479</span><span id="line-2479">    LOG.error(HBaseMarkers.FATAL,</span>
-<span class="source-line-no">2480</span><span id="line-2480">      "RegionServer abort: loaded coprocessors are: " + CoprocessorHost.getLoadedCoprocessors());</span>
-<span class="source-line-no">2481</span><span id="line-2481">    // Try and dump metrics if abort -- might give clue as to how fatal came about....</span>
-<span class="source-line-no">2482</span><span id="line-2482">    try {</span>
-<span class="source-line-no">2483</span><span id="line-2483">      LOG.info("Dump of metrics as JSON on abort: " + DumpRegionServerMetrics.dumpMetrics());</span>
-<span class="source-line-no">2484</span><span id="line-2484">    } catch (MalformedObjectNameException | IOException e) {</span>
-<span class="source-line-no">2485</span><span id="line-2485">      LOG.warn("Failed dumping metrics", e);</span>
-<span class="source-line-no">2486</span><span id="line-2486">    }</span>
-<span class="source-line-no">2487</span><span id="line-2487"></span>
-<span class="source-line-no">2488</span><span id="line-2488">    // Do our best to report our abort to the master, but this may not work</span>
-<span class="source-line-no">2489</span><span id="line-2489">    try {</span>
-<span class="source-line-no">2490</span><span id="line-2490">      if (cause != null) {</span>
-<span class="source-line-no">2491</span><span id="line-2491">        msg += "\nCause:\n" + Throwables.getStackTraceAsString(cause);</span>
-<span class="source-line-no">2492</span><span id="line-2492">      }</span>
-<span class="source-line-no">2493</span><span id="line-2493">      // Report to the master but only if we have already registered with the master.</span>
-<span class="source-line-no">2494</span><span id="line-2494">      RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">2495</span><span id="line-2495">      if (rss != null &amp;&amp; this.serverName != null) {</span>
-<span class="source-line-no">2496</span><span id="line-2496">        ReportRSFatalErrorRequest.Builder builder = ReportRSFatalErrorRequest.newBuilder();</span>
-<span class="source-line-no">2497</span><span id="line-2497">        builder.setServer(ProtobufUtil.toServerName(this.serverName));</span>
-<span class="source-line-no">2498</span><span id="line-2498">        builder.setErrorMessage(msg);</span>
-<span class="source-line-no">2499</span><span id="line-2499">        rss.reportRSFatalError(null, builder.build());</span>
-<span class="source-line-no">2500</span><span id="line-2500">      }</span>
-<span class="source-line-no">2501</span><span id="line-2501">    } catch (Throwable t) {</span>
-<span class="source-line-no">2502</span><span id="line-2502">      LOG.warn("Unable to report fatal error to master", t);</span>
-<span class="source-line-no">2503</span><span id="line-2503">    }</span>
-<span class="source-line-no">2504</span><span id="line-2504"></span>
-<span class="source-line-no">2505</span><span id="line-2505">    scheduleAbortTimer();</span>
-<span class="source-line-no">2506</span><span id="line-2506">    // shutdown should be run as the internal user</span>
-<span class="source-line-no">2507</span><span id="line-2507">    stop(reason, true, null);</span>
-<span class="source-line-no">2508</span><span id="line-2508">  }</span>
-<span class="source-line-no">2509</span><span id="line-2509"></span>
-<span class="source-line-no">2510</span><span id="line-2510">  /*</span>
-<span class="source-line-no">2511</span><span id="line-2511">   * Simulate a kill -9 of this server. Exits w/o closing regions or cleaninup logs but it does</span>
-<span class="source-line-no">2512</span><span id="line-2512">   * close socket in case want to bring up server on old hostname+port immediately.</span>
-<span class="source-line-no">2513</span><span id="line-2513">   */</span>
-<span class="source-line-no">2514</span><span id="line-2514">  @InterfaceAudience.Private</span>
-<span class="source-line-no">2515</span><span id="line-2515">  protected void kill() {</span>
-<span class="source-line-no">2516</span><span id="line-2516">    this.killed = true;</span>
-<span class="source-line-no">2517</span><span id="line-2517">    abort("Simulated kill");</span>
-<span class="source-line-no">2518</span><span id="line-2518">  }</span>
-<span class="source-line-no">2519</span><span id="line-2519"></span>
-<span class="source-line-no">2520</span><span id="line-2520">  // Limits the time spent in the shutdown process.</span>
-<span class="source-line-no">2521</span><span id="line-2521">  private void scheduleAbortTimer() {</span>
-<span class="source-line-no">2522</span><span id="line-2522">    if (this.abortMonitor == null) {</span>
-<span class="source-line-no">2523</span><span id="line-2523">      this.abortMonitor = new Timer("Abort regionserver monitor", true);</span>
-<span class="source-line-no">2524</span><span id="line-2524">      TimerTask abortTimeoutTask = null;</span>
-<span class="source-line-no">2525</span><span id="line-2525">      try {</span>
-<span class="source-line-no">2526</span><span id="line-2526">        Constructor&lt;? extends TimerTask&gt; timerTaskCtor =</span>
-<span class="source-line-no">2527</span><span id="line-2527">          Class.forName(conf.get(ABORT_TIMEOUT_TASK, SystemExitWhenAbortTimeout.class.getName()))</span>
-<span class="source-line-no">2528</span><span id="line-2528">            .asSubclass(TimerTask.class).getDeclaredConstructor();</span>
-<span class="source-line-no">2529</span><span id="line-2529">        timerTaskCtor.setAccessible(true);</span>
-<span class="source-line-no">2530</span><span id="line-2530">        abortTimeoutTask = timerTaskCtor.newInstance();</span>
-<span class="source-line-no">2531</span><span id="line-2531">      } catch (Exception e) {</span>
-<span class="source-line-no">2532</span><span id="line-2532">        LOG.warn("Initialize abort timeout task failed", e);</span>
-<span class="source-line-no">2533</span><span id="line-2533">      }</span>
-<span class="source-line-no">2534</span><span id="line-2534">      if (abortTimeoutTask != null) {</span>
-<span class="source-line-no">2535</span><span id="line-2535">        abortMonitor.schedule(abortTimeoutTask, conf.getLong(ABORT_TIMEOUT, DEFAULT_ABORT_TIMEOUT));</span>
-<span class="source-line-no">2536</span><span id="line-2536">      }</span>
-<span class="source-line-no">2537</span><span id="line-2537">    }</span>
-<span class="source-line-no">2538</span><span id="line-2538">  }</span>
-<span class="source-line-no">2539</span><span id="line-2539"></span>
-<span class="source-line-no">2540</span><span id="line-2540">  /**</span>
-<span class="source-line-no">2541</span><span id="line-2541">   * Wait on all threads to finish. Presumption is that all closes and stops have already been</span>
-<span class="source-line-no">2542</span><span id="line-2542">   * called.</span>
-<span class="source-line-no">2543</span><span id="line-2543">   */</span>
-<span class="source-line-no">2544</span><span id="line-2544">  protected void stopServiceThreads() {</span>
-<span class="source-line-no">2545</span><span id="line-2545">    // clean up the scheduled chores</span>
-<span class="source-line-no">2546</span><span id="line-2546">    stopChoreService();</span>
-<span class="source-line-no">2547</span><span id="line-2547">    if (bootstrapNodeManager != null) {</span>
-<span class="source-line-no">2548</span><span id="line-2548">      bootstrapNodeManager.stop();</span>
-<span class="source-line-no">2549</span><span id="line-2549">    }</span>
-<span class="source-line-no">2550</span><span id="line-2550">    if (this.cacheFlusher != null) {</span>
-<span class="source-line-no">2551</span><span id="line-2551">      this.cacheFlusher.shutdown();</span>
-<span class="source-line-no">2552</span><span id="line-2552">    }</span>
-<span class="source-line-no">2553</span><span id="line-2553">    if (this.walRoller != null) {</span>
-<span class="source-line-no">2554</span><span id="line-2554">      this.walRoller.close();</span>
-<span class="source-line-no">2555</span><span id="line-2555">    }</span>
-<span class="source-line-no">2556</span><span id="line-2556">    if (this.compactSplitThread != null) {</span>
-<span class="source-line-no">2557</span><span id="line-2557">      this.compactSplitThread.join();</span>
-<span class="source-line-no">2558</span><span id="line-2558">    }</span>
-<span class="source-line-no">2559</span><span id="line-2559">    stopExecutorService();</span>
-<span class="source-line-no">2560</span><span id="line-2560">    if (sameReplicationSourceAndSink &amp;&amp; this.replicationSourceHandler != null) {</span>
-<span class="source-line-no">2561</span><span id="line-2561">      this.replicationSourceHandler.stopReplicationService();</span>
-<span class="source-line-no">2562</span><span id="line-2562">    } else {</span>
-<span class="source-line-no">2563</span><span id="line-2563">      if (this.replicationSourceHandler != null) {</span>
-<span class="source-line-no">2564</span><span id="line-2564">        this.replicationSourceHandler.stopReplicationService();</span>
-<span class="source-line-no">2565</span><span id="line-2565">      }</span>
-<span class="source-line-no">2566</span><span id="line-2566">      if (this.replicationSinkHandler != null) {</span>
-<span class="source-line-no">2567</span><span id="line-2567">        this.replicationSinkHandler.stopReplicationService();</span>
-<span class="source-line-no">2568</span><span id="line-2568">      }</span>
-<span class="source-line-no">2569</span><span id="line-2569">    }</span>
-<span class="source-line-no">2570</span><span id="line-2570">  }</span>
-<span class="source-line-no">2571</span><span id="line-2571"></span>
-<span class="source-line-no">2572</span><span id="line-2572">  /** Returns Return the object that implements the replication source executorService. */</span>
-<span class="source-line-no">2573</span><span id="line-2573">  @Override</span>
-<span class="source-line-no">2574</span><span id="line-2574">  public ReplicationSourceService getReplicationSourceService() {</span>
-<span class="source-line-no">2575</span><span id="line-2575">    return replicationSourceHandler;</span>
-<span class="source-line-no">2576</span><span id="line-2576">  }</span>
-<span class="source-line-no">2577</span><span id="line-2577"></span>
-<span class="source-line-no">2578</span><span id="line-2578">  /** Returns Return the object that implements the replication sink executorService. */</span>
-<span class="source-line-no">2579</span><span id="line-2579">  public ReplicationSinkService getReplicationSinkService() {</span>
-<span class="source-line-no">2580</span><span id="line-2580">    return replicationSinkHandler;</span>
-<span class="source-line-no">2581</span><span id="line-2581">  }</span>
-<span class="source-line-no">2582</span><span id="line-2582"></span>
-<span class="source-line-no">2583</span><span id="line-2583">  /**</span>
-<span class="source-line-no">2584</span><span id="line-2584">   * Get the current master from ZooKeeper and open the RPC connection to it. To get a fresh</span>
-<span class="source-line-no">2585</span><span id="line-2585">   * connection, the current rssStub must be null. Method will block until a master is available.</span>
-<span class="source-line-no">2586</span><span id="line-2586">   * You can break from this block by requesting the server stop.</span>
-<span class="source-line-no">2587</span><span id="line-2587">   * @return master + port, or null if server has been stopped</span>
-<span class="source-line-no">2588</span><span id="line-2588">   */</span>
-<span class="source-line-no">2589</span><span id="line-2589">  private synchronized ServerName createRegionServerStatusStub() {</span>
-<span class="source-line-no">2590</span><span id="line-2590">    // Create RS stub without refreshing the master node from ZK, use cached data</span>
-<span class="source-line-no">2591</span><span id="line-2591">    return createRegionServerStatusStub(false);</span>
-<span class="source-line-no">2592</span><span id="line-2592">  }</span>
-<span class="source-line-no">2593</span><span id="line-2593"></span>
-<span class="source-line-no">2594</span><span id="line-2594">  /**</span>
-<span class="source-line-no">2595</span><span id="line-2595">   * Get the current master from ZooKeeper and open the RPC connection to it. To get a fresh</span>
-<span class="source-line-no">2596</span><span id="line-2596">   * connection, the current rssStub must be null. Method will block until a master is available.</span>
-<span class="source-line-no">2597</span><span id="line-2597">   * You can break from this block by requesting the server stop.</span>
-<span class="source-line-no">2598</span><span id="line-2598">   * @param refresh If true then master address will be read from ZK, otherwise use cached data</span>
-<span class="source-line-no">2599</span><span id="line-2599">   * @return master + port, or null if server has been stopped</span>
-<span class="source-line-no">2600</span><span id="line-2600">   */</span>
-<span class="source-line-no">2601</span><span id="line-2601">  @InterfaceAudience.Private</span>
-<span class="source-line-no">2602</span><span id="line-2602">  protected synchronized ServerName createRegionServerStatusStub(boolean refresh) {</span>
-<span class="source-line-no">2603</span><span id="line-2603">    if (rssStub != null) {</span>
-<span class="source-line-no">2604</span><span id="line-2604">      return masterAddressTracker.getMasterAddress();</span>
-<span class="source-line-no">2605</span><span id="line-2605">    }</span>
-<span class="source-line-no">2606</span><span id="line-2606">    ServerName sn = null;</span>
-<span class="source-line-no">2607</span><span id="line-2607">    long previousLogTime = 0;</span>
-<span class="source-line-no">2608</span><span id="line-2608">    RegionServerStatusService.BlockingInterface intRssStub = null;</span>
-<span class="source-line-no">2609</span><span id="line-2609">    LockService.BlockingInterface intLockStub = null;</span>
-<span class="source-line-no">2610</span><span id="line-2610">    boolean interrupted = false;</span>
-<span class="source-line-no">2611</span><span id="line-2611">    try {</span>
-<span class="source-line-no">2612</span><span id="line-2612">      while (keepLooping()) {</span>
-<span class="source-line-no">2613</span><span id="line-2613">        sn = this.masterAddressTracker.getMasterAddress(refresh);</span>
-<span class="source-line-no">2614</span><span id="line-2614">        if (sn == null) {</span>
-<span class="source-line-no">2615</span><span id="line-2615">          if (!keepLooping()) {</span>
-<span class="source-line-no">2616</span><span id="line-2616">            // give up with no connection.</span>
-<span class="source-line-no">2617</span><span id="line-2617">            LOG.debug("No master found and cluster is stopped; bailing out");</span>
-<span class="source-line-no">2618</span><span id="line-2618">            return null;</span>
-<span class="source-line-no">2619</span><span id="line-2619">          }</span>
-<span class="source-line-no">2620</span><span id="line-2620">          if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {</span>
-<span class="source-line-no">2621</span><span id="line-2621">            LOG.debug("No master found; retry");</span>
-<span class="source-line-no">2622</span><span id="line-2622">            previousLogTime = EnvironmentEdgeManager.currentTime();</span>
+<span class="source-line-no">2412</span><span id="line-2412">        tries++;</span>
+<span class="source-line-no">2413</span><span id="line-2413">        if (rssStub == rss) {</span>
+<span class="source-line-no">2414</span><span id="line-2414">          rssStub = null;</span>
+<span class="source-line-no">2415</span><span id="line-2415">        }</span>
+<span class="source-line-no">2416</span><span id="line-2416">      }</span>
+<span class="source-line-no">2417</span><span id="line-2417">    }</span>
+<span class="source-line-no">2418</span><span id="line-2418">    return false;</span>
+<span class="source-line-no">2419</span><span id="line-2419">  }</span>
+<span class="source-line-no">2420</span><span id="line-2420"></span>
+<span class="source-line-no">2421</span><span id="line-2421">  /**</span>
+<span class="source-line-no">2422</span><span id="line-2422">   * Trigger a flush in the primary region replica if this region is a secondary replica. Does not</span>
+<span class="source-line-no">2423</span><span id="line-2423">   * block this thread. See RegionReplicaFlushHandler for details.</span>
+<span class="source-line-no">2424</span><span id="line-2424">   */</span>
+<span class="source-line-no">2425</span><span id="line-2425">  private void triggerFlushInPrimaryRegion(final HRegion region) {</span>
+<span class="source-line-no">2426</span><span id="line-2426">    if (ServerRegionReplicaUtil.isDefaultReplica(region.getRegionInfo())) {</span>
+<span class="source-line-no">2427</span><span id="line-2427">      return;</span>
+<span class="source-line-no">2428</span><span id="line-2428">    }</span>
+<span class="source-line-no">2429</span><span id="line-2429">    TableName tn = region.getTableDescriptor().getTableName();</span>
+<span class="source-line-no">2430</span><span id="line-2430">    if (</span>
+<span class="source-line-no">2431</span><span id="line-2431">      !ServerRegionReplicaUtil.isRegionReplicaReplicationEnabled(region.conf, tn)</span>
+<span class="source-line-no">2432</span><span id="line-2432">        || !ServerRegionReplicaUtil.isRegionReplicaWaitForPrimaryFlushEnabled(region.conf) ||</span>
+<span class="source-line-no">2433</span><span id="line-2433">        // If the memstore replication not setup, we do not have to wait for observing a flush event</span>
+<span class="source-line-no">2434</span><span id="line-2434">        // from primary before starting to serve reads, because gaps from replication is not</span>
+<span class="source-line-no">2435</span><span id="line-2435">        // applicable,this logic is from</span>
+<span class="source-line-no">2436</span><span id="line-2436">        // TableDescriptorBuilder.ModifyableTableDescriptor.setRegionMemStoreReplication by</span>
+<span class="source-line-no">2437</span><span id="line-2437">        // HBASE-13063</span>
+<span class="source-line-no">2438</span><span id="line-2438">        !region.getTableDescriptor().hasRegionMemStoreReplication()</span>
+<span class="source-line-no">2439</span><span id="line-2439">    ) {</span>
+<span class="source-line-no">2440</span><span id="line-2440">      region.setReadsEnabled(true);</span>
+<span class="source-line-no">2441</span><span id="line-2441">      return;</span>
+<span class="source-line-no">2442</span><span id="line-2442">    }</span>
+<span class="source-line-no">2443</span><span id="line-2443"></span>
+<span class="source-line-no">2444</span><span id="line-2444">    region.setReadsEnabled(false); // disable reads before marking the region as opened.</span>
+<span class="source-line-no">2445</span><span id="line-2445">    // RegionReplicaFlushHandler might reset this.</span>
+<span class="source-line-no">2446</span><span id="line-2446"></span>
+<span class="source-line-no">2447</span><span id="line-2447">    // Submit it to be handled by one of the handlers so that we do not block OpenRegionHandler</span>
+<span class="source-line-no">2448</span><span id="line-2448">    if (this.executorService != null) {</span>
+<span class="source-line-no">2449</span><span id="line-2449">      this.executorService.submit(new RegionReplicaFlushHandler(this, region));</span>
+<span class="source-line-no">2450</span><span id="line-2450">    } else {</span>
+<span class="source-line-no">2451</span><span id="line-2451">      LOG.info("Executor is null; not running flush of primary region replica for {}",</span>
+<span class="source-line-no">2452</span><span id="line-2452">        region.getRegionInfo());</span>
+<span class="source-line-no">2453</span><span id="line-2453">    }</span>
+<span class="source-line-no">2454</span><span id="line-2454">  }</span>
+<span class="source-line-no">2455</span><span id="line-2455"></span>
+<span class="source-line-no">2456</span><span id="line-2456">  @InterfaceAudience.Private</span>
+<span class="source-line-no">2457</span><span id="line-2457">  public RSRpcServices getRSRpcServices() {</span>
+<span class="source-line-no">2458</span><span id="line-2458">    return rpcServices;</span>
+<span class="source-line-no">2459</span><span id="line-2459">  }</span>
+<span class="source-line-no">2460</span><span id="line-2460"></span>
+<span class="source-line-no">2461</span><span id="line-2461">  /**</span>
+<span class="source-line-no">2462</span><span id="line-2462">   * Cause the server to exit without closing the regions it is serving, the log it is using and</span>
+<span class="source-line-no">2463</span><span id="line-2463">   * without notifying the master. Used unit testing and on catastrophic events such as HDFS is</span>
+<span class="source-line-no">2464</span><span id="line-2464">   * yanked out from under hbase or we OOME. the reason we are aborting the exception that caused</span>
+<span class="source-line-no">2465</span><span id="line-2465">   * the abort, or null</span>
+<span class="source-line-no">2466</span><span id="line-2466">   */</span>
+<span class="source-line-no">2467</span><span id="line-2467">  @Override</span>
+<span class="source-line-no">2468</span><span id="line-2468">  public void abort(String reason, Throwable cause) {</span>
+<span class="source-line-no">2469</span><span id="line-2469">    if (!setAbortRequested()) {</span>
+<span class="source-line-no">2470</span><span id="line-2470">      // Abort already in progress, ignore the new request.</span>
+<span class="source-line-no">2471</span><span id="line-2471">      LOG.debug("Abort already in progress. Ignoring the current request with reason: {}", reason);</span>
+<span class="source-line-no">2472</span><span id="line-2472">      return;</span>
+<span class="source-line-no">2473</span><span id="line-2473">    }</span>
+<span class="source-line-no">2474</span><span id="line-2474">    String msg = "***** ABORTING region server " + this + ": " + reason + " *****";</span>
+<span class="source-line-no">2475</span><span id="line-2475">    if (cause != null) {</span>
+<span class="source-line-no">2476</span><span id="line-2476">      LOG.error(HBaseMarkers.FATAL, msg, cause);</span>
+<span class="source-line-no">2477</span><span id="line-2477">    } else {</span>
+<span class="source-line-no">2478</span><span id="line-2478">      LOG.error(HBaseMarkers.FATAL, msg);</span>
+<span class="source-line-no">2479</span><span id="line-2479">    }</span>
+<span class="source-line-no">2480</span><span id="line-2480">    // HBASE-4014: show list of coprocessors that were loaded to help debug</span>
+<span class="source-line-no">2481</span><span id="line-2481">    // regionserver crashes.Note that we're implicitly using</span>
+<span class="source-line-no">2482</span><span id="line-2482">    // java.util.HashSet's toString() method to print the coprocessor names.</span>
+<span class="source-line-no">2483</span><span id="line-2483">    LOG.error(HBaseMarkers.FATAL,</span>
+<span class="source-line-no">2484</span><span id="line-2484">      "RegionServer abort: loaded coprocessors are: " + CoprocessorHost.getLoadedCoprocessors());</span>
+<span class="source-line-no">2485</span><span id="line-2485">    // Try and dump metrics if abort -- might give clue as to how fatal came about....</span>
+<span class="source-line-no">2486</span><span id="line-2486">    try {</span>
+<span class="source-line-no">2487</span><span id="line-2487">      LOG.info("Dump of metrics as JSON on abort: " + DumpRegionServerMetrics.dumpMetrics());</span>
+<span class="source-line-no">2488</span><span id="line-2488">    } catch (MalformedObjectNameException | IOException e) {</span>
+<span class="source-line-no">2489</span><span id="line-2489">      LOG.warn("Failed dumping metrics", e);</span>
+<span class="source-line-no">2490</span><span id="line-2490">    }</span>
+<span class="source-line-no">2491</span><span id="line-2491"></span>
+<span class="source-line-no">2492</span><span id="line-2492">    // Do our best to report our abort to the master, but this may not work</span>
+<span class="source-line-no">2493</span><span id="line-2493">    try {</span>
+<span class="source-line-no">2494</span><span id="line-2494">      if (cause != null) {</span>
+<span class="source-line-no">2495</span><span id="line-2495">        msg += "\nCause:\n" + Throwables.getStackTraceAsString(cause);</span>
+<span class="source-line-no">2496</span><span id="line-2496">      }</span>
+<span class="source-line-no">2497</span><span id="line-2497">      // Report to the master but only if we have already registered with the master.</span>
+<span class="source-line-no">2498</span><span id="line-2498">      RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">2499</span><span id="line-2499">      if (rss != null &amp;&amp; this.serverName != null) {</span>
+<span class="source-line-no">2500</span><span id="line-2500">        ReportRSFatalErrorRequest.Builder builder = ReportRSFatalErrorRequest.newBuilder();</span>
+<span class="source-line-no">2501</span><span id="line-2501">        builder.setServer(ProtobufUtil.toServerName(this.serverName));</span>
+<span class="source-line-no">2502</span><span id="line-2502">        builder.setErrorMessage(msg);</span>
+<span class="source-line-no">2503</span><span id="line-2503">        rss.reportRSFatalError(null, builder.build());</span>
+<span class="source-line-no">2504</span><span id="line-2504">      }</span>
+<span class="source-line-no">2505</span><span id="line-2505">    } catch (Throwable t) {</span>
+<span class="source-line-no">2506</span><span id="line-2506">      LOG.warn("Unable to report fatal error to master", t);</span>
+<span class="source-line-no">2507</span><span id="line-2507">    }</span>
+<span class="source-line-no">2508</span><span id="line-2508"></span>
+<span class="source-line-no">2509</span><span id="line-2509">    scheduleAbortTimer();</span>
+<span class="source-line-no">2510</span><span id="line-2510">    // shutdown should be run as the internal user</span>
+<span class="source-line-no">2511</span><span id="line-2511">    stop(reason, true, null);</span>
+<span class="source-line-no">2512</span><span id="line-2512">  }</span>
+<span class="source-line-no">2513</span><span id="line-2513"></span>
+<span class="source-line-no">2514</span><span id="line-2514">  /*</span>
+<span class="source-line-no">2515</span><span id="line-2515">   * Simulate a kill -9 of this server. Exits w/o closing regions or cleaninup logs but it does</span>
+<span class="source-line-no">2516</span><span id="line-2516">   * close socket in case want to bring up server on old hostname+port immediately.</span>
+<span class="source-line-no">2517</span><span id="line-2517">   */</span>
+<span class="source-line-no">2518</span><span id="line-2518">  @InterfaceAudience.Private</span>
+<span class="source-line-no">2519</span><span id="line-2519">  protected void kill() {</span>
+<span class="source-line-no">2520</span><span id="line-2520">    this.killed = true;</span>
+<span class="source-line-no">2521</span><span id="line-2521">    abort("Simulated kill");</span>
+<span class="source-line-no">2522</span><span id="line-2522">  }</span>
+<span class="source-line-no">2523</span><span id="line-2523"></span>
+<span class="source-line-no">2524</span><span id="line-2524">  // Limits the time spent in the shutdown process.</span>
+<span class="source-line-no">2525</span><span id="line-2525">  private void scheduleAbortTimer() {</span>
+<span class="source-line-no">2526</span><span id="line-2526">    if (this.abortMonitor == null) {</span>
+<span class="source-line-no">2527</span><span id="line-2527">      this.abortMonitor = new Timer("Abort regionserver monitor", true);</span>
+<span class="source-line-no">2528</span><span id="line-2528">      TimerTask abortTimeoutTask = null;</span>
+<span class="source-line-no">2529</span><span id="line-2529">      try {</span>
+<span class="source-line-no">2530</span><span id="line-2530">        Constructor&lt;? extends TimerTask&gt; timerTaskCtor =</span>
+<span class="source-line-no">2531</span><span id="line-2531">          Class.forName(conf.get(ABORT_TIMEOUT_TASK, SystemExitWhenAbortTimeout.class.getName()))</span>
+<span class="source-line-no">2532</span><span id="line-2532">            .asSubclass(TimerTask.class).getDeclaredConstructor();</span>
+<span class="source-line-no">2533</span><span id="line-2533">        timerTaskCtor.setAccessible(true);</span>
+<span class="source-line-no">2534</span><span id="line-2534">        abortTimeoutTask = timerTaskCtor.newInstance();</span>
+<span class="source-line-no">2535</span><span id="line-2535">      } catch (Exception e) {</span>
+<span class="source-line-no">2536</span><span id="line-2536">        LOG.warn("Initialize abort timeout task failed", e);</span>
+<span class="source-line-no">2537</span><span id="line-2537">      }</span>
+<span class="source-line-no">2538</span><span id="line-2538">      if (abortTimeoutTask != null) {</span>
+<span class="source-line-no">2539</span><span id="line-2539">        abortMonitor.schedule(abortTimeoutTask, conf.getLong(ABORT_TIMEOUT, DEFAULT_ABORT_TIMEOUT));</span>
+<span class="source-line-no">2540</span><span id="line-2540">      }</span>
+<span class="source-line-no">2541</span><span id="line-2541">    }</span>
+<span class="source-line-no">2542</span><span id="line-2542">  }</span>
+<span class="source-line-no">2543</span><span id="line-2543"></span>
+<span class="source-line-no">2544</span><span id="line-2544">  /**</span>
+<span class="source-line-no">2545</span><span id="line-2545">   * Wait on all threads to finish. Presumption is that all closes and stops have already been</span>
+<span class="source-line-no">2546</span><span id="line-2546">   * called.</span>
+<span class="source-line-no">2547</span><span id="line-2547">   */</span>
+<span class="source-line-no">2548</span><span id="line-2548">  protected void stopServiceThreads() {</span>
+<span class="source-line-no">2549</span><span id="line-2549">    // clean up the scheduled chores</span>
+<span class="source-line-no">2550</span><span id="line-2550">    stopChoreService();</span>
+<span class="source-line-no">2551</span><span id="line-2551">    if (bootstrapNodeManager != null) {</span>
+<span class="source-line-no">2552</span><span id="line-2552">      bootstrapNodeManager.stop();</span>
+<span class="source-line-no">2553</span><span id="line-2553">    }</span>
+<span class="source-line-no">2554</span><span id="line-2554">    if (this.cacheFlusher != null) {</span>
+<span class="source-line-no">2555</span><span id="line-2555">      this.cacheFlusher.shutdown();</span>
+<span class="source-line-no">2556</span><span id="line-2556">    }</span>
+<span class="source-line-no">2557</span><span id="line-2557">    if (this.walRoller != null) {</span>
+<span class="source-line-no">2558</span><span id="line-2558">      this.walRoller.close();</span>
+<span class="source-line-no">2559</span><span id="line-2559">    }</span>
+<span class="source-line-no">2560</span><span id="line-2560">    if (this.compactSplitThread != null) {</span>
+<span class="source-line-no">2561</span><span id="line-2561">      this.compactSplitThread.join();</span>
+<span class="source-line-no">2562</span><span id="line-2562">    }</span>
+<span class="source-line-no">2563</span><span id="line-2563">    stopExecutorService();</span>
+<span class="source-line-no">2564</span><span id="line-2564">    if (sameReplicationSourceAndSink &amp;&amp; this.replicationSourceHandler != null) {</span>
+<span class="source-line-no">2565</span><span id="line-2565">      this.replicationSourceHandler.stopReplicationService();</span>
+<span class="source-line-no">2566</span><span id="line-2566">    } else {</span>
+<span class="source-line-no">2567</span><span id="line-2567">      if (this.replicationSourceHandler != null) {</span>
+<span class="source-line-no">2568</span><span id="line-2568">        this.replicationSourceHandler.stopReplicationService();</span>
+<span class="source-line-no">2569</span><span id="line-2569">      }</span>
+<span class="source-line-no">2570</span><span id="line-2570">      if (this.replicationSinkHandler != null) {</span>
+<span class="source-line-no">2571</span><span id="line-2571">        this.replicationSinkHandler.stopReplicationService();</span>
+<span class="source-line-no">2572</span><span id="line-2572">      }</span>
+<span class="source-line-no">2573</span><span id="line-2573">    }</span>
+<span class="source-line-no">2574</span><span id="line-2574">  }</span>
+<span class="source-line-no">2575</span><span id="line-2575"></span>
+<span class="source-line-no">2576</span><span id="line-2576">  /** Returns Return the object that implements the replication source executorService. */</span>
+<span class="source-line-no">2577</span><span id="line-2577">  @Override</span>
+<span class="source-line-no">2578</span><span id="line-2578">  public ReplicationSourceService getReplicationSourceService() {</span>
+<span class="source-line-no">2579</span><span id="line-2579">    return replicationSourceHandler;</span>
+<span class="source-line-no">2580</span><span id="line-2580">  }</span>
+<span class="source-line-no">2581</span><span id="line-2581"></span>
+<span class="source-line-no">2582</span><span id="line-2582">  /** Returns Return the object that implements the replication sink executorService. */</span>
+<span class="source-line-no">2583</span><span id="line-2583">  public ReplicationSinkService getReplicationSinkService() {</span>
+<span class="source-line-no">2584</span><span id="line-2584">    return replicationSinkHandler;</span>
+<span class="source-line-no">2585</span><span id="line-2585">  }</span>
+<span class="source-line-no">2586</span><span id="line-2586"></span>
+<span class="source-line-no">2587</span><span id="line-2587">  /**</span>
+<span class="source-line-no">2588</span><span id="line-2588">   * Get the current master from ZooKeeper and open the RPC connection to it. To get a fresh</span>
+<span class="source-line-no">2589</span><span id="line-2589">   * connection, the current rssStub must be null. Method will block until a master is available.</span>
+<span class="source-line-no">2590</span><span id="line-2590">   * You can break from this block by requesting the server stop.</span>
+<span class="source-line-no">2591</span><span id="line-2591">   * @return master + port, or null if server has been stopped</span>
+<span class="source-line-no">2592</span><span id="line-2592">   */</span>
+<span class="source-line-no">2593</span><span id="line-2593">  private synchronized ServerName createRegionServerStatusStub() {</span>
+<span class="source-line-no">2594</span><span id="line-2594">    // Create RS stub without refreshing the master node from ZK, use cached data</span>
+<span class="source-line-no">2595</span><span id="line-2595">    return createRegionServerStatusStub(false);</span>
+<span class="source-line-no">2596</span><span id="line-2596">  }</span>
+<span class="source-line-no">2597</span><span id="line-2597"></span>
+<span class="source-line-no">2598</span><span id="line-2598">  /**</span>
+<span class="source-line-no">2599</span><span id="line-2599">   * Get the current master from ZooKeeper and open the RPC connection to it. To get a fresh</span>
+<span class="source-line-no">2600</span><span id="line-2600">   * connection, the current rssStub must be null. Method will block until a master is available.</span>
+<span class="source-line-no">2601</span><span id="line-2601">   * You can break from this block by requesting the server stop.</span>
+<span class="source-line-no">2602</span><span id="line-2602">   * @param refresh If true then master address will be read from ZK, otherwise use cached data</span>
+<span class="source-line-no">2603</span><span id="line-2603">   * @return master + port, or null if server has been stopped</span>
+<span class="source-line-no">2604</span><span id="line-2604">   */</span>
+<span class="source-line-no">2605</span><span id="line-2605">  @InterfaceAudience.Private</span>
+<span class="source-line-no">2606</span><span id="line-2606">  protected synchronized ServerName createRegionServerStatusStub(boolean refresh) {</span>
+<span class="source-line-no">2607</span><span id="line-2607">    if (rssStub != null) {</span>
+<span class="source-line-no">2608</span><span id="line-2608">      return masterAddressTracker.getMasterAddress();</span>
+<span class="source-line-no">2609</span><span id="line-2609">    }</span>
+<span class="source-line-no">2610</span><span id="line-2610">    ServerName sn = null;</span>
+<span class="source-line-no">2611</span><span id="line-2611">    long previousLogTime = 0;</span>
+<span class="source-line-no">2612</span><span id="line-2612">    RegionServerStatusService.BlockingInterface intRssStub = null;</span>
+<span class="source-line-no">2613</span><span id="line-2613">    LockService.BlockingInterface intLockStub = null;</span>
+<span class="source-line-no">2614</span><span id="line-2614">    boolean interrupted = false;</span>
+<span class="source-line-no">2615</span><span id="line-2615">    try {</span>
+<span class="source-line-no">2616</span><span id="line-2616">      while (keepLooping()) {</span>
+<span class="source-line-no">2617</span><span id="line-2617">        sn = this.masterAddressTracker.getMasterAddress(refresh);</span>
+<span class="source-line-no">2618</span><span id="line-2618">        if (sn == null) {</span>
+<span class="source-line-no">2619</span><span id="line-2619">          if (!keepLooping()) {</span>
+<span class="source-line-no">2620</span><span id="line-2620">            // give up with no connection.</span>
+<span class="source-line-no">2621</span><span id="line-2621">            LOG.debug("No master found and cluster is stopped; bailing out");</span>
+<span class="source-line-no">2622</span><span id="line-2622">            return null;</span>
 <span class="source-line-no">2623</span><span id="line-2623">          }</span>
-<span class="source-line-no">2624</span><span id="line-2624">          refresh = true; // let's try pull it from ZK directly</span>
-<span class="source-line-no">2625</span><span id="line-2625">          if (sleepInterrupted(200)) {</span>
-<span class="source-line-no">2626</span><span id="line-2626">            interrupted = true;</span>
+<span class="source-line-no">2624</span><span id="line-2624">          if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {</span>
+<span class="source-line-no">2625</span><span id="line-2625">            LOG.debug("No master found; retry");</span>
+<span class="source-line-no">2626</span><span id="line-2626">            previousLogTime = EnvironmentEdgeManager.currentTime();</span>
 <span class="source-line-no">2627</span><span id="line-2627">          }</span>
-<span class="source-line-no">2628</span><span id="line-2628">          continue;</span>
-<span class="source-line-no">2629</span><span id="line-2629">        }</span>
-<span class="source-line-no">2630</span><span id="line-2630">        try {</span>
-<span class="source-line-no">2631</span><span id="line-2631">          BlockingRpcChannel channel = this.rpcClient.createBlockingRpcChannel(sn,</span>
-<span class="source-line-no">2632</span><span id="line-2632">            userProvider.getCurrent(), shortOperationTimeout);</span>
-<span class="source-line-no">2633</span><span id="line-2633">          intRssStub = RegionServerStatusService.newBlockingStub(channel);</span>
-<span class="source-line-no">2634</span><span id="line-2634">          intLockStub = LockService.newBlockingStub(channel);</span>
-<span class="source-line-no">2635</span><span id="line-2635">          break;</span>
-<span class="source-line-no">2636</span><span id="line-2636">        } catch (IOException e) {</span>
-<span class="source-line-no">2637</span><span id="line-2637">          if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {</span>
-<span class="source-line-no">2638</span><span id="line-2638">            e = e instanceof RemoteException ? ((RemoteException) e).unwrapRemoteException() : e;</span>
-<span class="source-line-no">2639</span><span id="line-2639">            if (e instanceof ServerNotRunningYetException) {</span>
-<span class="source-line-no">2640</span><span id="line-2640">              LOG.info("Master isn't available yet, retrying");</span>
-<span class="source-line-no">2641</span><span id="line-2641">            } else {</span>
-<span class="source-line-no">2642</span><span id="line-2642">              LOG.warn("Unable to connect to master. Retrying. Error was:", e);</span>
-<span class="source-line-no">2643</span><span id="line-2643">            }</span>
-<span class="source-line-no">2644</span><span id="line-2644">            previousLogTime = EnvironmentEdgeManager.currentTime();</span>
-<span class="source-line-no">2645</span><span id="line-2645">          }</span>
-<span class="source-line-no">2646</span><span id="line-2646">          if (sleepInterrupted(200)) {</span>
-<span class="source-line-no">2647</span><span id="line-2647">            interrupted = true;</span>
-<span class="source-line-no">2648</span><span id="line-2648">          }</span>
-<span class="source-line-no">2649</span><span id="line-2649">        }</span>
-<span class="source-line-no">2650</span><span id="line-2650">      }</span>
-<span class="source-line-no">2651</span><span id="line-2651">    } finally {</span>
-<span class="source-line-no">2652</span><span id="line-2652">      if (interrupted) {</span>
-<span class="source-line-no">2653</span><span id="line-2653">        Thread.currentThread().interrupt();</span>
+<span class="source-line-no">2628</span><span id="line-2628">          refresh = true; // let's try pull it from ZK directly</span>
+<span class="source-line-no">2629</span><span id="line-2629">          if (sleepInterrupted(200)) {</span>
+<span class="source-line-no">2630</span><span id="line-2630">            interrupted = true;</span>
+<span class="source-line-no">2631</span><span id="line-2631">          }</span>
+<span class="source-line-no">2632</span><span id="line-2632">          continue;</span>
+<span class="source-line-no">2633</span><span id="line-2633">        }</span>
+<span class="source-line-no">2634</span><span id="line-2634">        try {</span>
+<span class="source-line-no">2635</span><span id="line-2635">          BlockingRpcChannel channel = this.rpcClient.createBlockingRpcChannel(sn,</span>
+<span class="source-line-no">2636</span><span id="line-2636">            userProvider.getCurrent(), shortOperationTimeout);</span>
+<span class="source-line-no">2637</span><span id="line-2637">          intRssStub = RegionServerStatusService.newBlockingStub(channel);</span>
+<span class="source-line-no">2638</span><span id="line-2638">          intLockStub = LockService.newBlockingStub(channel);</span>
+<span class="source-line-no">2639</span><span id="line-2639">          break;</span>
+<span class="source-line-no">2640</span><span id="line-2640">        } catch (IOException e) {</span>
+<span class="source-line-no">2641</span><span id="line-2641">          if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {</span>
+<span class="source-line-no">2642</span><span id="line-2642">            e = e instanceof RemoteException ? ((RemoteException) e).unwrapRemoteException() : e;</span>
+<span class="source-line-no">2643</span><span id="line-2643">            if (e instanceof ServerNotRunningYetException) {</span>
+<span class="source-line-no">2644</span><span id="line-2644">              LOG.info("Master isn't available yet, retrying");</span>
+<span class="source-line-no">2645</span><span id="line-2645">            } else {</span>
+<span class="source-line-no">2646</span><span id="line-2646">              LOG.warn("Unable to connect to master. Retrying. Error was:", e);</span>
+<span class="source-line-no">2647</span><span id="line-2647">            }</span>
+<span class="source-line-no">2648</span><span id="line-2648">            previousLogTime = EnvironmentEdgeManager.currentTime();</span>
+<span class="source-line-no">2649</span><span id="line-2649">          }</span>
+<span class="source-line-no">2650</span><span id="line-2650">          if (sleepInterrupted(200)) {</span>
+<span class="source-line-no">2651</span><span id="line-2651">            interrupted = true;</span>
+<span class="source-line-no">2652</span><span id="line-2652">          }</span>
+<span class="source-line-no">2653</span><span id="line-2653">        }</span>
 <span class="source-line-no">2654</span><span id="line-2654">      }</span>
-<span class="source-line-no">2655</span><span id="line-2655">    }</span>
-<span class="source-line-no">2656</span><span id="line-2656">    this.rssStub = intRssStub;</span>
-<span class="source-line-no">2657</span><span id="line-2657">    this.lockStub = intLockStub;</span>
-<span class="source-line-no">2658</span><span id="line-2658">    return sn;</span>
-<span class="source-line-no">2659</span><span id="line-2659">  }</span>
-<span class="source-line-no">2660</span><span id="line-2660"></span>
-<span class="source-line-no">2661</span><span id="line-2661">  /**</span>
-<span class="source-line-no">2662</span><span id="line-2662">   * @return True if we should break loop because cluster is going down or this server has been</span>
-<span class="source-line-no">2663</span><span id="line-2663">   *         stopped or hdfs has gone bad.</span>
-<span class="source-line-no">2664</span><span id="line-2664">   */</span>
-<span class="source-line-no">2665</span><span id="line-2665">  private boolean keepLooping() {</span>
-<span class="source-line-no">2666</span><span id="line-2666">    return !this.stopped &amp;&amp; isClusterUp();</span>
-<span class="source-line-no">2667</span><span id="line-2667">  }</span>
-<span class="source-line-no">2668</span><span id="line-2668"></span>
-<span class="source-line-no">2669</span><span id="line-2669">  /*</span>
-<span class="source-line-no">2670</span><span id="line-2670">   * Let the master know we're here Run initialization using parameters passed us by the master.</span>
-<span class="source-line-no">2671</span><span id="line-2671">   * @return A Map of key/value configurations we got from the Master else null if we failed to</span>
-<span class="source-line-no">2672</span><span id="line-2672">   * register.</span>
-<span class="source-line-no">2673</span><span id="line-2673">   */</span>
-<span class="source-line-no">2674</span><span id="line-2674">  private RegionServerStartupResponse reportForDuty() throws IOException {</span>
-<span class="source-line-no">2675</span><span id="line-2675">    if (this.masterless) {</span>
-<span class="source-line-no">2676</span><span id="line-2676">      return RegionServerStartupResponse.getDefaultInstance();</span>
-<span class="source-line-no">2677</span><span id="line-2677">    }</span>
-<span class="source-line-no">2678</span><span id="line-2678">    ServerName masterServerName = createRegionServerStatusStub(true);</span>
-<span class="source-line-no">2679</span><span id="line-2679">    RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">2680</span><span id="line-2680">    if (masterServerName == null || rss == null) {</span>
-<span class="source-line-no">2681</span><span id="line-2681">      return null;</span>
-<span class="source-line-no">2682</span><span id="line-2682">    }</span>
-<span class="source-line-no">2683</span><span id="line-2683">    RegionServerStartupResponse result = null;</span>
-<span class="source-line-no">2684</span><span id="line-2684">    try {</span>
-<span class="source-line-no">2685</span><span id="line-2685">      rpcServices.requestCount.reset();</span>
-<span class="source-line-no">2686</span><span id="line-2686">      rpcServices.rpcGetRequestCount.reset();</span>
-<span class="source-line-no">2687</span><span id="line-2687">      rpcServices.rpcScanRequestCount.reset();</span>
-<span class="source-line-no">2688</span><span id="line-2688">      rpcServices.rpcFullScanRequestCount.reset();</span>
-<span class="source-line-no">2689</span><span id="line-2689">      rpcServices.rpcMultiRequestCount.reset();</span>
-<span class="source-line-no">2690</span><span id="line-2690">      rpcServices.rpcMutateRequestCount.reset();</span>
-<span class="source-line-no">2691</span><span id="line-2691">      LOG.info("reportForDuty to master=" + masterServerName + " with port="</span>
-<span class="source-line-no">2692</span><span id="line-2692">        + rpcServices.getSocketAddress().getPort() + ", startcode=" + this.startcode);</span>
-<span class="source-line-no">2693</span><span id="line-2693">      long now = EnvironmentEdgeManager.currentTime();</span>
-<span class="source-line-no">2694</span><span id="line-2694">      int port = rpcServices.getSocketAddress().getPort();</span>
-<span class="source-line-no">2695</span><span id="line-2695">      RegionServerStartupRequest.Builder request = RegionServerStartupRequest.newBuilder();</span>
-<span class="source-line-no">2696</span><span id="line-2696">      if (!StringUtils.isBlank(useThisHostnameInstead)) {</span>
-<span class="source-line-no">2697</span><span id="line-2697">        request.setUseThisHostnameInstead(useThisHostnameInstead);</span>
-<span class="source-line-no">2698</span><span id="line-2698">      }</span>
-<span class="source-line-no">2699</span><span id="line-2699">      request.setPort(port);</span>
-<span class="source-line-no">2700</span><span id="line-2700">      request.setServerStartCode(this.startcode);</span>
-<span class="source-line-no">2701</span><span id="line-2701">      request.setServerCurrentTime(now);</span>
-<span class="source-line-no">2702</span><span id="line-2702">      result = rss.regionServerStartup(null, request.build());</span>
-<span class="source-line-no">2703</span><span id="line-2703">    } catch (ServiceException se) {</span>
-<span class="source-line-no">2704</span><span id="line-2704">      IOException ioe = ProtobufUtil.getRemoteException(se);</span>
-<span class="source-line-no">2705</span><span id="line-2705">      if (ioe instanceof ClockOutOfSyncException) {</span>
-<span class="source-line-no">2706</span><span id="line-2706">        LOG.error(HBaseMarkers.FATAL, "Master rejected startup because clock is out of sync", ioe);</span>
-<span class="source-line-no">2707</span><span id="line-2707">        // Re-throw IOE will cause RS to abort</span>
-<span class="source-line-no">2708</span><span id="line-2708">        throw ioe;</span>
-<span class="source-line-no">2709</span><span id="line-2709">      } else if (ioe instanceof DecommissionedHostRejectedException) {</span>
-<span class="source-line-no">2710</span><span id="line-2710">        LOG.error(HBaseMarkers.FATAL,</span>
-<span class="source-line-no">2711</span><span id="line-2711">          "Master rejected startup because the host is considered decommissioned", ioe);</span>
-<span class="source-line-no">2712</span><span id="line-2712">        // Re-throw IOE will cause RS to abort</span>
-<span class="source-line-no">2713</span><span id="line-2713">        throw ioe;</span>
-<span class="source-line-no">2714</span><span id="line-2714">      } else if (ioe instanceof ServerNotRunningYetException) {</span>
-<span class="source-line-no">2715</span><span id="line-2715">        LOG.debug("Master is not running yet");</span>
-<span class="source-line-no">2716</span><span id="line-2716">      } else {</span>
-<span class="source-line-no">2717</span><span id="line-2717">        LOG.warn("error telling master we are up", se);</span>
-<span class="source-line-no">2718</span><span id="line-2718">      }</span>
-<span class="source-line-no">2719</span><span id="line-2719">      rssStub = null;</span>
-<span class="source-line-no">2720</span><span id="line-2720">    }</span>
-<span class="source-line-no">2721</span><span id="line-2721">    return result;</span>
-<span class="source-line-no">2722</span><span id="line-2722">  }</span>
-<span class="source-line-no">2723</span><span id="line-2723"></span>
-<span class="source-line-no">2724</span><span id="line-2724">  @Override</span>
-<span class="source-line-no">2725</span><span id="line-2725">  public RegionStoreSequenceIds getLastSequenceId(byte[] encodedRegionName) {</span>
-<span class="source-line-no">2726</span><span id="line-2726">    try {</span>
-<span class="source-line-no">2727</span><span id="line-2727">      GetLastFlushedSequenceIdRequest req =</span>
-<span class="source-line-no">2728</span><span id="line-2728">        RequestConverter.buildGetLastFlushedSequenceIdRequest(encodedRegionName);</span>
-<span class="source-line-no">2729</span><span id="line-2729">      RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">2730</span><span id="line-2730">      if (rss == null) { // Try to connect one more time</span>
-<span class="source-line-no">2731</span><span id="line-2731">        createRegionServerStatusStub();</span>
-<span class="source-line-no">2732</span><span id="line-2732">        rss = rssStub;</span>
-<span class="source-line-no">2733</span><span id="line-2733">        if (rss == null) {</span>
-<span class="source-line-no">2734</span><span id="line-2734">          // Still no luck, we tried</span>
-<span class="source-line-no">2735</span><span id="line-2735">          LOG.warn("Unable to connect to the master to check " + "the last flushed sequence id");</span>
-<span class="source-line-no">2736</span><span id="line-2736">          return RegionStoreSequenceIds.newBuilder().setLastFlushedSequenceId(HConstants.NO_SEQNUM)</span>
-<span class="source-line-no">2737</span><span id="line-2737">            .build();</span>
-<span class="source-line-no">2738</span><span id="line-2738">        }</span>
-<span class="source-line-no">2739</span><span id="line-2739">      }</span>
-<span class="source-line-no">2740</span><span id="line-2740">      GetLastFlushedSequenceIdResponse resp = rss.getLastFlushedSequenceId(null, req);</span>
-<span class="source-line-no">2741</span><span id="line-2741">      return RegionStoreSequenceIds.newBuilder()</span>
-<span class="source-line-no">2742</span><span id="line-2742">        .setLastFlushedSequenceId(resp.getLastFlushedSequenceId())</span>
-<span class="source-line-no">2743</span><span id="line-2743">        .addAllStoreSequenceId(resp.getStoreLastFlushedSequenceIdList()).build();</span>
-<span class="source-line-no">2744</span><span id="line-2744">    } catch (ServiceException e) {</span>
-<span class="source-line-no">2745</span><span id="line-2745">      LOG.warn("Unable to connect to the master to check the last flushed sequence id", e);</span>
-<span class="source-line-no">2746</span><span id="line-2746">      return RegionStoreSequenceIds.newBuilder().setLastFlushedSequenceId(HConstants.NO_SEQNUM)</span>
-<span class="source-line-no">2747</span><span id="line-2747">        .build();</span>
-<span class="source-line-no">2748</span><span id="line-2748">    }</span>
-<span class="source-line-no">2749</span><span id="line-2749">  }</span>
-<span class="source-line-no">2750</span><span id="line-2750"></span>
-<span class="source-line-no">2751</span><span id="line-2751">  /**</span>
-<span class="source-line-no">2752</span><span id="line-2752">   * Close meta region if we carry it</span>
-<span class="source-line-no">2753</span><span id="line-2753">   * @param abort Whether we're running an abort.</span>
-<span class="source-line-no">2754</span><span id="line-2754">   */</span>
-<span class="source-line-no">2755</span><span id="line-2755">  private void closeMetaTableRegions(final boolean abort) {</span>
-<span class="source-line-no">2756</span><span id="line-2756">    HRegion meta = null;</span>
-<span class="source-line-no">2757</span><span id="line-2757">    this.onlineRegionsLock.writeLock().lock();</span>
-<span class="source-line-no">2758</span><span id="line-2758">    try {</span>
-<span class="source-line-no">2759</span><span id="line-2759">      for (Map.Entry&lt;String, HRegion&gt; e : onlineRegions.entrySet()) {</span>
-<span class="source-line-no">2760</span><span id="line-2760">        RegionInfo hri = e.getValue().getRegionInfo();</span>
-<span class="source-line-no">2761</span><span id="line-2761">        if (hri.isMetaRegion()) {</span>
-<span class="source-line-no">2762</span><span id="line-2762">          meta = e.getValue();</span>
-<span class="source-line-no">2763</span><span id="line-2763">        }</span>
-<span class="source-line-no">2764</span><span id="line-2764">        if (meta != null) {</span>
-<span class="source-line-no">2765</span><span id="line-2765">          break;</span>
-<span class="source-line-no">2766</span><span id="line-2766">        }</span>
-<span class="source-line-no">2767</span><span id="line-2767">      }</span>
-<span class="source-line-no">2768</span><span id="line-2768">    } finally {</span>
-<span class="source-line-no">2769</span><span id="line-2769">      this.onlineRegionsLock.writeLock().unlock();</span>
-<span class="source-line-no">2770</span><span id="line-2770">    }</span>
-<span class="source-line-no">2771</span><span id="line-2771">    if (meta != null) {</span>
-<span class="source-line-no">2772</span><span id="line-2772">      closeRegionIgnoreErrors(meta.getRegionInfo(), abort);</span>
-<span class="source-line-no">2773</span><span id="line-2773">    }</span>
-<span class="source-line-no">2774</span><span id="line-2774">  }</span>
-<span class="source-line-no">2775</span><span id="line-2775"></span>
-<span class="source-line-no">2776</span><span id="line-2776">  /**</span>
-<span class="source-line-no">2777</span><span id="line-2777">   * Schedule closes on all user regions. Should be safe calling multiple times because it wont'</span>
-<span class="source-line-no">2778</span><span id="line-2778">   * close regions that are already closed or that are closing.</span>
-<span class="source-line-no">2779</span><span id="line-2779">   * @param abort Whether we're running an abort.</span>
-<span class="source-line-no">2780</span><span id="line-2780">   */</span>
-<span class="source-line-no">2781</span><span id="line-2781">  private void closeUserRegions(final boolean abort) {</span>
-<span class="source-line-no">2782</span><span id="line-2782">    this.onlineRegionsLock.writeLock().lock();</span>
-<span class="source-line-no">2783</span><span id="line-2783">    try {</span>
-<span class="source-line-no">2784</span><span id="line-2784">      for (Map.Entry&lt;String, HRegion&gt; e : this.onlineRegions.entrySet()) {</span>
-<span class="source-line-no">2785</span><span id="line-2785">        HRegion r = e.getValue();</span>
-<span class="source-line-no">2786</span><span id="line-2786">        if (!r.getRegionInfo().isMetaRegion() &amp;&amp; r.isAvailable()) {</span>
-<span class="source-line-no">2787</span><span id="line-2787">          // Don't update zk with this close transition; pass false.</span>
-<span class="source-line-no">2788</span><span id="line-2788">          closeRegionIgnoreErrors(r.getRegionInfo(), abort);</span>
-<span class="source-line-no">2789</span><span id="line-2789">        }</span>
-<span class="source-line-no">2790</span><span id="line-2790">      }</span>
-<span class="source-line-no">2791</span><span id="line-2791">    } finally {</span>
-<span class="source-line-no">2792</span><span id="line-2792">      this.onlineRegionsLock.writeLock().unlock();</span>
-<span class="source-line-no">2793</span><span id="line-2793">    }</span>
-<span class="source-line-no">2794</span><span id="line-2794">  }</span>
-<span class="source-line-no">2795</span><span id="line-2795"></span>
-<span class="source-line-no">2796</span><span id="line-2796">  protected Map&lt;String, HRegion&gt; getOnlineRegions() {</span>
-<span class="source-line-no">2797</span><span id="line-2797">    return this.onlineRegions;</span>
+<span class="source-line-no">2655</span><span id="line-2655">    } finally {</span>
+<span class="source-line-no">2656</span><span id="line-2656">      if (interrupted) {</span>
+<span class="source-line-no">2657</span><span id="line-2657">        Thread.currentThread().interrupt();</span>
+<span class="source-line-no">2658</span><span id="line-2658">      }</span>
+<span class="source-line-no">2659</span><span id="line-2659">    }</span>
+<span class="source-line-no">2660</span><span id="line-2660">    this.rssStub = intRssStub;</span>
+<span class="source-line-no">2661</span><span id="line-2661">    this.lockStub = intLockStub;</span>
+<span class="source-line-no">2662</span><span id="line-2662">    return sn;</span>
+<span class="source-line-no">2663</span><span id="line-2663">  }</span>
+<span class="source-line-no">2664</span><span id="line-2664"></span>
+<span class="source-line-no">2665</span><span id="line-2665">  /**</span>
+<span class="source-line-no">2666</span><span id="line-2666">   * @return True if we should break loop because cluster is going down or this server has been</span>
+<span class="source-line-no">2667</span><span id="line-2667">   *         stopped or hdfs has gone bad.</span>
+<span class="source-line-no">2668</span><span id="line-2668">   */</span>
+<span class="source-line-no">2669</span><span id="line-2669">  private boolean keepLooping() {</span>
+<span class="source-line-no">2670</span><span id="line-2670">    return !this.stopped &amp;&amp; isClusterUp();</span>
+<span class="source-line-no">2671</span><span id="line-2671">  }</span>
+<span class="source-line-no">2672</span><span id="line-2672"></span>
+<span class="source-line-no">2673</span><span id="line-2673">  /*</span>
+<span class="source-line-no">2674</span><span id="line-2674">   * Let the master know we're here Run initialization using parameters passed us by the master.</span>
+<span class="source-line-no">2675</span><span id="line-2675">   * @return A Map of key/value configurations we got from the Master else null if we failed to</span>
+<span class="source-line-no">2676</span><span id="line-2676">   * register.</span>
+<span class="source-line-no">2677</span><span id="line-2677">   */</span>
+<span class="source-line-no">2678</span><span id="line-2678">  private RegionServerStartupResponse reportForDuty() throws IOException {</span>
+<span class="source-line-no">2679</span><span id="line-2679">    if (this.masterless) {</span>
+<span class="source-line-no">2680</span><span id="line-2680">      return RegionServerStartupResponse.getDefaultInstance();</span>
+<span class="source-line-no">2681</span><span id="line-2681">    }</span>
+<span class="source-line-no">2682</span><span id="line-2682">    ServerName masterServerName = createRegionServerStatusStub(true);</span>
+<span class="source-line-no">2683</span><span id="line-2683">    RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">2684</span><span id="line-2684">    if (masterServerName == null || rss == null) {</span>
+<span class="source-line-no">2685</span><span id="line-2685">      return null;</span>
+<span class="source-line-no">2686</span><span id="line-2686">    }</span>
+<span class="source-line-no">2687</span><span id="line-2687">    RegionServerStartupResponse result = null;</span>
+<span class="source-line-no">2688</span><span id="line-2688">    try {</span>
+<span class="source-line-no">2689</span><span id="line-2689">      rpcServices.requestCount.reset();</span>
+<span class="source-line-no">2690</span><span id="line-2690">      rpcServices.rpcGetRequestCount.reset();</span>
+<span class="source-line-no">2691</span><span id="line-2691">      rpcServices.rpcScanRequestCount.reset();</span>
+<span class="source-line-no">2692</span><span id="line-2692">      rpcServices.rpcFullScanRequestCount.reset();</span>
+<span class="source-line-no">2693</span><span id="line-2693">      rpcServices.rpcMultiRequestCount.reset();</span>
+<span class="source-line-no">2694</span><span id="line-2694">      rpcServices.rpcMutateRequestCount.reset();</span>
+<span class="source-line-no">2695</span><span id="line-2695">      LOG.info("reportForDuty to master=" + masterServerName + " with port="</span>
+<span class="source-line-no">2696</span><span id="line-2696">        + rpcServices.getSocketAddress().getPort() + ", startcode=" + this.startcode);</span>
+<span class="source-line-no">2697</span><span id="line-2697">      long now = EnvironmentEdgeManager.currentTime();</span>
+<span class="source-line-no">2698</span><span id="line-2698">      int port = rpcServices.getSocketAddress().getPort();</span>
+<span class="source-line-no">2699</span><span id="line-2699">      RegionServerStartupRequest.Builder request = RegionServerStartupRequest.newBuilder();</span>
+<span class="source-line-no">2700</span><span id="line-2700">      if (!StringUtils.isBlank(useThisHostnameInstead)) {</span>
+<span class="source-line-no">2701</span><span id="line-2701">        request.setUseThisHostnameInstead(useThisHostnameInstead);</span>
+<span class="source-line-no">2702</span><span id="line-2702">      }</span>
+<span class="source-line-no">2703</span><span id="line-2703">      request.setPort(port);</span>
+<span class="source-line-no">2704</span><span id="line-2704">      request.setServerStartCode(this.startcode);</span>
+<span class="source-line-no">2705</span><span id="line-2705">      request.setServerCurrentTime(now);</span>
+<span class="source-line-no">2706</span><span id="line-2706">      result = rss.regionServerStartup(null, request.build());</span>
+<span class="source-line-no">2707</span><span id="line-2707">    } catch (ServiceException se) {</span>
+<span class="source-line-no">2708</span><span id="line-2708">      IOException ioe = ProtobufUtil.getRemoteException(se);</span>
+<span class="source-line-no">2709</span><span id="line-2709">      if (ioe instanceof ClockOutOfSyncException) {</span>
+<span class="source-line-no">2710</span><span id="line-2710">        LOG.error(HBaseMarkers.FATAL, "Master rejected startup because clock is out of sync", ioe);</span>
+<span class="source-line-no">2711</span><span id="line-2711">        // Re-throw IOE will cause RS to abort</span>
+<span class="source-line-no">2712</span><span id="line-2712">        throw ioe;</span>
+<span class="source-line-no">2713</span><span id="line-2713">      } else if (ioe instanceof DecommissionedHostRejectedException) {</span>
+<span class="source-line-no">2714</span><span id="line-2714">        LOG.error(HBaseMarkers.FATAL,</span>
+<span class="source-line-no">2715</span><span id="line-2715">          "Master rejected startup because the host is considered decommissioned", ioe);</span>
+<span class="source-line-no">2716</span><span id="line-2716">        // Re-throw IOE will cause RS to abort</span>
+<span class="source-line-no">2717</span><span id="line-2717">        throw ioe;</span>
+<span class="source-line-no">2718</span><span id="line-2718">      } else if (ioe instanceof ServerNotRunningYetException) {</span>
+<span class="source-line-no">2719</span><span id="line-2719">        LOG.debug("Master is not running yet");</span>
+<span class="source-line-no">2720</span><span id="line-2720">      } else {</span>
+<span class="source-line-no">2721</span><span id="line-2721">        LOG.warn("error telling master we are up", se);</span>
+<span class="source-line-no">2722</span><span id="line-2722">      }</span>
+<span class="source-line-no">2723</span><span id="line-2723">      rssStub = null;</span>
+<span class="source-line-no">2724</span><span id="line-2724">    }</span>
+<span class="source-line-no">2725</span><span id="line-2725">    return result;</span>
+<span class="source-line-no">2726</span><span id="line-2726">  }</span>
+<span class="source-line-no">2727</span><span id="line-2727"></span>
+<span class="source-line-no">2728</span><span id="line-2728">  @Override</span>
+<span class="source-line-no">2729</span><span id="line-2729">  public RegionStoreSequenceIds getLastSequenceId(byte[] encodedRegionName) {</span>
+<span class="source-line-no">2730</span><span id="line-2730">    try {</span>
+<span class="source-line-no">2731</span><span id="line-2731">      GetLastFlushedSequenceIdRequest req =</span>
+<span class="source-line-no">2732</span><span id="line-2732">        RequestConverter.buildGetLastFlushedSequenceIdRequest(encodedRegionName);</span>
+<span class="source-line-no">2733</span><span id="line-2733">      RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">2734</span><span id="line-2734">      if (rss == null) { // Try to connect one more time</span>
+<span class="source-line-no">2735</span><span id="line-2735">        createRegionServerStatusStub();</span>
+<span class="source-line-no">2736</span><span id="line-2736">        rss = rssStub;</span>
+<span class="source-line-no">2737</span><span id="line-2737">        if (rss == null) {</span>
+<span class="source-line-no">2738</span><span id="line-2738">          // Still no luck, we tried</span>
+<span class="source-line-no">2739</span><span id="line-2739">          LOG.warn("Unable to connect to the master to check " + "the last flushed sequence id");</span>
+<span class="source-line-no">2740</span><span id="line-2740">          return RegionStoreSequenceIds.newBuilder().setLastFlushedSequenceId(HConstants.NO_SEQNUM)</span>
+<span class="source-line-no">2741</span><span id="line-2741">            .build();</span>
+<span class="source-line-no">2742</span><span id="line-2742">        }</span>
+<span class="source-line-no">2743</span><span id="line-2743">      }</span>
+<span class="source-line-no">2744</span><span id="line-2744">      GetLastFlushedSequenceIdResponse resp = rss.getLastFlushedSequenceId(null, req);</span>
+<span class="source-line-no">2745</span><span id="line-2745">      return RegionStoreSequenceIds.newBuilder()</span>
+<span class="source-line-no">2746</span><span id="line-2746">        .setLastFlushedSequenceId(resp.getLastFlushedSequenceId())</span>
+<span class="source-line-no">2747</span><span id="line-2747">        .addAllStoreSequenceId(resp.getStoreLastFlushedSequenceIdList()).build();</span>
+<span class="source-line-no">2748</span><span id="line-2748">    } catch (ServiceException e) {</span>
+<span class="source-line-no">2749</span><span id="line-2749">      LOG.warn("Unable to connect to the master to check the last flushed sequence id", e);</span>
+<span class="source-line-no">2750</span><span id="line-2750">      return RegionStoreSequenceIds.newBuilder().setLastFlushedSequenceId(HConstants.NO_SEQNUM)</span>
+<span class="source-line-no">2751</span><span id="line-2751">        .build();</span>
+<span class="source-line-no">2752</span><span id="line-2752">    }</span>
+<span class="source-line-no">2753</span><span id="line-2753">  }</span>
+<span class="source-line-no">2754</span><span id="line-2754"></span>
+<span class="source-line-no">2755</span><span id="line-2755">  /**</span>
+<span class="source-line-no">2756</span><span id="line-2756">   * Close meta region if we carry it</span>
+<span class="source-line-no">2757</span><span id="line-2757">   * @param abort Whether we're running an abort.</span>
+<span class="source-line-no">2758</span><span id="line-2758">   */</span>
+<span class="source-line-no">2759</span><span id="line-2759">  private void closeMetaTableRegions(final boolean abort) {</span>
+<span class="source-line-no">2760</span><span id="line-2760">    HRegion meta = null;</span>
+<span class="source-line-no">2761</span><span id="line-2761">    this.onlineRegionsLock.writeLock().lock();</span>
+<span class="source-line-no">2762</span><span id="line-2762">    try {</span>
+<span class="source-line-no">2763</span><span id="line-2763">      for (Map.Entry&lt;String, HRegion&gt; e : onlineRegions.entrySet()) {</span>
+<span class="source-line-no">2764</span><span id="line-2764">        RegionInfo hri = e.getValue().getRegionInfo();</span>
+<span class="source-line-no">2765</span><span id="line-2765">        if (hri.isMetaRegion()) {</span>
+<span class="source-line-no">2766</span><span id="line-2766">          meta = e.getValue();</span>
+<span class="source-line-no">2767</span><span id="line-2767">        }</span>
+<span class="source-line-no">2768</span><span id="line-2768">        if (meta != null) {</span>
+<span class="source-line-no">2769</span><span id="line-2769">          break;</span>
+<span class="source-line-no">2770</span><span id="line-2770">        }</span>
+<span class="source-line-no">2771</span><span id="line-2771">      }</span>
+<span class="source-line-no">2772</span><span id="line-2772">    } finally {</span>
+<span class="source-line-no">2773</span><span id="line-2773">      this.onlineRegionsLock.writeLock().unlock();</span>
+<span class="source-line-no">2774</span><span id="line-2774">    }</span>
+<span class="source-line-no">2775</span><span id="line-2775">    if (meta != null) {</span>
+<span class="source-line-no">2776</span><span id="line-2776">      closeRegionIgnoreErrors(meta.getRegionInfo(), abort);</span>
+<span class="source-line-no">2777</span><span id="line-2777">    }</span>
+<span class="source-line-no">2778</span><span id="line-2778">  }</span>
+<span class="source-line-no">2779</span><span id="line-2779"></span>
+<span class="source-line-no">2780</span><span id="line-2780">  /**</span>
+<span class="source-line-no">2781</span><span id="line-2781">   * Schedule closes on all user regions. Should be safe calling multiple times because it wont'</span>
+<span class="source-line-no">2782</span><span id="line-2782">   * close regions that are already closed or that are closing.</span>
+<span class="source-line-no">2783</span><span id="line-2783">   * @param abort Whether we're running an abort.</span>
+<span class="source-line-no">2784</span><span id="line-2784">   */</span>
+<span class="source-line-no">2785</span><span id="line-2785">  private void closeUserRegions(final boolean abort) {</span>
+<span class="source-line-no">2786</span><span id="line-2786">    this.onlineRegionsLock.writeLock().lock();</span>
+<span class="source-line-no">2787</span><span id="line-2787">    try {</span>
+<span class="source-line-no">2788</span><span id="line-2788">      for (Map.Entry&lt;String, HRegion&gt; e : this.onlineRegions.entrySet()) {</span>
+<span class="source-line-no">2789</span><span id="line-2789">        HRegion r = e.getValue();</span>
+<span class="source-line-no">2790</span><span id="line-2790">        if (!r.getRegionInfo().isMetaRegion() &amp;&amp; r.isAvailable()) {</span>
+<span class="source-line-no">2791</span><span id="line-2791">          // Don't update zk with this close transition; pass false.</span>
+<span class="source-line-no">2792</span><span id="line-2792">          closeRegionIgnoreErrors(r.getRegionInfo(), abort);</span>
+<span class="source-line-no">2793</span><span id="line-2793">        }</span>
+<span class="source-line-no">2794</span><span id="line-2794">      }</span>
+<span class="source-line-no">2795</span><span id="line-2795">    } finally {</span>
+<span class="source-line-no">2796</span><span id="line-2796">      this.onlineRegionsLock.writeLock().unlock();</span>
+<span class="source-line-no">2797</span><span id="line-2797">    }</span>
 <span class="source-line-no">2798</span><span id="line-2798">  }</span>
 <span class="source-line-no">2799</span><span id="line-2799"></span>
-<span class="source-line-no">2800</span><span id="line-2800">  public int getNumberOfOnlineRegions() {</span>
-<span class="source-line-no">2801</span><span id="line-2801">    return this.onlineRegions.size();</span>
+<span class="source-line-no">2800</span><span id="line-2800">  protected Map&lt;String, HRegion&gt; getOnlineRegions() {</span>
+<span class="source-line-no">2801</span><span id="line-2801">    return this.onlineRegions;</span>
 <span class="source-line-no">2802</span><span id="line-2802">  }</span>
 <span class="source-line-no">2803</span><span id="line-2803"></span>
-<span class="source-line-no">2804</span><span id="line-2804">  /**</span>
-<span class="source-line-no">2805</span><span id="line-2805">   * For tests, web ui and metrics. This method will only work if HRegionServer is in the same JVM</span>
-<span class="source-line-no">2806</span><span id="line-2806">   * as client; HRegion cannot be serialized to cross an rpc.</span>
-<span class="source-line-no">2807</span><span id="line-2807">   */</span>
-<span class="source-line-no">2808</span><span id="line-2808">  public Collection&lt;HRegion&gt; getOnlineRegionsLocalContext() {</span>
-<span class="source-line-no">2809</span><span id="line-2809">    Collection&lt;HRegion&gt; regions = this.onlineRegions.values();</span>
-<span class="source-line-no">2810</span><span id="line-2810">    return Collections.unmodifiableCollection(regions);</span>
-<span class="source-line-no">2811</span><span id="line-2811">  }</span>
-<span class="source-line-no">2812</span><span id="line-2812"></span>
-<span class="source-line-no">2813</span><span id="line-2813">  @Override</span>
-<span class="source-line-no">2814</span><span id="line-2814">  public void addRegion(HRegion region) {</span>
-<span class="source-line-no">2815</span><span id="line-2815">    this.onlineRegions.put(region.getRegionInfo().getEncodedName(), region);</span>
-<span class="source-line-no">2816</span><span id="line-2816">    configurationManager.registerObserver(region);</span>
-<span class="source-line-no">2817</span><span id="line-2817">  }</span>
-<span class="source-line-no">2818</span><span id="line-2818"></span>
-<span class="source-line-no">2819</span><span id="line-2819">  private void addRegion(SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; sortedRegions, HRegion region,</span>
-<span class="source-line-no">2820</span><span id="line-2820">    long size) {</span>
-<span class="source-line-no">2821</span><span id="line-2821">    if (!sortedRegions.containsKey(size)) {</span>
-<span class="source-line-no">2822</span><span id="line-2822">      sortedRegions.put(size, new ArrayList&lt;&gt;());</span>
-<span class="source-line-no">2823</span><span id="line-2823">    }</span>
-<span class="source-line-no">2824</span><span id="line-2824">    sortedRegions.get(size).add(region);</span>
-<span class="source-line-no">2825</span><span id="line-2825">  }</span>
-<span class="source-line-no">2826</span><span id="line-2826"></span>
-<span class="source-line-no">2827</span><span id="line-2827">  /**</span>
-<span class="source-line-no">2828</span><span id="line-2828">   * @return A new Map of online regions sorted by region off-heap size with the first entry being</span>
-<span class="source-line-no">2829</span><span id="line-2829">   *         the biggest.</span>
-<span class="source-line-no">2830</span><span id="line-2830">   */</span>
-<span class="source-line-no">2831</span><span id="line-2831">  SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; getCopyOfOnlineRegionsSortedByOffHeapSize() {</span>
-<span class="source-line-no">2832</span><span id="line-2832">    // we'll sort the regions in reverse</span>
-<span class="source-line-no">2833</span><span id="line-2833">    SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; sortedRegions = new TreeMap&lt;&gt;(Comparator.reverseOrder());</span>
-<span class="source-line-no">2834</span><span id="line-2834">    // Copy over all regions. Regions are sorted by size with biggest first.</span>
-<span class="source-line-no">2835</span><span id="line-2835">    for (HRegion region : this.onlineRegions.values()) {</span>
-<span class="source-line-no">2836</span><span id="line-2836">      addRegion(sortedRegions, region, region.getMemStoreOffHeapSize());</span>
-<span class="source-line-no">2837</span><span id="line-2837">    }</span>
-<span class="source-line-no">2838</span><span id="line-2838">    return sortedRegions;</span>
-<span class="source-line-no">2839</span><span id="line-2839">  }</span>
-<span class="source-line-no">2840</span><span id="line-2840"></span>
-<span class="source-line-no">2841</span><span id="line-2841">  /**</span>
-<span class="source-line-no">2842</span><span id="line-2842">   * @return A new Map of online regions sorted by region heap size with the first entry being the</span>
-<span class="source-line-no">2843</span><span id="line-2843">   *         biggest.</span>
-<span class="source-line-no">2844</span><span id="line-2844">   */</span>
-<span class="source-line-no">2845</span><span id="line-2845">  SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; getCopyOfOnlineRegionsSortedByOnHeapSize() {</span>
-<span class="source-line-no">2846</span><span id="line-2846">    // we'll sort the regions in reverse</span>
-<span class="source-line-no">2847</span><span id="line-2847">    SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; sortedRegions = new TreeMap&lt;&gt;(Comparator.reverseOrder());</span>
-<span class="source-line-no">2848</span><span id="line-2848">    // Copy over all regions. Regions are sorted by size with biggest first.</span>
-<span class="source-line-no">2849</span><span id="line-2849">    for (HRegion region : this.onlineRegions.values()) {</span>
-<span class="source-line-no">2850</span><span id="line-2850">      addRegion(sortedRegions, region, region.getMemStoreHeapSize());</span>
-<span class="source-line-no">2851</span><span id="line-2851">    }</span>
-<span class="source-line-no">2852</span><span id="line-2852">    return sortedRegions;</span>
-<span class="source-line-no">2853</span><span id="line-2853">  }</span>
-<span class="source-line-no">2854</span><span id="line-2854"></span>
-<span class="source-line-no">2855</span><span id="line-2855">  /** Returns reference to FlushRequester */</span>
-<span class="source-line-no">2856</span><span id="line-2856">  @Override</span>
-<span class="source-line-no">2857</span><span id="line-2857">  public FlushRequester getFlushRequester() {</span>
-<span class="source-line-no">2858</span><span id="line-2858">    return this.cacheFlusher;</span>
-<span class="source-line-no">2859</span><span id="line-2859">  }</span>
-<span class="source-line-no">2860</span><span id="line-2860"></span>
-<span class="source-line-no">2861</span><span id="line-2861">  @Override</span>
-<span class="source-line-no">2862</span><span id="line-2862">  public CompactionRequester getCompactionRequestor() {</span>
-<span class="source-line-no">2863</span><span id="line-2863">    return this.compactSplitThread;</span>
-<span class="source-line-no">2864</span><span id="line-2864">  }</span>
-<span class="source-line-no">2865</span><span id="line-2865"></span>
-<span class="source-line-no">2866</span><span id="line-2866">  @Override</span>
-<span class="source-line-no">2867</span><span id="line-2867">  public LeaseManager getLeaseManager() {</span>
-<span class="source-line-no">2868</span><span id="line-2868">    return leaseManager;</span>
-<span class="source-line-no">2869</span><span id="line-2869">  }</span>
-<span class="source-line-no">2870</span><span id="line-2870"></span>
-<span class="source-line-no">2871</span><span id="line-2871">  /** Returns {@code true} when the data file system is available, {@code false} otherwise. */</span>
-<span class="source-line-no">2872</span><span id="line-2872">  boolean isDataFileSystemOk() {</span>
-<span class="source-line-no">2873</span><span id="line-2873">    return this.dataFsOk;</span>
-<span class="source-line-no">2874</span><span id="line-2874">  }</span>
-<span class="source-line-no">2875</span><span id="line-2875"></span>
-<span class="source-line-no">2876</span><span id="line-2876">  public RegionServerCoprocessorHost getRegionServerCoprocessorHost() {</span>
-<span class="source-line-no">2877</span><span id="line-2877">    return this.rsHost;</span>
+<span class="source-line-no">2804</span><span id="line-2804">  public int getNumberOfOnlineRegions() {</span>
+<span class="source-line-no">2805</span><span id="line-2805">    return this.onlineRegions.size();</span>
+<span class="source-line-no">2806</span><span id="line-2806">  }</span>
+<span class="source-line-no">2807</span><span id="line-2807"></span>
+<span class="source-line-no">2808</span><span id="line-2808">  /**</span>
+<span class="source-line-no">2809</span><span id="line-2809">   * For tests, web ui and metrics. This method will only work if HRegionServer is in the same JVM</span>
+<span class="source-line-no">2810</span><span id="line-2810">   * as client; HRegion cannot be serialized to cross an rpc.</span>
+<span class="source-line-no">2811</span><span id="line-2811">   */</span>
+<span class="source-line-no">2812</span><span id="line-2812">  public Collection&lt;HRegion&gt; getOnlineRegionsLocalContext() {</span>
+<span class="source-line-no">2813</span><span id="line-2813">    Collection&lt;HRegion&gt; regions = this.onlineRegions.values();</span>
+<span class="source-line-no">2814</span><span id="line-2814">    return Collections.unmodifiableCollection(regions);</span>
+<span class="source-line-no">2815</span><span id="line-2815">  }</span>
+<span class="source-line-no">2816</span><span id="line-2816"></span>
+<span class="source-line-no">2817</span><span id="line-2817">  @Override</span>
+<span class="source-line-no">2818</span><span id="line-2818">  public void addRegion(HRegion region) {</span>
+<span class="source-line-no">2819</span><span id="line-2819">    this.onlineRegions.put(region.getRegionInfo().getEncodedName(), region);</span>
+<span class="source-line-no">2820</span><span id="line-2820">    configurationManager.registerObserver(region);</span>
+<span class="source-line-no">2821</span><span id="line-2821">  }</span>
+<span class="source-line-no">2822</span><span id="line-2822"></span>
+<span class="source-line-no">2823</span><span id="line-2823">  private void addRegion(SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; sortedRegions, HRegion region,</span>
+<span class="source-line-no">2824</span><span id="line-2824">    long size) {</span>
+<span class="source-line-no">2825</span><span id="line-2825">    if (!sortedRegions.containsKey(size)) {</span>
+<span class="source-line-no">2826</span><span id="line-2826">      sortedRegions.put(size, new ArrayList&lt;&gt;());</span>
+<span class="source-line-no">2827</span><span id="line-2827">    }</span>
+<span class="source-line-no">2828</span><span id="line-2828">    sortedRegions.get(size).add(region);</span>
+<span class="source-line-no">2829</span><span id="line-2829">  }</span>
+<span class="source-line-no">2830</span><span id="line-2830"></span>
+<span class="source-line-no">2831</span><span id="line-2831">  /**</span>
+<span class="source-line-no">2832</span><span id="line-2832">   * @return A new Map of online regions sorted by region off-heap size with the first entry being</span>
+<span class="source-line-no">2833</span><span id="line-2833">   *         the biggest.</span>
+<span class="source-line-no">2834</span><span id="line-2834">   */</span>
+<span class="source-line-no">2835</span><span id="line-2835">  SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; getCopyOfOnlineRegionsSortedByOffHeapSize() {</span>
+<span class="source-line-no">2836</span><span id="line-2836">    // we'll sort the regions in reverse</span>
+<span class="source-line-no">2837</span><span id="line-2837">    SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; sortedRegions = new TreeMap&lt;&gt;(Comparator.reverseOrder());</span>
+<span class="source-line-no">2838</span><span id="line-2838">    // Copy over all regions. Regions are sorted by size with biggest first.</span>
+<span class="source-line-no">2839</span><span id="line-2839">    for (HRegion region : this.onlineRegions.values()) {</span>
+<span class="source-line-no">2840</span><span id="line-2840">      addRegion(sortedRegions, region, region.getMemStoreOffHeapSize());</span>
+<span class="source-line-no">2841</span><span id="line-2841">    }</span>
+<span class="source-line-no">2842</span><span id="line-2842">    return sortedRegions;</span>
+<span class="source-line-no">2843</span><span id="line-2843">  }</span>
+<span class="source-line-no">2844</span><span id="line-2844"></span>
+<span class="source-line-no">2845</span><span id="line-2845">  /**</span>
+<span class="source-line-no">2846</span><span id="line-2846">   * @return A new Map of online regions sorted by region heap size with the first entry being the</span>
+<span class="source-line-no">2847</span><span id="line-2847">   *         biggest.</span>
+<span class="source-line-no">2848</span><span id="line-2848">   */</span>
+<span class="source-line-no">2849</span><span id="line-2849">  SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; getCopyOfOnlineRegionsSortedByOnHeapSize() {</span>
+<span class="source-line-no">2850</span><span id="line-2850">    // we'll sort the regions in reverse</span>
+<span class="source-line-no">2851</span><span id="line-2851">    SortedMap&lt;Long, Collection&lt;HRegion&gt;&gt; sortedRegions = new TreeMap&lt;&gt;(Comparator.reverseOrder());</span>
+<span class="source-line-no">2852</span><span id="line-2852">    // Copy over all regions. Regions are sorted by size with biggest first.</span>
+<span class="source-line-no">2853</span><span id="line-2853">    for (HRegion region : this.onlineRegions.values()) {</span>
+<span class="source-line-no">2854</span><span id="line-2854">      addRegion(sortedRegions, region, region.getMemStoreHeapSize());</span>
+<span class="source-line-no">2855</span><span id="line-2855">    }</span>
+<span class="source-line-no">2856</span><span id="line-2856">    return sortedRegions;</span>
+<span class="source-line-no">2857</span><span id="line-2857">  }</span>
+<span class="source-line-no">2858</span><span id="line-2858"></span>
+<span class="source-line-no">2859</span><span id="line-2859">  /** Returns reference to FlushRequester */</span>
+<span class="source-line-no">2860</span><span id="line-2860">  @Override</span>
+<span class="source-line-no">2861</span><span id="line-2861">  public FlushRequester getFlushRequester() {</span>
+<span class="source-line-no">2862</span><span id="line-2862">    return this.cacheFlusher;</span>
+<span class="source-line-no">2863</span><span id="line-2863">  }</span>
+<span class="source-line-no">2864</span><span id="line-2864"></span>
+<span class="source-line-no">2865</span><span id="line-2865">  @Override</span>
+<span class="source-line-no">2866</span><span id="line-2866">  public CompactionRequester getCompactionRequestor() {</span>
+<span class="source-line-no">2867</span><span id="line-2867">    return this.compactSplitThread;</span>
+<span class="source-line-no">2868</span><span id="line-2868">  }</span>
+<span class="source-line-no">2869</span><span id="line-2869"></span>
+<span class="source-line-no">2870</span><span id="line-2870">  @Override</span>
+<span class="source-line-no">2871</span><span id="line-2871">  public LeaseManager getLeaseManager() {</span>
+<span class="source-line-no">2872</span><span id="line-2872">    return leaseManager;</span>
+<span class="source-line-no">2873</span><span id="line-2873">  }</span>
+<span class="source-line-no">2874</span><span id="line-2874"></span>
+<span class="source-line-no">2875</span><span id="line-2875">  /** Returns {@code true} when the data file system is available, {@code false} otherwise. */</span>
+<span class="source-line-no">2876</span><span id="line-2876">  boolean isDataFileSystemOk() {</span>
+<span class="source-line-no">2877</span><span id="line-2877">    return this.dataFsOk;</span>
 <span class="source-line-no">2878</span><span id="line-2878">  }</span>
 <span class="source-line-no">2879</span><span id="line-2879"></span>
-<span class="source-line-no">2880</span><span id="line-2880">  @Override</span>
-<span class="source-line-no">2881</span><span id="line-2881">  public ConcurrentMap&lt;byte[], Boolean&gt; getRegionsInTransitionInRS() {</span>
-<span class="source-line-no">2882</span><span id="line-2882">    return this.regionsInTransitionInRS;</span>
-<span class="source-line-no">2883</span><span id="line-2883">  }</span>
-<span class="source-line-no">2884</span><span id="line-2884"></span>
-<span class="source-line-no">2885</span><span id="line-2885">  @Override</span>
-<span class="source-line-no">2886</span><span id="line-2886">  public RegionServerRpcQuotaManager getRegionServerRpcQuotaManager() {</span>
-<span class="source-line-no">2887</span><span id="line-2887">    return rsQuotaManager;</span>
-<span class="source-line-no">2888</span><span id="line-2888">  }</span>
-<span class="source-line-no">2889</span><span id="line-2889"></span>
-<span class="source-line-no">2890</span><span id="line-2890">  //</span>
-<span class="source-line-no">2891</span><span id="line-2891">  // Main program and support routines</span>
-<span class="source-line-no">2892</span><span id="line-2892">  //</span>
-<span class="source-line-no">2893</span><span id="line-2893">  /**</span>
-<span class="source-line-no">2894</span><span id="line-2894">   * Load the replication executorService objects, if any</span>
-<span class="source-line-no">2895</span><span id="line-2895">   */</span>
-<span class="source-line-no">2896</span><span id="line-2896">  private static void createNewReplicationInstance(Configuration conf, HRegionServer server,</span>
-<span class="source-line-no">2897</span><span id="line-2897">    FileSystem walFs, Path walDir, Path oldWALDir, WALFactory walFactory) throws IOException {</span>
-<span class="source-line-no">2898</span><span id="line-2898">    // read in the name of the source replication class from the config file.</span>
-<span class="source-line-no">2899</span><span id="line-2899">    String sourceClassname = conf.get(HConstants.REPLICATION_SOURCE_SERVICE_CLASSNAME,</span>
-<span class="source-line-no">2900</span><span id="line-2900">      HConstants.REPLICATION_SERVICE_CLASSNAME_DEFAULT);</span>
-<span class="source-line-no">2901</span><span id="line-2901"></span>
-<span class="source-line-no">2902</span><span id="line-2902">    // read in the name of the sink replication class from the config file.</span>
-<span class="source-line-no">2903</span><span id="line-2903">    String sinkClassname = conf.get(HConstants.REPLICATION_SINK_SERVICE_CLASSNAME,</span>
-<span class="source-line-no">2904</span><span id="line-2904">      HConstants.REPLICATION_SINK_SERVICE_CLASSNAME_DEFAULT);</span>
+<span class="source-line-no">2880</span><span id="line-2880">  public RegionServerCoprocessorHost getRegionServerCoprocessorHost() {</span>
+<span class="source-line-no">2881</span><span id="line-2881">    return this.rsHost;</span>
+<span class="source-line-no">2882</span><span id="line-2882">  }</span>
+<span class="source-line-no">2883</span><span id="line-2883"></span>
+<span class="source-line-no">2884</span><span id="line-2884">  @Override</span>
+<span class="source-line-no">2885</span><span id="line-2885">  public ConcurrentMap&lt;byte[], Boolean&gt; getRegionsInTransitionInRS() {</span>
+<span class="source-line-no">2886</span><span id="line-2886">    return this.regionsInTransitionInRS;</span>
+<span class="source-line-no">2887</span><span id="line-2887">  }</span>
+<span class="source-line-no">2888</span><span id="line-2888"></span>
+<span class="source-line-no">2889</span><span id="line-2889">  @Override</span>
+<span class="source-line-no">2890</span><span id="line-2890">  public RegionServerRpcQuotaManager getRegionServerRpcQuotaManager() {</span>
+<span class="source-line-no">2891</span><span id="line-2891">    return rsQuotaManager;</span>
+<span class="source-line-no">2892</span><span id="line-2892">  }</span>
+<span class="source-line-no">2893</span><span id="line-2893"></span>
+<span class="source-line-no">2894</span><span id="line-2894">  //</span>
+<span class="source-line-no">2895</span><span id="line-2895">  // Main program and support routines</span>
+<span class="source-line-no">2896</span><span id="line-2896">  //</span>
+<span class="source-line-no">2897</span><span id="line-2897">  /**</span>
+<span class="source-line-no">2898</span><span id="line-2898">   * Load the replication executorService objects, if any</span>
+<span class="source-line-no">2899</span><span id="line-2899">   */</span>
+<span class="source-line-no">2900</span><span id="line-2900">  private static void createNewReplicationInstance(Configuration conf, HRegionServer server,</span>
+<span class="source-line-no">2901</span><span id="line-2901">    FileSystem walFs, Path walDir, Path oldWALDir, WALFactory walFactory) throws IOException {</span>
+<span class="source-line-no">2902</span><span id="line-2902">    // read in the name of the source replication class from the config file.</span>
+<span class="source-line-no">2903</span><span id="line-2903">    String sourceClassname = conf.get(HConstants.REPLICATION_SOURCE_SERVICE_CLASSNAME,</span>
+<span class="source-line-no">2904</span><span id="line-2904">      HConstants.REPLICATION_SERVICE_CLASSNAME_DEFAULT);</span>
 <span class="source-line-no">2905</span><span id="line-2905"></span>
-<span class="source-line-no">2906</span><span id="line-2906">    // If both the sink and the source class names are the same, then instantiate</span>
-<span class="source-line-no">2907</span><span id="line-2907">    // only one object.</span>
-<span class="source-line-no">2908</span><span id="line-2908">    if (sourceClassname.equals(sinkClassname)) {</span>
-<span class="source-line-no">2909</span><span id="line-2909">      server.replicationSourceHandler = newReplicationInstance(sourceClassname,</span>
-<span class="source-line-no">2910</span><span id="line-2910">        ReplicationSourceService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
-<span class="source-line-no">2911</span><span id="line-2911">      server.replicationSinkHandler = (ReplicationSinkService) server.replicationSourceHandler;</span>
-<span class="source-line-no">2912</span><span id="line-2912">      server.sameReplicationSourceAndSink = true;</span>
-<span class="source-line-no">2913</span><span id="line-2913">    } else {</span>
-<span class="source-line-no">2914</span><span id="line-2914">      server.replicationSourceHandler = newReplicationInstance(sourceClassname,</span>
-<span class="source-line-no">2915</span><span id="line-2915">        ReplicationSourceService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
-<span class="source-line-no">2916</span><span id="line-2916">      server.replicationSinkHandler = newReplicationInstance(sinkClassname,</span>
-<span class="source-line-no">2917</span><span id="line-2917">        ReplicationSinkService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
-<span class="source-line-no">2918</span><span id="line-2918">      server.sameReplicationSourceAndSink = false;</span>
-<span class="source-line-no">2919</span><span id="line-2919">    }</span>
-<span class="source-line-no">2920</span><span id="line-2920">  }</span>
-<span class="source-line-no">2921</span><span id="line-2921"></span>
-<span class="source-line-no">2922</span><span id="line-2922">  private static &lt;T extends ReplicationService&gt; T newReplicationInstance(String classname,</span>
-<span class="source-line-no">2923</span><span id="line-2923">    Class&lt;T&gt; xface, Configuration conf, HRegionServer server, FileSystem walFs, Path logDir,</span>
-<span class="source-line-no">2924</span><span id="line-2924">    Path oldLogDir, WALFactory walFactory) throws IOException {</span>
-<span class="source-line-no">2925</span><span id="line-2925">    final Class&lt;? extends T&gt; clazz;</span>
-<span class="source-line-no">2926</span><span id="line-2926">    try {</span>
-<span class="source-line-no">2927</span><span id="line-2927">      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();</span>
-<span class="source-line-no">2928</span><span id="line-2928">      clazz = Class.forName(classname, true, classLoader).asSubclass(xface);</span>
-<span class="source-line-no">2929</span><span id="line-2929">    } catch (java.lang.ClassNotFoundException nfe) {</span>
-<span class="source-line-no">2930</span><span id="line-2930">      throw new IOException("Could not find class for " + classname);</span>
-<span class="source-line-no">2931</span><span id="line-2931">    }</span>
-<span class="source-line-no">2932</span><span id="line-2932">    T service = ReflectionUtils.newInstance(clazz, conf);</span>
-<span class="source-line-no">2933</span><span id="line-2933">    service.initialize(server, walFs, logDir, oldLogDir, walFactory);</span>
-<span class="source-line-no">2934</span><span id="line-2934">    return service;</span>
-<span class="source-line-no">2935</span><span id="line-2935">  }</span>
-<span class="source-line-no">2936</span><span id="line-2936"></span>
-<span class="source-line-no">2937</span><span id="line-2937">  public Map&lt;String, ReplicationStatus&gt; getWalGroupsReplicationStatus() {</span>
-<span class="source-line-no">2938</span><span id="line-2938">    Map&lt;String, ReplicationStatus&gt; walGroupsReplicationStatus = new TreeMap&lt;&gt;();</span>
-<span class="source-line-no">2939</span><span id="line-2939">    if (!this.isOnline()) {</span>
-<span class="source-line-no">2940</span><span id="line-2940">      return walGroupsReplicationStatus;</span>
-<span class="source-line-no">2941</span><span id="line-2941">    }</span>
-<span class="source-line-no">2942</span><span id="line-2942">    List&lt;ReplicationSourceInterface&gt; allSources = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">2943</span><span id="line-2943">    allSources.addAll(replicationSourceHandler.getReplicationManager().getSources());</span>
-<span class="source-line-no">2944</span><span id="line-2944">    allSources.addAll(replicationSourceHandler.getReplicationManager().getOldSources());</span>
-<span class="source-line-no">2945</span><span id="line-2945">    for (ReplicationSourceInterface source : allSources) {</span>
-<span class="source-line-no">2946</span><span id="line-2946">      walGroupsReplicationStatus.putAll(source.getWalGroupStatus());</span>
-<span class="source-line-no">2947</span><span id="line-2947">    }</span>
-<span class="source-line-no">2948</span><span id="line-2948">    return walGroupsReplicationStatus;</span>
-<span class="source-line-no">2949</span><span id="line-2949">  }</span>
-<span class="source-line-no">2950</span><span id="line-2950"></span>
-<span class="source-line-no">2951</span><span id="line-2951">  /**</span>
-<span class="source-line-no">2952</span><span id="line-2952">   * Utility for constructing an instance of the passed HRegionServer class.</span>
-<span class="source-line-no">2953</span><span id="line-2953">   */</span>
-<span class="source-line-no">2954</span><span id="line-2954">  static HRegionServer constructRegionServer(final Class&lt;? extends HRegionServer&gt; regionServerClass,</span>
-<span class="source-line-no">2955</span><span id="line-2955">    final Configuration conf) {</span>
-<span class="source-line-no">2956</span><span id="line-2956">    try {</span>
-<span class="source-line-no">2957</span><span id="line-2957">      Constructor&lt;? extends HRegionServer&gt; c =</span>
-<span class="source-line-no">2958</span><span id="line-2958">        regionServerClass.getConstructor(Configuration.class);</span>
-<span class="source-line-no">2959</span><span id="line-2959">      return c.newInstance(conf);</span>
-<span class="source-line-no">2960</span><span id="line-2960">    } catch (Exception e) {</span>
-<span class="source-line-no">2961</span><span id="line-2961">      throw new RuntimeException(</span>
-<span class="source-line-no">2962</span><span id="line-2962">        "Failed construction of " + "Regionserver: " + regionServerClass.toString(), e);</span>
-<span class="source-line-no">2963</span><span id="line-2963">    }</span>
-<span class="source-line-no">2964</span><span id="line-2964">  }</span>
-<span class="source-line-no">2965</span><span id="line-2965"></span>
-<span class="source-line-no">2966</span><span id="line-2966">  /**</span>
-<span class="source-line-no">2967</span><span id="line-2967">   * @see org.apache.hadoop.hbase.regionserver.HRegionServerCommandLine</span>
-<span class="source-line-no">2968</span><span id="line-2968">   */</span>
-<span class="source-line-no">2969</span><span id="line-2969">  public static void main(String[] args) {</span>
-<span class="source-line-no">2970</span><span id="line-2970">    LOG.info("STARTING executorService " + HRegionServer.class.getSimpleName());</span>
-<span class="source-line-no">2971</span><span id="line-2971">    VersionInfo.logVersion();</span>
-<span class="source-line-no">2972</span><span id="line-2972">    Configuration conf = HBaseConfiguration.create();</span>
-<span class="source-line-no">2973</span><span id="line-2973">    @SuppressWarnings("unchecked")</span>
-<span class="source-line-no">2974</span><span id="line-2974">    Class&lt;? extends HRegionServer&gt; regionServerClass = (Class&lt;? extends HRegionServer&gt;) conf</span>
-<span class="source-line-no">2975</span><span id="line-2975">      .getClass(HConstants.REGION_SERVER_IMPL, HRegionServer.class);</span>
-<span class="source-line-no">2976</span><span id="line-2976"></span>
-<span class="source-line-no">2977</span><span id="line-2977">    new HRegionServerCommandLine(regionServerClass).doMain(args);</span>
-<span class="source-line-no">2978</span><span id="line-2978">  }</span>
-<span class="source-line-no">2979</span><span id="line-2979"></span>
-<span class="source-line-no">2980</span><span id="line-2980">  /**</span>
-<span class="source-line-no">2981</span><span id="line-2981">   * Gets the online regions of the specified table. This method looks at the in-memory</span>
-<span class="source-line-no">2982</span><span id="line-2982">   * onlineRegions. It does not go to &lt;code&gt;hbase:meta&lt;/code&gt;. Only returns &lt;em&gt;online&lt;/em&gt; regions.</span>
-<span class="source-line-no">2983</span><span id="line-2983">   * If a region on this table has been closed during a disable, etc., it will not be included in</span>
-<span class="source-line-no">2984</span><span id="line-2984">   * the returned list. So, the returned list may not necessarily be ALL regions in this table, its</span>
-<span class="source-line-no">2985</span><span id="line-2985">   * all the ONLINE regions in the table.</span>
-<span class="source-line-no">2986</span><span id="line-2986">   * @param tableName table to limit the scope of the query</span>
-<span class="source-line-no">2987</span><span id="line-2987">   * @return Online regions from &lt;code&gt;tableName&lt;/code&gt;</span>
-<span class="source-line-no">2988</span><span id="line-2988">   */</span>
-<span class="source-line-no">2989</span><span id="line-2989">  @Override</span>
-<span class="source-line-no">2990</span><span id="line-2990">  public List&lt;HRegion&gt; getRegions(TableName tableName) {</span>
-<span class="source-line-no">2991</span><span id="line-2991">    List&lt;HRegion&gt; tableRegions = new ArrayList&lt;&gt;();</span>
-<span class="source-line-no">2992</span><span id="line-2992">    synchronized (this.onlineRegions) {</span>
-<span class="source-line-no">2993</span><span id="line-2993">      for (HRegion region : this.onlineRegions.values()) {</span>
-<span class="source-line-no">2994</span><span id="line-2994">        RegionInfo regionInfo = region.getRegionInfo();</span>
-<span class="source-line-no">2995</span><span id="line-2995">        if (regionInfo.getTable().equals(tableName)) {</span>
-<span class="source-line-no">2996</span><span id="line-2996">          tableRegions.add(region);</span>
-<span class="source-line-no">2997</span><span id="line-2997">        }</span>
-<span class="source-line-no">2998</span><span id="line-2998">      }</span>
-<span class="source-line-no">2999</span><span id="line-2999">    }</span>
-<span class="source-line-no">3000</span><span id="line-3000">    return tableRegions;</span>
-<span class="source-line-no">3001</span><span id="line-3001">  }</span>
-<span class="source-line-no">3002</span><span id="line-3002"></span>
-<span class="source-line-no">3003</span><span id="line-3003">  @Override</span>
-<span class="source-line-no">3004</span><span id="line-3004">  public List&lt;HRegion&gt; getRegions() {</span>
-<span class="source-line-no">3005</span><span id="line-3005">    List&lt;HRegion&gt; allRegions;</span>
-<span class="source-line-no">3006</span><span id="line-3006">    synchronized (this.onlineRegions) {</span>
-<span class="source-line-no">3007</span><span id="line-3007">      // Return a clone copy of the onlineRegions</span>
-<span class="source-line-no">3008</span><span id="line-3008">      allRegions = new ArrayList&lt;&gt;(onlineRegions.values());</span>
-<span class="source-line-no">3009</span><span id="line-3009">    }</span>
-<span class="source-line-no">3010</span><span id="line-3010">    return allRegions;</span>
-<span class="source-line-no">3011</span><span id="line-3011">  }</span>
-<span class="source-line-no">3012</span><span id="line-3012"></span>
-<span class="source-line-no">3013</span><span id="line-3013">  /**</span>
-<span class="source-line-no">3014</span><span id="line-3014">   * Gets the online tables in this RS. This method looks at the in-memory onlineRegions.</span>
-<span class="source-line-no">3015</span><span id="line-3015">   * @return all the online tables in this RS</span>
-<span class="source-line-no">3016</span><span id="line-3016">   */</span>
-<span class="source-line-no">3017</span><span id="line-3017">  public Set&lt;TableName&gt; getOnlineTables() {</span>
-<span class="source-line-no">3018</span><span id="line-3018">    Set&lt;TableName&gt; tables = new HashSet&lt;&gt;();</span>
-<span class="source-line-no">3019</span><span id="line-3019">    synchronized (this.onlineRegions) {</span>
-<span class="source-line-no">3020</span><span id="line-3020">      for (Region region : this.onlineRegions.values()) {</span>
-<span class="source-line-no">3021</span><span id="line-3021">        tables.add(region.getTableDescriptor().getTableName());</span>
-<span class="source-line-no">3022</span><span id="line-3022">      }</span>
-<span class="source-line-no">3023</span><span id="line-3023">    }</span>
-<span class="source-line-no">3024</span><span id="line-3024">    return tables;</span>
-<span class="source-line-no">3025</span><span id="line-3025">  }</span>
-<span class="source-line-no">3026</span><span id="line-3026"></span>
-<span class="source-line-no">3027</span><span id="line-3027">  public String[] getRegionServerCoprocessors() {</span>
-<span class="source-line-no">3028</span><span id="line-3028">    TreeSet&lt;String&gt; coprocessors = new TreeSet&lt;&gt;();</span>
-<span class="source-line-no">3029</span><span id="line-3029">    try {</span>
-<span class="source-line-no">3030</span><span id="line-3030">      coprocessors.addAll(getWAL(null).getCoprocessorHost().getCoprocessors());</span>
-<span class="source-line-no">3031</span><span id="line-3031">    } catch (IOException exception) {</span>
-<span class="source-line-no">3032</span><span id="line-3032">      LOG.warn("Exception attempting to fetch wal coprocessor information for the common wal; "</span>
-<span class="source-line-no">3033</span><span id="line-3033">        + "skipping.");</span>
-<span class="source-line-no">3034</span><span id="line-3034">      LOG.debug("Exception details for failure to fetch wal coprocessor information.", exception);</span>
-<span class="source-line-no">3035</span><span id="line-3035">    }</span>
-<span class="source-line-no">3036</span><span id="line-3036">    Collection&lt;HRegion&gt; regions = getOnlineRegionsLocalContext();</span>
-<span class="source-line-no">3037</span><span id="line-3037">    for (HRegion region : regions) {</span>
-<span class="source-line-no">3038</span><span id="line-3038">      coprocessors.addAll(region.getCoprocessorHost().getCoprocessors());</span>
-<span class="source-line-no">3039</span><span id="line-3039">      try {</span>
-<span class="source-line-no">3040</span><span id="line-3040">        coprocessors.addAll(getWAL(region.getRegionInfo()).getCoprocessorHost().getCoprocessors());</span>
-<span class="source-line-no">3041</span><span id="line-3041">      } catch (IOException exception) {</span>
-<span class="source-line-no">3042</span><span id="line-3042">        LOG.warn("Exception attempting to fetch wal coprocessor information for region " + region</span>
-<span class="source-line-no">3043</span><span id="line-3043">          + "; skipping.");</span>
-<span class="source-line-no">3044</span><span id="line-3044">        LOG.debug("Exception details for failure to fetch wal coprocessor information.", exception);</span>
-<span class="source-line-no">3045</span><span id="line-3045">      }</span>
-<span class="source-line-no">3046</span><span id="line-3046">    }</span>
-<span class="source-line-no">3047</span><span id="line-3047">    coprocessors.addAll(rsHost.getCoprocessors());</span>
-<span class="source-line-no">3048</span><span id="line-3048">    return coprocessors.toArray(new String[0]);</span>
-<span class="source-line-no">3049</span><span id="line-3049">  }</span>
-<span class="source-line-no">3050</span><span id="line-3050"></span>
-<span class="source-line-no">3051</span><span id="line-3051">  /**</span>
-<span class="source-line-no">3052</span><span id="line-3052">   * Try to close the region, logs a warning on failure but continues.</span>
-<span class="source-line-no">3053</span><span id="line-3053">   * @param region Region to close</span>
-<span class="source-line-no">3054</span><span id="line-3054">   */</span>
-<span class="source-line-no">3055</span><span id="line-3055">  private void closeRegionIgnoreErrors(RegionInfo region, final boolean abort) {</span>
-<span class="source-line-no">3056</span><span id="line-3056">    try {</span>
-<span class="source-line-no">3057</span><span id="line-3057">      if (!closeRegion(region.getEncodedName(), abort, null)) {</span>
-<span class="source-line-no">3058</span><span id="line-3058">        LOG</span>
-<span class="source-line-no">3059</span><span id="line-3059">          .warn("Failed to close " + region.getRegionNameAsString() + " - ignoring and continuing");</span>
-<span class="source-line-no">3060</span><span id="line-3060">      }</span>
-<span class="source-line-no">3061</span><span id="line-3061">    } catch (IOException e) {</span>
-<span class="source-line-no">3062</span><span id="line-3062">      LOG.warn("Failed to close " + region.getRegionNameAsString() + " - ignoring and continuing",</span>
-<span class="source-line-no">3063</span><span id="line-3063">        e);</span>
-<span class="source-line-no">3064</span><span id="line-3064">    }</span>
-<span class="source-line-no">3065</span><span id="line-3065">  }</span>
-<span class="source-line-no">3066</span><span id="line-3066"></span>
-<span class="source-line-no">3067</span><span id="line-3067">  /**</span>
-<span class="source-line-no">3068</span><span id="line-3068">   * Close asynchronously a region, can be called from the master or internally by the regionserver</span>
-<span class="source-line-no">3069</span><span id="line-3069">   * when stopping. If called from the master, the region will update the status.</span>
-<span class="source-line-no">3070</span><span id="line-3070">   * &lt;p&gt;</span>
-<span class="source-line-no">3071</span><span id="line-3071">   * If an opening was in progress, this method will cancel it, but will not start a new close. The</span>
-<span class="source-line-no">3072</span><span id="line-3072">   * coprocessors are not called in this case. A NotServingRegionException exception is thrown.</span>
-<span class="source-line-no">3073</span><span id="line-3073">   * &lt;/p&gt;</span>
+<span class="source-line-no">2906</span><span id="line-2906">    // read in the name of the sink replication class from the config file.</span>
+<span class="source-line-no">2907</span><span id="line-2907">    String sinkClassname = conf.get(HConstants.REPLICATION_SINK_SERVICE_CLASSNAME,</span>
+<span class="source-line-no">2908</span><span id="line-2908">      HConstants.REPLICATION_SINK_SERVICE_CLASSNAME_DEFAULT);</span>
+<span class="source-line-no">2909</span><span id="line-2909"></span>
+<span class="source-line-no">2910</span><span id="line-2910">    // If both the sink and the source class names are the same, then instantiate</span>
+<span class="source-line-no">2911</span><span id="line-2911">    // only one object.</span>
+<span class="source-line-no">2912</span><span id="line-2912">    if (sourceClassname.equals(sinkClassname)) {</span>
+<span class="source-line-no">2913</span><span id="line-2913">      server.replicationSourceHandler = newReplicationInstance(sourceClassname,</span>
+<span class="source-line-no">2914</span><span id="line-2914">        ReplicationSourceService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
+<span class="source-line-no">2915</span><span id="line-2915">      server.replicationSinkHandler = (ReplicationSinkService) server.replicationSourceHandler;</span>
+<span class="source-line-no">2916</span><span id="line-2916">      server.sameReplicationSourceAndSink = true;</span>
+<span class="source-line-no">2917</span><span id="line-2917">    } else {</span>
+<span class="source-line-no">2918</span><span id="line-2918">      server.replicationSourceHandler = newReplicationInstance(sourceClassname,</span>
+<span class="source-line-no">2919</span><span id="line-2919">        ReplicationSourceService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
+<span class="source-line-no">2920</span><span id="line-2920">      server.replicationSinkHandler = newReplicationInstance(sinkClassname,</span>
+<span class="source-line-no">2921</span><span id="line-2921">        ReplicationSinkService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
+<span class="source-line-no">2922</span><span id="line-2922">      server.sameReplicationSourceAndSink = false;</span>
+<span class="source-line-no">2923</span><span id="line-2923">    }</span>
+<span class="source-line-no">2924</span><span id="line-2924">  }</span>
+<span class="source-line-no">2925</span><span id="line-2925"></span>
+<span class="source-line-no">2926</span><span id="line-2926">  private static &lt;T extends ReplicationService&gt; T newReplicationInstance(String classname,</span>
+<span class="source-line-no">2927</span><span id="line-2927">    Class&lt;T&gt; xface, Configuration conf, HRegionServer server, FileSystem walFs, Path logDir,</span>
+<span class="source-line-no">2928</span><span id="line-2928">    Path oldLogDir, WALFactory walFactory) throws IOException {</span>
+<span class="source-line-no">2929</span><span id="line-2929">    final Class&lt;? extends T&gt; clazz;</span>
+<span class="source-line-no">2930</span><span id="line-2930">    try {</span>
+<span class="source-line-no">2931</span><span id="line-2931">      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();</span>
+<span class="source-line-no">2932</span><span id="line-2932">      clazz = Class.forName(classname, true, classLoader).asSubclass(xface);</span>
+<span class="source-line-no">2933</span><span id="line-2933">    } catch (java.lang.ClassNotFoundException nfe) {</span>
+<span class="source-line-no">2934</span><span id="line-2934">      throw new IOException("Could not find class for " + classname);</span>
+<span class="source-line-no">2935</span><span id="line-2935">    }</span>
+<span class="source-line-no">2936</span><span id="line-2936">    T service = ReflectionUtils.newInstance(clazz, conf);</span>
+<span class="source-line-no">2937</span><span id="line-2937">    service.initialize(server, walFs, logDir, oldLogDir, walFactory);</span>
+<span class="source-line-no">2938</span><span id="line-2938">    return service;</span>
+<span class="source-line-no">2939</span><span id="line-2939">  }</span>
+<span class="source-line-no">2940</span><span id="line-2940"></span>
+<span class="source-line-no">2941</span><span id="line-2941">  public Map&lt;String, ReplicationStatus&gt; getWalGroupsReplicationStatus() {</span>
+<span class="source-line-no">2942</span><span id="line-2942">    Map&lt;String, ReplicationStatus&gt; walGroupsReplicationStatus = new TreeMap&lt;&gt;();</span>
+<span class="source-line-no">2943</span><span id="line-2943">    if (!this.isOnline()) {</span>
+<span class="source-line-no">2944</span><span id="line-2944">      return walGroupsReplicationStatus;</span>
+<span class="source-line-no">2945</span><span id="line-2945">    }</span>
+<span class="source-line-no">2946</span><span id="line-2946">    List&lt;ReplicationSourceInterface&gt; allSources = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">2947</span><span id="line-2947">    allSources.addAll(replicationSourceHandler.getReplicationManager().getSources());</span>
+<span class="source-line-no">2948</span><span id="line-2948">    allSources.addAll(replicationSourceHandler.getReplicationManager().getOldSources());</span>
+<span class="source-line-no">2949</span><span id="line-2949">    for (ReplicationSourceInterface source : allSources) {</span>
+<span class="source-line-no">2950</span><span id="line-2950">      walGroupsReplicationStatus.putAll(source.getWalGroupStatus());</span>
+<span class="source-line-no">2951</span><span id="line-2951">    }</span>
+<span class="source-line-no">2952</span><span id="line-2952">    return walGroupsReplicationStatus;</span>
+<span class="source-line-no">2953</span><span id="line-2953">  }</span>
+<span class="source-line-no">2954</span><span id="line-2954"></span>
+<span class="source-line-no">2955</span><span id="line-2955">  /**</span>
+<span class="source-line-no">2956</span><span id="line-2956">   * Utility for constructing an instance of the passed HRegionServer class.</span>
+<span class="source-line-no">2957</span><span id="line-2957">   */</span>
+<span class="source-line-no">2958</span><span id="line-2958">  static HRegionServer constructRegionServer(final Class&lt;? extends HRegionServer&gt; regionServerClass,</span>
+<span class="source-line-no">2959</span><span id="line-2959">    final Configuration conf) {</span>
+<span class="source-line-no">2960</span><span id="line-2960">    try {</span>
+<span class="source-line-no">2961</span><span id="line-2961">      Constructor&lt;? extends HRegionServer&gt; c =</span>
+<span class="source-line-no">2962</span><span id="line-2962">        regionServerClass.getConstructor(Configuration.class);</span>
+<span class="source-line-no">2963</span><span id="line-2963">      return c.newInstance(conf);</span>
+<span class="source-line-no">2964</span><span id="line-2964">    } catch (Exception e) {</span>
+<span class="source-line-no">2965</span><span id="line-2965">      throw new RuntimeException(</span>
+<span class="source-line-no">2966</span><span id="line-2966">        "Failed construction of " + "Regionserver: " + regionServerClass.toString(), e);</span>
+<span class="source-line-no">2967</span><span id="line-2967">    }</span>
+<span class="source-line-no">2968</span><span id="line-2968">  }</span>
+<span class="source-line-no">2969</span><span id="line-2969"></span>
+<span class="source-line-no">2970</span><span id="line-2970">  /**</span>
+<span class="source-line-no">2971</span><span id="line-2971">   * @see org.apache.hadoop.hbase.regionserver.HRegionServerCommandLine</span>
+<span class="source-line-no">2972</span><span id="line-2972">   */</span>
+<span class="source-line-no">2973</span><span id="line-2973">  public static void main(String[] args) {</span>
+<span class="source-line-no">2974</span><span id="line-2974">    LOG.info("STARTING executorService " + HRegionServer.class.getSimpleName());</span>
+<span class="source-line-no">2975</span><span id="line-2975">    VersionInfo.logVersion();</span>
+<span class="source-line-no">2976</span><span id="line-2976">    Configuration conf = HBaseConfiguration.create();</span>
+<span class="source-line-no">2977</span><span id="line-2977">    @SuppressWarnings("unchecked")</span>
+<span class="source-line-no">2978</span><span id="line-2978">    Class&lt;? extends HRegionServer&gt; regionServerClass = (Class&lt;? extends HRegionServer&gt;) conf</span>
+<span class="source-line-no">2979</span><span id="line-2979">      .getClass(HConstants.REGION_SERVER_IMPL, HRegionServer.class);</span>
+<span class="source-line-no">2980</span><span id="line-2980"></span>
+<span class="source-line-no">2981</span><span id="line-2981">    new HRegionServerCommandLine(regionServerClass).doMain(args);</span>
+<span class="source-line-no">2982</span><span id="line-2982">  }</span>
+<span class="source-line-no">2983</span><span id="line-2983"></span>
+<span class="source-line-no">2984</span><span id="line-2984">  /**</span>
+<span class="source-line-no">2985</span><span id="line-2985">   * Gets the online regions of the specified table. This method looks at the in-memory</span>
+<span class="source-line-no">2986</span><span id="line-2986">   * onlineRegions. It does not go to &lt;code&gt;hbase:meta&lt;/code&gt;. Only returns &lt;em&gt;online&lt;/em&gt; regions.</span>
+<span class="source-line-no">2987</span><span id="line-2987">   * If a region on this table has been closed during a disable, etc., it will not be included in</span>
+<span class="source-line-no">2988</span><span id="line-2988">   * the returned list. So, the returned list may not necessarily be ALL regions in this table, its</span>
+<span class="source-line-no">2989</span><span id="line-2989">   * all the ONLINE regions in the table.</span>
+<span class="source-line-no">2990</span><span id="line-2990">   * @param tableName table to limit the scope of the query</span>
+<span class="source-line-no">2991</span><span id="line-2991">   * @return Online regions from &lt;code&gt;tableName&lt;/code&gt;</span>
+<span class="source-line-no">2992</span><span id="line-2992">   */</span>
+<span class="source-line-no">2993</span><span id="line-2993">  @Override</span>
+<span class="source-line-no">2994</span><span id="line-2994">  public List&lt;HRegion&gt; getRegions(TableName tableName) {</span>
+<span class="source-line-no">2995</span><span id="line-2995">    List&lt;HRegion&gt; tableRegions = new ArrayList&lt;&gt;();</span>
+<span class="source-line-no">2996</span><span id="line-2996">    synchronized (this.onlineRegions) {</span>
+<span class="source-line-no">2997</span><span id="line-2997">      for (HRegion region : this.onlineRegions.values()) {</span>
+<span class="source-line-no">2998</span><span id="line-2998">        RegionInfo regionInfo = region.getRegionInfo();</span>
+<span class="source-line-no">2999</span><span id="line-2999">        if (regionInfo.getTable().equals(tableName)) {</span>
+<span class="source-line-no">3000</span><span id="line-3000">          tableRegions.add(region);</span>
+<span class="source-line-no">3001</span><span id="line-3001">        }</span>
+<span class="source-line-no">3002</span><span id="line-3002">      }</span>
+<span class="source-line-no">3003</span><span id="line-3003">    }</span>
+<span class="source-line-no">3004</span><span id="line-3004">    return tableRegions;</span>
+<span class="source-line-no">3005</span><span id="line-3005">  }</span>
+<span class="source-line-no">3006</span><span id="line-3006"></span>
+<span class="source-line-no">3007</span><span id="line-3007">  @Override</span>
+<span class="source-line-no">3008</span><span id="line-3008">  public List&lt;HRegion&gt; getRegions() {</span>
+<span class="source-line-no">3009</span><span id="line-3009">    List&lt;HRegion&gt; allRegions;</span>
+<span class="source-line-no">3010</span><span id="line-3010">    synchronized (this.onlineRegions) {</span>
+<span class="source-line-no">3011</span><span id="line-3011">      // Return a clone copy of the onlineRegions</span>
+<span class="source-line-no">3012</span><span id="line-3012">      allRegions = new ArrayList&lt;&gt;(onlineRegions.values());</span>
+<span class="source-line-no">3013</span><span id="line-3013">    }</span>
+<span class="source-line-no">3014</span><span id="line-3014">    return allRegions;</span>
+<span class="source-line-no">3015</span><span id="line-3015">  }</span>
+<span class="source-line-no">3016</span><span id="line-3016"></span>
+<span class="source-line-no">3017</span><span id="line-3017">  /**</span>
+<span class="source-line-no">3018</span><span id="line-3018">   * Gets the online tables in this RS. This method looks at the in-memory onlineRegions.</span>
+<span class="source-line-no">3019</span><span id="line-3019">   * @return all the online tables in this RS</span>
+<span class="source-line-no">3020</span><span id="line-3020">   */</span>
+<span class="source-line-no">3021</span><span id="line-3021">  public Set&lt;TableName&gt; getOnlineTables() {</span>
+<span class="source-line-no">3022</span><span id="line-3022">    Set&lt;TableName&gt; tables = new HashSet&lt;&gt;();</span>
+<span class="source-line-no">3023</span><span id="line-3023">    synchronized (this.onlineRegions) {</span>
+<span class="source-line-no">3024</span><span id="line-3024">      for (Region region : this.onlineRegions.values()) {</span>
+<span class="source-line-no">3025</span><span id="line-3025">        tables.add(region.getTableDescriptor().getTableName());</span>
+<span class="source-line-no">3026</span><span id="line-3026">      }</span>
+<span class="source-line-no">3027</span><span id="line-3027">    }</span>
+<span class="source-line-no">3028</span><span id="line-3028">    return tables;</span>
+<span class="source-line-no">3029</span><span id="line-3029">  }</span>
+<span class="source-line-no">3030</span><span id="line-3030"></span>
+<span class="source-line-no">3031</span><span id="line-3031">  public String[] getRegionServerCoprocessors() {</span>
+<span class="source-line-no">3032</span><span id="line-3032">    TreeSet&lt;String&gt; coprocessors = new TreeSet&lt;&gt;();</span>
+<span class="source-line-no">3033</span><span id="line-3033">    try {</span>
+<span class="source-line-no">3034</span><span id="line-3034">      coprocessors.addAll(getWAL(null).getCoprocessorHost().getCoprocessors());</span>
+<span class="source-line-no">3035</span><span id="line-3035">    } catch (IOException exception) {</span>
+<span class="source-line-no">3036</span><span id="line-3036">      LOG.warn("Exception attempting to fetch wal coprocessor information for the common wal; "</span>
+<span class="source-line-no">3037</span><span id="line-3037">        + "skipping.");</span>
+<span class="source-line-no">3038</span><span id="line-3038">      LOG.debug("Exception details for failure to fetch wal coprocessor information.", exception);</span>
+<span class="source-line-no">3039</span><span id="line-3039">    }</span>
+<span class="source-line-no">3040</span><span id="line-3040">    Collection&lt;HRegion&gt; regions = getOnlineRegionsLocalContext();</span>
+<span class="source-line-no">3041</span><span id="line-3041">    for (HRegion region : regions) {</span>
+<span class="source-line-no">3042</span><span id="line-3042">      coprocessors.addAll(region.getCoprocessorHost().getCoprocessors());</span>
+<span class="source-line-no">3043</span><span id="line-3043">      try {</span>
+<span class="source-line-no">3044</span><span id="line-3044">        coprocessors.addAll(getWAL(region.getRegionInfo()).getCoprocessorHost().getCoprocessors());</span>
+<span class="source-line-no">3045</span><span id="line-3045">      } catch (IOException exception) {</span>
+<span class="source-line-no">3046</span><span id="line-3046">        LOG.warn("Exception attempting to fetch wal coprocessor information for region " + region</span>
+<span class="source-line-no">3047</span><span id="line-3047">          + "; skipping.");</span>
+<span class="source-line-no">3048</span><span id="line-3048">        LOG.debug("Exception details for failure to fetch wal coprocessor information.", exception);</span>
+<span class="source-line-no">3049</span><span id="line-3049">      }</span>
+<span class="source-line-no">3050</span><span id="line-3050">    }</span>
+<span class="source-line-no">3051</span><span id="line-3051">    coprocessors.addAll(rsHost.getCoprocessors());</span>
+<span class="source-line-no">3052</span><span id="line-3052">    return coprocessors.toArray(new String[0]);</span>
+<span class="source-line-no">3053</span><span id="line-3053">  }</span>
+<span class="source-line-no">3054</span><span id="line-3054"></span>
+<span class="source-line-no">3055</span><span id="line-3055">  /**</span>
+<span class="source-line-no">3056</span><span id="line-3056">   * Try to close the region, logs a warning on failure but continues.</span>
+<span class="source-line-no">3057</span><span id="line-3057">   * @param region Region to close</span>
+<span class="source-line-no">3058</span><span id="line-3058">   */</span>
+<span class="source-line-no">3059</span><span id="line-3059">  private void closeRegionIgnoreErrors(RegionInfo region, final boolean abort) {</span>
+<span class="source-line-no">3060</span><span id="line-3060">    try {</span>
+<span class="source-line-no">3061</span><span id="line-3061">      if (!closeRegion(region.getEncodedName(), abort, null)) {</span>
+<span class="source-line-no">3062</span><span id="line-3062">        LOG</span>
+<span class="source-line-no">3063</span><span id="line-3063">          .warn("Failed to close " + region.getRegionNameAsString() + " - ignoring and continuing");</span>
+<span class="source-line-no">3064</span><span id="line-3064">      }</span>
+<span class="source-line-no">3065</span><span id="line-3065">    } catch (IOException e) {</span>
+<span class="source-line-no">3066</span><span id="line-3066">      LOG.warn("Failed to close " + region.getRegionNameAsString() + " - ignoring and continuing",</span>
+<span class="source-line-no">3067</span><span id="line-3067">        e);</span>
+<span class="source-line-no">3068</span><span id="line-3068">    }</span>
+<span class="source-line-no">3069</span><span id="line-3069">  }</span>
+<span class="source-line-no">3070</span><span id="line-3070"></span>
+<span class="source-line-no">3071</span><span id="line-3071">  /**</span>
+<span class="source-line-no">3072</span><span id="line-3072">   * Close asynchronously a region, can be called from the master or internally by the regionserver</span>
+<span class="source-line-no">3073</span><span id="line-3073">   * when stopping. If called from the master, the region will update the status.</span>
 <span class="source-line-no">3074</span><span id="line-3074">   * &lt;p&gt;</span>
-<span class="source-line-no">3075</span><span id="line-3075">   * If a close was in progress, this new request will be ignored, and an exception thrown.</span>
-<span class="source-line-no">3076</span><span id="line-3076">   * &lt;/p&gt;</span>
-<span class="source-line-no">3077</span><span id="line-3077">   * &lt;p&gt;</span>
-<span class="source-line-no">3078</span><span id="line-3078">   * Provides additional flag to indicate if this region blocks should be evicted from the cache.</span>
-<span class="source-line-no">3079</span><span id="line-3079">   * &lt;/p&gt;</span>
-<span class="source-line-no">3080</span><span id="line-3080">   * @param encodedName Region to close</span>
-<span class="source-line-no">3081</span><span id="line-3081">   * @param abort       True if we are aborting</span>
-<span class="source-line-no">3082</span><span id="line-3082">   * @param destination Where the Region is being moved too... maybe null if unknown.</span>
-<span class="source-line-no">3083</span><span id="line-3083">   * @return True if closed a region.</span>
-<span class="source-line-no">3084</span><span id="line-3084">   * @throws NotServingRegionException if the region is not online</span>
-<span class="source-line-no">3085</span><span id="line-3085">   */</span>
-<span class="source-line-no">3086</span><span id="line-3086">  protected boolean closeRegion(String encodedName, final boolean abort,</span>
-<span class="source-line-no">3087</span><span id="line-3087">    final ServerName destination) throws NotServingRegionException {</span>
-<span class="source-line-no">3088</span><span id="line-3088">    // Check for permissions to close.</span>
-<span class="source-line-no">3089</span><span id="line-3089">    HRegion actualRegion = this.getRegion(encodedName);</span>
-<span class="source-line-no">3090</span><span id="line-3090">    // Can be null if we're calling close on a region that's not online</span>
-<span class="source-line-no">3091</span><span id="line-3091">    if ((actualRegion != null) &amp;&amp; (actualRegion.getCoprocessorHost() != null)) {</span>
-<span class="source-line-no">3092</span><span id="line-3092">      try {</span>
-<span class="source-line-no">3093</span><span id="line-3093">        actualRegion.getCoprocessorHost().preClose(false);</span>
-<span class="source-line-no">3094</span><span id="line-3094">      } catch (IOException exp) {</span>
-<span class="source-line-no">3095</span><span id="line-3095">        LOG.warn("Unable to close region: the coprocessor launched an error ", exp);</span>
-<span class="source-line-no">3096</span><span id="line-3096">        return false;</span>
-<span class="source-line-no">3097</span><span id="line-3097">      }</span>
-<span class="source-line-no">3098</span><span id="line-3098">    }</span>
-<span class="source-line-no">3099</span><span id="line-3099"></span>
-<span class="source-line-no">3100</span><span id="line-3100">    // previous can come back 'null' if not in map.</span>
-<span class="source-line-no">3101</span><span id="line-3101">    final Boolean previous =</span>
-<span class="source-line-no">3102</span><span id="line-3102">      this.regionsInTransitionInRS.putIfAbsent(Bytes.toBytes(encodedName), Boolean.FALSE);</span>
+<span class="source-line-no">3075</span><span id="line-3075">   * If an opening was in progress, this method will cancel it, but will not start a new close. The</span>
+<span class="source-line-no">3076</span><span id="line-3076">   * coprocessors are not called in this case. A NotServingRegionException exception is thrown.</span>
+<span class="source-line-no">3077</span><span id="line-3077">   * &lt;/p&gt;</span>
+<span class="source-line-no">3078</span><span id="line-3078">   * &lt;p&gt;</span>
+<span class="source-line-no">3079</span><span id="line-3079">   * If a close was in progress, this new request will be ignored, and an exception thrown.</span>
+<span class="source-line-no">3080</span><span id="line-3080">   * &lt;/p&gt;</span>
+<span class="source-line-no">3081</span><span id="line-3081">   * &lt;p&gt;</span>
+<span class="source-line-no">3082</span><span id="line-3082">   * Provides additional flag to indicate if this region blocks should be evicted from the cache.</span>
+<span class="source-line-no">3083</span><span id="line-3083">   * &lt;/p&gt;</span>
+<span class="source-line-no">3084</span><span id="line-3084">   * @param encodedName Region to close</span>
+<span class="source-line-no">3085</span><span id="line-3085">   * @param abort       True if we are aborting</span>
+<span class="source-line-no">3086</span><span id="line-3086">   * @param destination Where the Region is being moved too... maybe null if unknown.</span>
+<span class="source-line-no">3087</span><span id="line-3087">   * @return True if closed a region.</span>
+<span class="source-line-no">3088</span><span id="line-3088">   * @throws NotServingRegionException if the region is not online</span>
+<span class="source-line-no">3089</span><span id="line-3089">   */</span>
+<span class="source-line-no">3090</span><span id="line-3090">  protected boolean closeRegion(String encodedName, final boolean abort,</span>
+<span class="source-line-no">3091</span><span id="line-3091">    final ServerName destination) throws NotServingRegionException {</span>
+<span class="source-line-no">3092</span><span id="line-3092">    // Check for permissions to close.</span>
+<span class="source-line-no">3093</span><span id="line-3093">    HRegion actualRegion = this.getRegion(encodedName);</span>
+<span class="source-line-no">3094</span><span id="line-3094">    // Can be null if we're calling close on a region that's not online</span>
+<span class="source-line-no">3095</span><span id="line-3095">    if ((actualRegion != null) &amp;&amp; (actualRegion.getCoprocessorHost() != null)) {</span>
+<span class="source-line-no">3096</span><span id="line-3096">      try {</span>
+<span class="source-line-no">3097</span><span id="line-3097">        actualRegion.getCoprocessorHost().preClose(false);</span>
+<span class="source-line-no">3098</span><span id="line-3098">      } catch (IOException exp) {</span>
+<span class="source-line-no">3099</span><span id="line-3099">        LOG.warn("Unable to close region: the coprocessor launched an error ", exp);</span>
+<span class="source-line-no">3100</span><span id="line-3100">        return false;</span>
+<span class="source-line-no">3101</span><span id="line-3101">      }</span>
+<span class="source-line-no">3102</span><span id="line-3102">    }</span>
 <span class="source-line-no">3103</span><span id="line-3103"></span>
-<span class="source-line-no">3104</span><span id="line-3104">    if (Boolean.TRUE.equals(previous)) {</span>
-<span class="source-line-no">3105</span><span id="line-3105">      LOG.info("Received CLOSE for the region:" + encodedName + " , which we are already "</span>
-<span class="source-line-no">3106</span><span id="line-3106">        + "trying to OPEN. Cancelling OPENING.");</span>
-<span class="source-line-no">3107</span><span id="line-3107">      if (!regionsInTransitionInRS.replace(Bytes.toBytes(encodedName), previous, Boolean.FALSE)) {</span>
-<span class="source-line-no">3108</span><span id="line-3108">        // The replace failed. That should be an exceptional case, but theoretically it can happen.</span>
-<span class="source-line-no">3109</span><span id="line-3109">        // We're going to try to do a standard close then.</span>
-<span class="source-line-no">3110</span><span id="line-3110">        LOG.warn("The opening for region " + encodedName + " was done before we could cancel it."</span>
-<span class="source-line-no">3111</span><span id="line-3111">          + " Doing a standard close now");</span>
-<span class="source-line-no">3112</span><span id="line-3112">        return closeRegion(encodedName, abort, destination);</span>
-<span class="source-line-no">3113</span><span id="line-3113">      }</span>
-<span class="source-line-no">3114</span><span id="line-3114">      // Let's get the region from the online region list again</span>
-<span class="source-line-no">3115</span><span id="line-3115">      actualRegion = this.getRegion(encodedName);</span>
-<span class="source-line-no">3116</span><span id="line-3116">      if (actualRegion == null) { // If already online, we still need to close it.</span>
-<span class="source-line-no">3117</span><span id="line-3117">        LOG.info("The opening previously in progress has been cancelled by a CLOSE request.");</span>
-<span class="source-line-no">3118</span><span id="line-3118">        // The master deletes the znode when it receives this exception.</span>
-<span class="source-line-no">3119</span><span id="line-3119">        throw new NotServingRegionException(</span>
-<span class="source-line-no">3120</span><span id="line-3120">          "The region " + encodedName + " was opening but not yet served. Opening is cancelled.");</span>
-<span class="source-line-no">3121</span><span id="line-3121">      }</span>
-<span class="source-line-no">3122</span><span id="line-3122">    } else if (previous == null) {</span>
-<span class="source-line-no">3123</span><span id="line-3123">      LOG.info("Received CLOSE for {}", encodedName);</span>
-<span class="source-line-no">3124</span><span id="line-3124">    } else if (Boolean.FALSE.equals(previous)) {</span>
-<span class="source-line-no">3125</span><span id="line-3125">      LOG.info("Received CLOSE for the region: " + encodedName</span>
-<span class="source-line-no">3126</span><span id="line-3126">        + ", which we are already trying to CLOSE, but not completed yet");</span>
-<span class="source-line-no">3127</span><span id="line-3127">      return true;</span>
-<span class="source-line-no">3128</span><span id="line-3128">    }</span>
-<span class="source-line-no">3129</span><span id="line-3129"></span>
-<span class="source-line-no">3130</span><span id="line-3130">    if (actualRegion == null) {</span>
-<span class="source-line-no">3131</span><span id="line-3131">      LOG.debug("Received CLOSE for a region which is not online, and we're not opening.");</span>
-<span class="source-line-no">3132</span><span id="line-3132">      this.regionsInTransitionInRS.remove(Bytes.toBytes(encodedName));</span>
-<span class="source-line-no">3133</span><span id="line-3133">      // The master deletes the znode when it receives this exception.</span>
-<span class="source-line-no">3134</span><span id="line-3134">      throw new NotServingRegionException(</span>
-<span class="source-line-no">3135</span><span id="line-3135">        "The region " + encodedName + " is not online, and is not opening.");</span>
-<span class="source-line-no">3136</span><span id="line-3136">    }</span>
-<span class="source-line-no">3137</span><span id="line-3137"></span>
-<span class="source-line-no">3138</span><span id="line-3138">    CloseRegionHandler crh;</span>
-<span class="source-line-no">3139</span><span id="line-3139">    final RegionInfo hri = actualRegion.getRegionInfo();</span>
-<span class="source-line-no">3140</span><span id="line-3140">    if (hri.isMetaRegion()) {</span>
-<span class="source-line-no">3141</span><span id="line-3141">      crh = new CloseMetaHandler(this, this, hri, abort);</span>
-<span class="source-line-no">3142</span><span id="line-3142">    } else {</span>
-<span class="source-line-no">3143</span><span id="line-3143">      crh = new CloseRegionHandler(this, this, hri, abort, destination);</span>
-<span class="source-line-no">3144</span><span id="line-3144">    }</span>
-<span class="source-line-no">3145</span><span id="line-3145">    this.executorService.submit(crh);</span>
-<span class="source-line-no">3146</span><span id="line-3146">    return true;</span>
-<span class="source-line-no">3147</span><span id="line-3147">  }</span>
-<span class="source-line-no">3148</span><span id="line-3148"></span>
-<span class="source-line-no">3149</span><span id="line-3149">  /**</span>
-<span class="source-line-no">3150</span><span id="line-3150">   * @return HRegion for the passed binary &lt;code&gt;regionName&lt;/code&gt; or null if named region is not</span>
-<span class="source-line-no">3151</span><span id="line-3151">   *         member of the online regions.</span>
-<span class="source-line-no">3152</span><span id="line-3152">   */</span>
-<span class="source-line-no">3153</span><span id="line-3153">  public HRegion getOnlineRegion(final byte[] regionName) {</span>
-<span class="source-line-no">3154</span><span id="line-3154">    String encodedRegionName = RegionInfo.encodeRegionName(regionName);</span>
-<span class="source-line-no">3155</span><span id="line-3155">    return this.onlineRegions.get(encodedRegionName);</span>
-<span class="source-line-no">3156</span><span id="line-3156">  }</span>
-<span class="source-line-no">3157</span><span id="line-3157"></span>
-<span class="source-line-no">3158</span><span id="line-3158">  @Override</span>
-<span class="source-line-no">3159</span><span id="line-3159">  public HRegion getRegion(final String encodedRegionName) {</span>
-<span class="source-line-no">3160</span><span id="line-3160">    return this.onlineRegions.get(encodedRegionName);</span>
-<span class="source-line-no">3161</span><span id="line-3161">  }</span>
-<span class="source-line-no">3162</span><span id="line-3162"></span>
-<span class="source-line-no">3163</span><span id="line-3163">  @Override</span>
-<span class="source-line-no">3164</span><span id="line-3164">  public boolean removeRegion(final HRegion r, ServerName destination) {</span>
-<span class="source-line-no">3165</span><span id="line-3165">    HRegion toReturn = this.onlineRegions.remove(r.getRegionInfo().getEncodedName());</span>
-<span class="source-line-no">3166</span><span id="line-3166">    if (DataTieringManager.getInstance() != null) {</span>
-<span class="source-line-no">3167</span><span id="line-3167">      DataTieringManager.getInstance().getRegionColdDataSize()</span>
-<span class="source-line-no">3168</span><span id="line-3168">        .remove(r.getRegionInfo().getEncodedName());</span>
-<span class="source-line-no">3169</span><span id="line-3169">    }</span>
-<span class="source-line-no">3170</span><span id="line-3170">    metricsRegionServerImpl.requestsCountCache.remove(r.getRegionInfo().getEncodedName());</span>
-<span class="source-line-no">3171</span><span id="line-3171">    if (destination != null) {</span>
-<span class="source-line-no">3172</span><span id="line-3172">      long closeSeqNum = r.getMaxFlushedSeqId();</span>
-<span class="source-line-no">3173</span><span id="line-3173">      if (closeSeqNum == HConstants.NO_SEQNUM) {</span>
-<span class="source-line-no">3174</span><span id="line-3174">        // No edits in WAL for this region; get the sequence number when the region was opened.</span>
-<span class="source-line-no">3175</span><span id="line-3175">        closeSeqNum = r.getOpenSeqNum();</span>
-<span class="source-line-no">3176</span><span id="line-3176">        if (closeSeqNum == HConstants.NO_SEQNUM) {</span>
-<span class="source-line-no">3177</span><span id="line-3177">          closeSeqNum = 0;</span>
-<span class="source-line-no">3178</span><span id="line-3178">        }</span>
-<span class="source-line-no">3179</span><span id="line-3179">      }</span>
-<span class="source-line-no">3180</span><span id="line-3180">      boolean selfMove = ServerName.isSameAddress(destination, this.getServerName());</span>
-<span class="source-line-no">3181</span><span id="line-3181">      addToMovedRegions(r.getRegionInfo().getEncodedName(), destination, closeSeqNum, selfMove);</span>
-<span class="source-line-no">3182</span><span id="line-3182">      if (selfMove) {</span>
-<span class="source-line-no">3183</span><span id="line-3183">        this.regionServerAccounting.getRetainedRegionRWRequestsCnt().put(</span>
-<span class="source-line-no">3184</span><span id="line-3184">          r.getRegionInfo().getEncodedName(),</span>
-<span class="source-line-no">3185</span><span id="line-3185">          new Pair&lt;&gt;(r.getReadRequestsCount(), r.getWriteRequestsCount()));</span>
-<span class="source-line-no">3186</span><span id="line-3186">      }</span>
-<span class="source-line-no">3187</span><span id="line-3187">    }</span>
-<span class="source-line-no">3188</span><span id="line-3188">    this.regionFavoredNodesMap.remove(r.getRegionInfo().getEncodedName());</span>
-<span class="source-line-no">3189</span><span id="line-3189">    configurationManager.deregisterObserver(r);</span>
-<span class="source-line-no">3190</span><span id="line-3190">    return toReturn != null;</span>
-<span class="source-line-no">3191</span><span id="line-3191">  }</span>
-<span class="source-line-no">3192</span><span id="line-3192"></span>
-<span class="source-line-no">3193</span><span id="line-3193">  /**</span>
-<span class="source-line-no">3194</span><span id="line-3194">   * Protected Utility method for safely obtaining an HRegion handle.</span>
-<span class="source-line-no">3195</span><span id="line-3195">   * @param regionName Name of online {@link HRegion} to return</span>
-<span class="source-line-no">3196</span><span id="line-3196">   * @return {@link HRegion} for &lt;code&gt;regionName&lt;/code&gt;</span>
-<span class="source-line-no">3197</span><span id="line-3197">   */</span>
-<span class="source-line-no">3198</span><span id="line-3198">  protected HRegion getRegion(final byte[] regionName) throws NotServingRegionException {</span>
-<span class="source-line-no">3199</span><span id="line-3199">    String encodedRegionName = RegionInfo.encodeRegionName(regionName);</span>
-<span class="source-line-no">3200</span><span id="line-3200">    return getRegionByEncodedName(regionName, encodedRegionName);</span>
-<span class="source-line-no">3201</span><span id="line-3201">  }</span>
-<span class="source-line-no">3202</span><span id="line-3202"></span>
-<span class="source-line-no">3203</span><span id="line-3203">  public HRegion getRegionByEncodedName(String encodedRegionName) throws NotServingRegionException {</span>
-<span class="source-line-no">3204</span><span id="line-3204">    return getRegionByEncodedName(null, encodedRegionName);</span>
+<span class="source-line-no">3104</span><span id="line-3104">    // previous can come back 'null' if not in map.</span>
+<span class="source-line-no">3105</span><span id="line-3105">    final Boolean previous =</span>
+<span class="source-line-no">3106</span><span id="line-3106">      this.regionsInTransitionInRS.putIfAbsent(Bytes.toBytes(encodedName), Boolean.FALSE);</span>
+<span class="source-line-no">3107</span><span id="line-3107"></span>
+<span class="source-line-no">3108</span><span id="line-3108">    if (Boolean.TRUE.equals(previous)) {</span>
+<span class="source-line-no">3109</span><span id="line-3109">      LOG.info("Received CLOSE for the region:" + encodedName + " , which we are already "</span>
+<span class="source-line-no">3110</span><span id="line-3110">        + "trying to OPEN. Cancelling OPENING.");</span>
+<span class="source-line-no">3111</span><span id="line-3111">      if (!regionsInTransitionInRS.replace(Bytes.toBytes(encodedName), previous, Boolean.FALSE)) {</span>
+<span class="source-line-no">3112</span><span id="line-3112">        // The replace failed. That should be an exceptional case, but theoretically it can happen.</span>
+<span class="source-line-no">3113</span><span id="line-3113">        // We're going to try to do a standard close then.</span>
+<span class="source-line-no">3114</span><span id="line-3114">        LOG.warn("The opening for region " + encodedName + " was done before we could cancel it."</span>
+<span class="source-line-no">3115</span><span id="line-3115">          + " Doing a standard close now");</span>
+<span class="source-line-no">3116</span><span id="line-3116">        return closeRegion(encodedName, abort, destination);</span>
+<span class="source-line-no">3117</span><span id="line-3117">      }</span>
+<span class="source-line-no">3118</span><span id="line-3118">      // Let's get the region from the online region list again</span>
+<span class="source-line-no">3119</span><span id="line-3119">      actualRegion = this.getRegion(encodedName);</span>
+<span class="source-line-no">3120</span><span id="line-3120">      if (actualRegion == null) { // If already online, we still need to close it.</span>
+<span class="source-line-no">3121</span><span id="line-3121">        LOG.info("The opening previously in progress has been cancelled by a CLOSE request.");</span>
+<span class="source-line-no">3122</span><span id="line-3122">        // The master deletes the znode when it receives this exception.</span>
+<span class="source-line-no">3123</span><span id="line-3123">        throw new NotServingRegionException(</span>
+<span class="source-line-no">3124</span><span id="line-3124">          "The region " + encodedName + " was opening but not yet served. Opening is cancelled.");</span>
+<span class="source-line-no">3125</span><span id="line-3125">      }</span>
+<span class="source-line-no">3126</span><span id="line-3126">    } else if (previous == null) {</span>
+<span class="source-line-no">3127</span><span id="line-3127">      LOG.info("Received CLOSE for {}", encodedName);</span>
+<span class="source-line-no">3128</span><span id="line-3128">    } else if (Boolean.FALSE.equals(previous)) {</span>
+<span class="source-line-no">3129</span><span id="line-3129">      LOG.info("Received CLOSE for the region: " + encodedName</span>
+<span class="source-line-no">3130</span><span id="line-3130">        + ", which we are already trying to CLOSE, but not completed yet");</span>
+<span class="source-line-no">3131</span><span id="line-3131">      return true;</span>
+<span class="source-line-no">3132</span><span id="line-3132">    }</span>
+<span class="source-line-no">3133</span><span id="line-3133"></span>
+<span class="source-line-no">3134</span><span id="line-3134">    if (actualRegion == null) {</span>
+<span class="source-line-no">3135</span><span id="line-3135">      LOG.debug("Received CLOSE for a region which is not online, and we're not opening.");</span>
+<span class="source-line-no">3136</span><span id="line-3136">      this.regionsInTransitionInRS.remove(Bytes.toBytes(encodedName));</span>
+<span class="source-line-no">3137</span><span id="line-3137">      // The master deletes the znode when it receives this exception.</span>
+<span class="source-line-no">3138</span><span id="line-3138">      throw new NotServingRegionException(</span>
+<span class="source-line-no">3139</span><span id="line-3139">        "The region " + encodedName + " is not online, and is not opening.");</span>
+<span class="source-line-no">3140</span><span id="line-3140">    }</span>
+<span class="source-line-no">3141</span><span id="line-3141"></span>
+<span class="source-line-no">3142</span><span id="line-3142">    CloseRegionHandler crh;</span>
+<span class="source-line-no">3143</span><span id="line-3143">    final RegionInfo hri = actualRegion.getRegionInfo();</span>
+<span class="source-line-no">3144</span><span id="line-3144">    if (hri.isMetaRegion()) {</span>
+<span class="source-line-no">3145</span><span id="line-3145">      crh = new CloseMetaHandler(this, this, hri, abort);</span>
+<span class="source-line-no">3146</span><span id="line-3146">    } else {</span>
+<span class="source-line-no">3147</span><span id="line-3147">      crh = new CloseRegionHandler(this, this, hri, abort, destination);</span>
+<span class="source-line-no">3148</span><span id="line-3148">    }</span>
+<span class="source-line-no">3149</span><span id="line-3149">    this.executorService.submit(crh);</span>
+<span class="source-line-no">3150</span><span id="line-3150">    return true;</span>
+<span class="source-line-no">3151</span><span id="line-3151">  }</span>
+<span class="source-line-no">3152</span><span id="line-3152"></span>
+<span class="source-line-no">3153</span><span id="line-3153">  /**</span>
+<span class="source-line-no">3154</span><span id="line-3154">   * @return HRegion for the passed binary &lt;code&gt;regionName&lt;/code&gt; or null if named region is not</span>
+<span class="source-line-no">3155</span><span id="line-3155">   *         member of the online regions.</span>
+<span class="source-line-no">3156</span><span id="line-3156">   */</span>
+<span class="source-line-no">3157</span><span id="line-3157">  public HRegion getOnlineRegion(final byte[] regionName) {</span>
+<span class="source-line-no">3158</span><span id="line-3158">    String encodedRegionName = RegionInfo.encodeRegionName(regionName);</span>
+<span class="source-line-no">3159</span><span id="line-3159">    return this.onlineRegions.get(encodedRegionName);</span>
+<span class="source-line-no">3160</span><span id="line-3160">  }</span>
+<span class="source-line-no">3161</span><span id="line-3161"></span>
+<span class="source-line-no">3162</span><span id="line-3162">  @Override</span>
+<span class="source-line-no">3163</span><span id="line-3163">  public HRegion getRegion(final String encodedRegionName) {</span>
+<span class="source-line-no">3164</span><span id="line-3164">    return this.onlineRegions.get(encodedRegionName);</span>
+<span class="source-line-no">3165</span><span id="line-3165">  }</span>
+<span class="source-line-no">3166</span><span id="line-3166"></span>
+<span class="source-line-no">3167</span><span id="line-3167">  @Override</span>
+<span class="source-line-no">3168</span><span id="line-3168">  public boolean removeRegion(final HRegion r, ServerName destination) {</span>
+<span class="source-line-no">3169</span><span id="line-3169">    HRegion toReturn = this.onlineRegions.remove(r.getRegionInfo().getEncodedName());</span>
+<span class="source-line-no">3170</span><span id="line-3170">    if (DataTieringManager.getInstance() != null) {</span>
+<span class="source-line-no">3171</span><span id="line-3171">      DataTieringManager.getInstance().getRegionColdDataSize()</span>
+<span class="source-line-no">3172</span><span id="line-3172">        .remove(r.getRegionInfo().getEncodedName());</span>
+<span class="source-line-no">3173</span><span id="line-3173">    }</span>
+<span class="source-line-no">3174</span><span id="line-3174">    metricsRegionServerImpl.requestsCountCache.remove(r.getRegionInfo().getEncodedName());</span>
+<span class="source-line-no">3175</span><span id="line-3175">    if (destination != null) {</span>
+<span class="source-line-no">3176</span><span id="line-3176">      long closeSeqNum = r.getMaxFlushedSeqId();</span>
+<span class="source-line-no">3177</span><span id="line-3177">      if (closeSeqNum == HConstants.NO_SEQNUM) {</span>
+<span class="source-line-no">3178</span><span id="line-3178">        // No edits in WAL for this region; get the sequence number when the region was opened.</span>
+<span class="source-line-no">3179</span><span id="line-3179">        closeSeqNum = r.getOpenSeqNum();</span>
+<span class="source-line-no">3180</span><span id="line-3180">        if (closeSeqNum == HConstants.NO_SEQNUM) {</span>
+<span class="source-line-no">3181</span><span id="line-3181">          closeSeqNum = 0;</span>
+<span class="source-line-no">3182</span><span id="line-3182">        }</span>
+<span class="source-line-no">3183</span><span id="line-3183">      }</span>
+<span class="source-line-no">3184</span><span id="line-3184">      boolean selfMove = ServerName.isSameAddress(destination, this.getServerName());</span>
+<span class="source-line-no">3185</span><span id="line-3185">      addToMovedRegions(r.getRegionInfo().getEncodedName(), destination, closeSeqNum, selfMove);</span>
+<span class="source-line-no">3186</span><span id="line-3186">      if (selfMove) {</span>
+<span class="source-line-no">3187</span><span id="line-3187">        this.regionServerAccounting.getRetainedRegionRWRequestsCnt().put(</span>
+<span class="source-line-no">3188</span><span id="line-3188">          r.getRegionInfo().getEncodedName(),</span>
+<span class="source-line-no">3189</span><span id="line-3189">          new Pair&lt;&gt;(r.getReadRequestsCount(), r.getWriteRequestsCount()));</span>
+<span class="source-line-no">3190</span><span id="line-3190">      }</span>
+<span class="source-line-no">3191</span><span id="line-3191">    }</span>
+<span class="source-line-no">3192</span><span id="line-3192">    this.regionFavoredNodesMap.remove(r.getRegionInfo().getEncodedName());</span>
+<span class="source-line-no">3193</span><span id="line-3193">    configurationManager.deregisterObserver(r);</span>
+<span class="source-line-no">3194</span><span id="line-3194">    return toReturn != null;</span>
+<span class="source-line-no">3195</span><span id="line-3195">  }</span>
+<span class="source-line-no">3196</span><span id="line-3196"></span>
+<span class="source-line-no">3197</span><span id="line-3197">  /**</span>
+<span class="source-line-no">3198</span><span id="line-3198">   * Protected Utility method for safely obtaining an HRegion handle.</span>
+<span class="source-line-no">3199</span><span id="line-3199">   * @param regionName Name of online {@link HRegion} to return</span>
+<span class="source-line-no">3200</span><span id="line-3200">   * @return {@link HRegion} for &lt;code&gt;regionName&lt;/code&gt;</span>
+<span class="source-line-no">3201</span><span id="line-3201">   */</span>
+<span class="source-line-no">3202</span><span id="line-3202">  protected HRegion getRegion(final byte[] regionName) throws NotServingRegionException {</span>
+<span class="source-line-no">3203</span><span id="line-3203">    String encodedRegionName = RegionInfo.encodeRegionName(regionName);</span>
+<span class="source-line-no">3204</span><span id="line-3204">    return getRegionByEncodedName(regionName, encodedRegionName);</span>
 <span class="source-line-no">3205</span><span id="line-3205">  }</span>
 <span class="source-line-no">3206</span><span id="line-3206"></span>
-<span class="source-line-no">3207</span><span id="line-3207">  private HRegion getRegionByEncodedName(byte[] regionName, String encodedRegionName)</span>
-<span class="source-line-no">3208</span><span id="line-3208">    throws NotServingRegionException {</span>
-<span class="source-line-no">3209</span><span id="line-3209">    HRegion region = this.onlineRegions.get(encodedRegionName);</span>
-<span class="source-line-no">3210</span><span id="line-3210">    if (region == null) {</span>
-<span class="source-line-no">3211</span><span id="line-3211">      MovedRegionInfo moveInfo = getMovedRegion(encodedRegionName);</span>
-<span class="source-line-no">3212</span><span id="line-3212">      if (moveInfo != null) {</span>
-<span class="source-line-no">3213</span><span id="line-3213">        throw new RegionMovedException(moveInfo.getServerName(), moveInfo.getSeqNum());</span>
-<span class="source-line-no">3214</span><span id="line-3214">      }</span>
-<span class="source-line-no">3215</span><span id="line-3215">      Boolean isOpening = this.regionsInTransitionInRS.get(Bytes.toBytes(encodedRegionName));</span>
-<span class="source-line-no">3216</span><span id="line-3216">      String regionNameStr =</span>
-<span class="source-line-no">3217</span><span id="line-3217">        regionName == null ? encodedRegionName : Bytes.toStringBinary(regionName);</span>
-<span class="source-line-no">3218</span><span id="line-3218">      if (isOpening != null &amp;&amp; isOpening) {</span>
-<span class="source-line-no">3219</span><span id="line-3219">        throw new RegionOpeningException(</span>
-<span class="source-line-no">3220</span><span id="line-3220">          "Region " + regionNameStr + " is opening on " + this.serverName);</span>
-<span class="source-line-no">3221</span><span id="line-3221">      }</span>
-<span class="source-line-no">3222</span><span id="line-3222">      throw new NotServingRegionException(</span>
-<span class="source-line-no">3223</span><span id="line-3223">        "" + regionNameStr + " is not online on " + this.serverName);</span>
-<span class="source-line-no">3224</span><span id="line-3224">    }</span>
-<span class="source-line-no">3225</span><span id="line-3225">    return region;</span>
-<span class="source-line-no">3226</span><span id="line-3226">  }</span>
-<span class="source-line-no">3227</span><span id="line-3227"></span>
-<span class="source-line-no">3228</span><span id="line-3228">  /**</span>
-<span class="source-line-no">3229</span><span id="line-3229">   * Cleanup after Throwable caught invoking method. Converts &lt;code&gt;t&lt;/code&gt; to IOE if it isn't</span>
-<span class="source-line-no">3230</span><span id="line-3230">   * already.</span>
-<span class="source-line-no">3231</span><span id="line-3231">   * @param t   Throwable</span>
-<span class="source-line-no">3232</span><span id="line-3232">   * @param msg Message to log in error. Can be null.</span>
-<span class="source-line-no">3233</span><span id="line-3233">   * @return Throwable converted to an IOE; methods can only let out IOEs.</span>
-<span class="source-line-no">3234</span><span id="line-3234">   */</span>
-<span class="source-line-no">3235</span><span id="line-3235">  private Throwable cleanup(final Throwable t, final String msg) {</span>
-<span class="source-line-no">3236</span><span id="line-3236">    // Don't log as error if NSRE; NSRE is 'normal' operation.</span>
-<span class="source-line-no">3237</span><span id="line-3237">    if (t instanceof NotServingRegionException) {</span>
-<span class="source-line-no">3238</span><span id="line-3238">      LOG.debug("NotServingRegionException; " + t.getMessage());</span>
-<span class="source-line-no">3239</span><span id="line-3239">      return t;</span>
-<span class="source-line-no">3240</span><span id="line-3240">    }</span>
-<span class="source-line-no">3241</span><span id="line-3241">    Throwable e = t instanceof RemoteException ? ((RemoteException) t).unwrapRemoteException() : t;</span>
-<span class="source-line-no">3242</span><span id="line-3242">    if (msg == null) {</span>
-<span class="source-line-no">3243</span><span id="line-3243">      LOG.error("", e);</span>
-<span class="source-line-no">3244</span><span id="line-3244">    } else {</span>
-<span class="source-line-no">3245</span><span id="line-3245">      LOG.error(msg, e);</span>
-<span class="source-line-no">3246</span><span id="line-3246">    }</span>
-<span class="source-line-no">3247</span><span id="line-3247">    if (!rpcServices.checkOOME(t)) {</span>
-<span class="source-line-no">3248</span><span id="line-3248">      checkFileSystem();</span>
-<span class="source-line-no">3249</span><span id="line-3249">    }</span>
-<span class="source-line-no">3250</span><span id="line-3250">    return t;</span>
-<span class="source-line-no">3251</span><span id="line-3251">  }</span>
-<span class="source-line-no">3252</span><span id="line-3252"></span>
-<span class="source-line-no">3253</span><span id="line-3253">  /**</span>
-<span class="source-line-no">3254</span><span id="line-3254">   * @param msg Message to put in new IOE if passed &lt;code&gt;t&lt;/code&gt; is not an IOE</span>
-<span class="source-line-no">3255</span><span id="line-3255">   * @return Make &lt;code&gt;t&lt;/code&gt; an IOE if it isn't already.</span>
-<span class="source-line-no">3256</span><span id="line-3256">   */</span>
-<span class="source-line-no">3257</span><span id="line-3257">  private IOException convertThrowableToIOE(final Throwable t, final String msg) {</span>
-<span class="source-line-no">3258</span><span id="line-3258">    return (t instanceof IOException ? (IOException) t</span>
-<span class="source-line-no">3259</span><span id="line-3259">      : msg == null || msg.length() == 0 ? new IOException(t)</span>
-<span class="source-line-no">3260</span><span id="line-3260">      : new IOException(msg, t));</span>
-<span class="source-line-no">3261</span><span id="line-3261">  }</span>
-<span class="source-line-no">3262</span><span id="line-3262"></span>
-<span class="source-line-no">3263</span><span id="line-3263">  /**</span>
-<span class="source-line-no">3264</span><span id="line-3264">   * Checks to see if the file system is still accessible. If not, sets abortRequested and</span>
-<span class="source-line-no">3265</span><span id="line-3265">   * stopRequested</span>
-<span class="source-line-no">3266</span><span id="line-3266">   * @return false if file system is not available</span>
-<span class="source-line-no">3267</span><span id="line-3267">   */</span>
-<span class="source-line-no">3268</span><span id="line-3268">  boolean checkFileSystem() {</span>
-<span class="source-line-no">3269</span><span id="line-3269">    if (this.dataFsOk &amp;&amp; this.dataFs != null) {</span>
-<span class="source-line-no">3270</span><span id="line-3270">      try {</span>
-<span class="source-line-no">3271</span><span id="line-3271">        FSUtils.checkFileSystemAvailable(this.dataFs);</span>
-<span class="source-line-no">3272</span><span id="line-3272">      } catch (IOException e) {</span>
-<span class="source-line-no">3273</span><span id="line-3273">        abort("File System not available", e);</span>
-<span class="source-line-no">3274</span><span id="line-3274">        this.dataFsOk = false;</span>
-<span class="source-line-no">3275</span><span id="line-3275">      }</span>
-<span class="source-line-no">3276</span><span id="line-3276">    }</span>
-<span class="source-line-no">3277</span><span id="line-3277">    return this.dataFsOk;</span>
-<span class="source-line-no">3278</span><span id="line-3278">  }</span>
-<span class="source-line-no">3279</span><span id="line-3279"></span>
-<span class="source-line-no">3280</span><span id="line-3280">  @Override</span>
-<span class="source-line-no">3281</span><span id="line-3281">  public void updateRegionFavoredNodesMapping(String encodedRegionName,</span>
-<span class="source-line-no">3282</span><span id="line-3282">    List&lt;org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName&gt; favoredNodes) {</span>
-<span class="source-line-no">3283</span><span id="line-3283">    Address[] addr = new Address[favoredNodes.size()];</span>
-<span class="source-line-no">3284</span><span id="line-3284">    // Refer to the comment on the declaration of regionFavoredNodesMap on why</span>
-<span class="source-line-no">3285</span><span id="line-3285">    // it is a map of region name to Address[]</span>
-<span class="source-line-no">3286</span><span id="line-3286">    for (int i = 0; i &lt; favoredNodes.size(); i++) {</span>
-<span class="source-line-no">3287</span><span id="line-3287">      addr[i] = Address.fromParts(favoredNodes.get(i).getHostName(), favoredNodes.get(i).getPort());</span>
-<span class="source-line-no">3288</span><span id="line-3288">    }</span>
-<span class="source-line-no">3289</span><span id="line-3289">    regionFavoredNodesMap.put(encodedRegionName, addr);</span>
-<span class="source-line-no">3290</span><span id="line-3290">  }</span>
-<span class="source-line-no">3291</span><span id="line-3291"></span>
-<span class="source-line-no">3292</span><span id="line-3292">  /**</span>
-<span class="source-line-no">3293</span><span id="line-3293">   * Return the favored nodes for a region given its encoded name. Look at the comment around</span>
-<span class="source-line-no">3294</span><span id="line-3294">   * {@link #regionFavoredNodesMap} on why we convert to InetSocketAddress[] here.</span>
-<span class="source-line-no">3295</span><span id="line-3295">   * @param encodedRegionName the encoded region name.</span>
-<span class="source-line-no">3296</span><span id="line-3296">   * @return array of favored locations</span>
-<span class="source-line-no">3297</span><span id="line-3297">   */</span>
-<span class="source-line-no">3298</span><span id="line-3298">  @Override</span>
-<span class="source-line-no">3299</span><span id="line-3299">  public InetSocketAddress[] getFavoredNodesForRegion(String encodedRegionName) {</span>
-<span class="source-line-no">3300</span><span id="line-3300">    return Address.toSocketAddress(regionFavoredNodesMap.get(encodedRegionName));</span>
-<span class="source-line-no">3301</span><span id="line-3301">  }</span>
-<span class="source-line-no">3302</span><span id="line-3302"></span>
-<span class="source-line-no">3303</span><span id="line-3303">  @Override</span>
-<span class="source-line-no">3304</span><span id="line-3304">  public ServerNonceManager getNonceManager() {</span>
-<span class="source-line-no">3305</span><span id="line-3305">    return this.nonceManager;</span>
-<span class="source-line-no">3306</span><span id="line-3306">  }</span>
-<span class="source-line-no">3307</span><span id="line-3307"></span>
-<span class="source-line-no">3308</span><span id="line-3308">  private static class MovedRegionInfo {</span>
-<span class="source-line-no">3309</span><span id="line-3309">    private final ServerName serverName;</span>
-<span class="source-line-no">3310</span><span id="line-3310">    private final long seqNum;</span>
+<span class="source-line-no">3207</span><span id="line-3207">  public HRegion getRegionByEncodedName(String encodedRegionName) throws NotServingRegionException {</span>
+<span class="source-line-no">3208</span><span id="line-3208">    return getRegionByEncodedName(null, encodedRegionName);</span>
+<span class="source-line-no">3209</span><span id="line-3209">  }</span>
+<span class="source-line-no">3210</span><span id="line-3210"></span>
+<span class="source-line-no">3211</span><span id="line-3211">  private HRegion getRegionByEncodedName(byte[] regionName, String encodedRegionName)</span>
+<span class="source-line-no">3212</span><span id="line-3212">    throws NotServingRegionException {</span>
+<span class="source-line-no">3213</span><span id="line-3213">    HRegion region = this.onlineRegions.get(encodedRegionName);</span>
+<span class="source-line-no">3214</span><span id="line-3214">    if (region == null) {</span>
+<span class="source-line-no">3215</span><span id="line-3215">      MovedRegionInfo moveInfo = getMovedRegion(encodedRegionName);</span>
+<span class="source-line-no">3216</span><span id="line-3216">      if (moveInfo != null) {</span>
+<span class="source-line-no">3217</span><span id="line-3217">        throw new RegionMovedException(moveInfo.getServerName(), moveInfo.getSeqNum());</span>
+<span class="source-line-no">3218</span><span id="line-3218">      }</span>
+<span class="source-line-no">3219</span><span id="line-3219">      Boolean isOpening = this.regionsInTransitionInRS.get(Bytes.toBytes(encodedRegionName));</span>
+<span class="source-line-no">3220</span><span id="line-3220">      String regionNameStr =</span>
+<span class="source-line-no">3221</span><span id="line-3221">        regionName == null ? encodedRegionName : Bytes.toStringBinary(regionName);</span>
+<span class="source-line-no">3222</span><span id="line-3222">      if (isOpening != null &amp;&amp; isOpening) {</span>
+<span class="source-line-no">3223</span><span id="line-3223">        throw new RegionOpeningException(</span>
+<span class="source-line-no">3224</span><span id="line-3224">          "Region " + regionNameStr + " is opening on " + this.serverName);</span>
+<span class="source-line-no">3225</span><span id="line-3225">      }</span>
+<span class="source-line-no">3226</span><span id="line-3226">      throw new NotServingRegionException(</span>
+<span class="source-line-no">3227</span><span id="line-3227">        "" + regionNameStr + " is not online on " + this.serverName);</span>
+<span class="source-line-no">3228</span><span id="line-3228">    }</span>
+<span class="source-line-no">3229</span><span id="line-3229">    return region;</span>
+<span class="source-line-no">3230</span><span id="line-3230">  }</span>
+<span class="source-line-no">3231</span><span id="line-3231"></span>
+<span class="source-line-no">3232</span><span id="line-3232">  /**</span>
+<span class="source-line-no">3233</span><span id="line-3233">   * Cleanup after Throwable caught invoking method. Converts &lt;code&gt;t&lt;/code&gt; to IOE if it isn't</span>
+<span class="source-line-no">3234</span><span id="line-3234">   * already.</span>
+<span class="source-line-no">3235</span><span id="line-3235">   * @param t   Throwable</span>
+<span class="source-line-no">3236</span><span id="line-3236">   * @param msg Message to log in error. Can be null.</span>
+<span class="source-line-no">3237</span><span id="line-3237">   * @return Throwable converted to an IOE; methods can only let out IOEs.</span>
+<span class="source-line-no">3238</span><span id="line-3238">   */</span>
+<span class="source-line-no">3239</span><span id="line-3239">  private Throwable cleanup(final Throwable t, final String msg) {</span>
+<span class="source-line-no">3240</span><span id="line-3240">    // Don't log as error if NSRE; NSRE is 'normal' operation.</span>
+<span class="source-line-no">3241</span><span id="line-3241">    if (t instanceof NotServingRegionException) {</span>
+<span class="source-line-no">3242</span><span id="line-3242">      LOG.debug("NotServingRegionException; " + t.getMessage());</span>
+<span class="source-line-no">3243</span><span id="line-3243">      return t;</span>
+<span class="source-line-no">3244</span><span id="line-3244">    }</span>
+<span class="source-line-no">3245</span><span id="line-3245">    Throwable e = t instanceof RemoteException ? ((RemoteException) t).unwrapRemoteException() : t;</span>
+<span class="source-line-no">3246</span><span id="line-3246">    if (msg == null) {</span>
+<span class="source-line-no">3247</span><span id="line-3247">      LOG.error("", e);</span>
+<span class="source-line-no">3248</span><span id="line-3248">    } else {</span>
+<span class="source-line-no">3249</span><span id="line-3249">      LOG.error(msg, e);</span>
+<span class="source-line-no">3250</span><span id="line-3250">    }</span>
+<span class="source-line-no">3251</span><span id="line-3251">    if (!rpcServices.checkOOME(t)) {</span>
+<span class="source-line-no">3252</span><span id="line-3252">      checkFileSystem();</span>
+<span class="source-line-no">3253</span><span id="line-3253">    }</span>
+<span class="source-line-no">3254</span><span id="line-3254">    return t;</span>
+<span class="source-line-no">3255</span><span id="line-3255">  }</span>
+<span class="source-line-no">3256</span><span id="line-3256"></span>
+<span class="source-line-no">3257</span><span id="line-3257">  /**</span>
+<span class="source-line-no">3258</span><span id="line-3258">   * @param msg Message to put in new IOE if passed &lt;code&gt;t&lt;/code&gt; is not an IOE</span>
+<span class="source-line-no">3259</span><span id="line-3259">   * @return Make &lt;code&gt;t&lt;/code&gt; an IOE if it isn't already.</span>
+<span class="source-line-no">3260</span><span id="line-3260">   */</span>
+<span class="source-line-no">3261</span><span id="line-3261">  private IOException convertThrowableToIOE(final Throwable t, final String msg) {</span>
+<span class="source-line-no">3262</span><span id="line-3262">    return (t instanceof IOException ? (IOException) t</span>
+<span class="source-line-no">3263</span><span id="line-3263">      : msg == null || msg.length() == 0 ? new IOException(t)</span>
+<span class="source-line-no">3264</span><span id="line-3264">      : new IOException(msg, t));</span>
+<span class="source-line-no">3265</span><span id="line-3265">  }</span>
+<span class="source-line-no">3266</span><span id="line-3266"></span>
+<span class="source-line-no">3267</span><span id="line-3267">  /**</span>
+<span class="source-line-no">3268</span><span id="line-3268">   * Checks to see if the file system is still accessible. If not, sets abortRequested and</span>
+<span class="source-line-no">3269</span><span id="line-3269">   * stopRequested</span>
+<span class="source-line-no">3270</span><span id="line-3270">   * @return false if file system is not available</span>
+<span class="source-line-no">3271</span><span id="line-3271">   */</span>
+<span class="source-line-no">3272</span><span id="line-3272">  boolean checkFileSystem() {</span>
+<span class="source-line-no">3273</span><span id="line-3273">    if (this.dataFsOk &amp;&amp; this.dataFs != null) {</span>
+<span class="source-line-no">3274</span><span id="line-3274">      try {</span>
+<span class="source-line-no">3275</span><span id="line-3275">        FSUtils.checkFileSystemAvailable(this.dataFs);</span>
+<span class="source-line-no">3276</span><span id="line-3276">      } catch (IOException e) {</span>
+<span class="source-line-no">3277</span><span id="line-3277">        abort("File System not available", e);</span>
+<span class="source-line-no">3278</span><span id="line-3278">        this.dataFsOk = false;</span>
+<span class="source-line-no">3279</span><span id="line-3279">      }</span>
+<span class="source-line-no">3280</span><span id="line-3280">    }</span>
+<span class="source-line-no">3281</span><span id="line-3281">    return this.dataFsOk;</span>
+<span class="source-line-no">3282</span><span id="line-3282">  }</span>
+<span class="source-line-no">3283</span><span id="line-3283"></span>
+<span class="source-line-no">3284</span><span id="line-3284">  @Override</span>
+<span class="source-line-no">3285</span><span id="line-3285">  public void updateRegionFavoredNodesMapping(String encodedRegionName,</span>
+<span class="source-line-no">3286</span><span id="line-3286">    List&lt;org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName&gt; favoredNodes) {</span>
+<span class="source-line-no">3287</span><span id="line-3287">    Address[] addr = new Address[favoredNodes.size()];</span>
+<span class="source-line-no">3288</span><span id="line-3288">    // Refer to the comment on the declaration of regionFavoredNodesMap on why</span>
+<span class="source-line-no">3289</span><span id="line-3289">    // it is a map of region name to Address[]</span>
+<span class="source-line-no">3290</span><span id="line-3290">    for (int i = 0; i &lt; favoredNodes.size(); i++) {</span>
+<span class="source-line-no">3291</span><span id="line-3291">      addr[i] = Address.fromParts(favoredNodes.get(i).getHostName(), favoredNodes.get(i).getPort());</span>
+<span class="source-line-no">3292</span><span id="line-3292">    }</span>
+<span class="source-line-no">3293</span><span id="line-3293">    regionFavoredNodesMap.put(encodedRegionName, addr);</span>
+<span class="source-line-no">3294</span><span id="line-3294">  }</span>
+<span class="source-line-no">3295</span><span id="line-3295"></span>
+<span class="source-line-no">3296</span><span id="line-3296">  /**</span>
+<span class="source-line-no">3297</span><span id="line-3297">   * Return the favored nodes for a region given its encoded name. Look at the comment around</span>
+<span class="source-line-no">3298</span><span id="line-3298">   * {@link #regionFavoredNodesMap} on why we convert to InetSocketAddress[] here.</span>
+<span class="source-line-no">3299</span><span id="line-3299">   * @param encodedRegionName the encoded region name.</span>
+<span class="source-line-no">3300</span><span id="line-3300">   * @return array of favored locations</span>
+<span class="source-line-no">3301</span><span id="line-3301">   */</span>
+<span class="source-line-no">3302</span><span id="line-3302">  @Override</span>
+<span class="source-line-no">3303</span><span id="line-3303">  public InetSocketAddress[] getFavoredNodesForRegion(String encodedRegionName) {</span>
+<span class="source-line-no">3304</span><span id="line-3304">    return Address.toSocketAddress(regionFavoredNodesMap.get(encodedRegionName));</span>
+<span class="source-line-no">3305</span><span id="line-3305">  }</span>
+<span class="source-line-no">3306</span><span id="line-3306"></span>
+<span class="source-line-no">3307</span><span id="line-3307">  @Override</span>
+<span class="source-line-no">3308</span><span id="line-3308">  public ServerNonceManager getNonceManager() {</span>
+<span class="source-line-no">3309</span><span id="line-3309">    return this.nonceManager;</span>
+<span class="source-line-no">3310</span><span id="line-3310">  }</span>
 <span class="source-line-no">3311</span><span id="line-3311"></span>
-<span class="source-line-no">3312</span><span id="line-3312">    MovedRegionInfo(ServerName serverName, long closeSeqNum) {</span>
-<span class="source-line-no">3313</span><span id="line-3313">      this.serverName = serverName;</span>
-<span class="source-line-no">3314</span><span id="line-3314">      this.seqNum = closeSeqNum;</span>
-<span class="source-line-no">3315</span><span id="line-3315">    }</span>
-<span class="source-line-no">3316</span><span id="line-3316"></span>
-<span class="source-line-no">3317</span><span id="line-3317">    public ServerName getServerName() {</span>
-<span class="source-line-no">3318</span><span id="line-3318">      return serverName;</span>
+<span class="source-line-no">3312</span><span id="line-3312">  private static class MovedRegionInfo {</span>
+<span class="source-line-no">3313</span><span id="line-3313">    private final ServerName serverName;</span>
+<span class="source-line-no">3314</span><span id="line-3314">    private final long seqNum;</span>
+<span class="source-line-no">3315</span><span id="line-3315"></span>
+<span class="source-line-no">3316</span><span id="line-3316">    MovedRegionInfo(ServerName serverName, long closeSeqNum) {</span>
+<span class="source-line-no">3317</span><span id="line-3317">      this.serverName = serverName;</span>
+<span class="source-line-no">3318</span><span id="line-3318">      this.seqNum = closeSeqNum;</span>
 <span class="source-line-no">3319</span><span id="line-3319">    }</span>
 <span class="source-line-no">3320</span><span id="line-3320"></span>
-<span class="source-line-no">3321</span><span id="line-3321">    public long getSeqNum() {</span>
-<span class="source-line-no">3322</span><span id="line-3322">      return seqNum;</span>
+<span class="source-line-no">3321</span><span id="line-3321">    public ServerName getServerName() {</span>
+<span class="source-line-no">3322</span><span id="line-3322">      return serverName;</span>
 <span class="source-line-no">3323</span><span id="line-3323">    }</span>
-<span class="source-line-no">3324</span><span id="line-3324">  }</span>
-<span class="source-line-no">3325</span><span id="line-3325"></span>
-<span class="source-line-no">3326</span><span id="line-3326">  /**</span>
-<span class="source-line-no">3327</span><span id="line-3327">   * We need a timeout. If not there is a risk of giving a wrong information: this would double the</span>
-<span class="source-line-no">3328</span><span id="line-3328">   * number of network calls instead of reducing them.</span>
-<span class="source-line-no">3329</span><span id="line-3329">   */</span>
-<span class="source-line-no">3330</span><span id="line-3330">  private static final int TIMEOUT_REGION_MOVED = (2 * 60 * 1000);</span>
-<span class="source-line-no">3331</span><span id="line-3331"></span>
-<span class="source-line-no">3332</span><span id="line-3332">  private void addToMovedRegions(String encodedName, ServerName destination, long closeSeqNum,</span>
-<span class="source-line-no">3333</span><span id="line-3333">    boolean selfMove) {</span>
-<span class="source-line-no">3334</span><span id="line-3334">    if (selfMove) {</span>
-<span class="source-line-no">3335</span><span id="line-3335">      LOG.warn("Not adding moved region record: " + encodedName + " to self.");</span>
-<span class="source-line-no">3336</span><span id="line-3336">      return;</span>
-<span class="source-line-no">3337</span><span id="line-3337">    }</span>
-<span class="source-line-no">3338</span><span id="line-3338">    LOG.info("Adding " + encodedName + " move to " + destination + " record at close sequenceid="</span>
-<span class="source-line-no">3339</span><span id="line-3339">      + closeSeqNum);</span>
-<span class="source-line-no">3340</span><span id="line-3340">    movedRegionInfoCache.put(encodedName, new MovedRegionInfo(destination, closeSeqNum));</span>
-<span class="source-line-no">3341</span><span id="line-3341">  }</span>
-<span class="source-line-no">3342</span><span id="line-3342"></span>
-<span class="source-line-no">3343</span><span id="line-3343">  void removeFromMovedRegions(String encodedName) {</span>
-<span class="source-line-no">3344</span><span id="line-3344">    movedRegionInfoCache.invalidate(encodedName);</span>
+<span class="source-line-no">3324</span><span id="line-3324"></span>
+<span class="source-line-no">3325</span><span id="line-3325">    public long getSeqNum() {</span>
+<span class="source-line-no">3326</span><span id="line-3326">      return seqNum;</span>
+<span class="source-line-no">3327</span><span id="line-3327">    }</span>
+<span class="source-line-no">3328</span><span id="line-3328">  }</span>
+<span class="source-line-no">3329</span><span id="line-3329"></span>
+<span class="source-line-no">3330</span><span id="line-3330">  /**</span>
+<span class="source-line-no">3331</span><span id="line-3331">   * We need a timeout. If not there is a risk of giving a wrong information: this would double the</span>
+<span class="source-line-no">3332</span><span id="line-3332">   * number of network calls instead of reducing them.</span>
+<span class="source-line-no">3333</span><span id="line-3333">   */</span>
+<span class="source-line-no">3334</span><span id="line-3334">  private static final int TIMEOUT_REGION_MOVED = (2 * 60 * 1000);</span>
+<span class="source-line-no">3335</span><span id="line-3335"></span>
+<span class="source-line-no">3336</span><span id="line-3336">  private void addToMovedRegions(String encodedName, ServerName destination, long closeSeqNum,</span>
+<span class="source-line-no">3337</span><span id="line-3337">    boolean selfMove) {</span>
+<span class="source-line-no">3338</span><span id="line-3338">    if (selfMove) {</span>
+<span class="source-line-no">3339</span><span id="line-3339">      LOG.warn("Not adding moved region record: " + encodedName + " to self.");</span>
+<span class="source-line-no">3340</span><span id="line-3340">      return;</span>
+<span class="source-line-no">3341</span><span id="line-3341">    }</span>
+<span class="source-line-no">3342</span><span id="line-3342">    LOG.info("Adding " + encodedName + " move to " + destination + " record at close sequenceid="</span>
+<span class="source-line-no">3343</span><span id="line-3343">      + closeSeqNum);</span>
+<span class="source-line-no">3344</span><span id="line-3344">    movedRegionInfoCache.put(encodedName, new MovedRegionInfo(destination, closeSeqNum));</span>
 <span class="source-line-no">3345</span><span id="line-3345">  }</span>
 <span class="source-line-no">3346</span><span id="line-3346"></span>
-<span class="source-line-no">3347</span><span id="line-3347">  @InterfaceAudience.Private</span>
-<span class="source-line-no">3348</span><span id="line-3348">  public MovedRegionInfo getMovedRegion(String encodedRegionName) {</span>
-<span class="source-line-no">3349</span><span id="line-3349">    return movedRegionInfoCache.getIfPresent(encodedRegionName);</span>
-<span class="source-line-no">3350</span><span id="line-3350">  }</span>
-<span class="source-line-no">3351</span><span id="line-3351"></span>
-<span class="source-line-no">3352</span><span id="line-3352">  @InterfaceAudience.Private</span>
-<span class="source-line-no">3353</span><span id="line-3353">  public int movedRegionCacheExpiredTime() {</span>
-<span class="source-line-no">3354</span><span id="line-3354">    return TIMEOUT_REGION_MOVED;</span>
-<span class="source-line-no">3355</span><span id="line-3355">  }</span>
-<span class="source-line-no">3356</span><span id="line-3356"></span>
-<span class="source-line-no">3357</span><span id="line-3357">  private String getMyEphemeralNodePath() {</span>
-<span class="source-line-no">3358</span><span id="line-3358">    return zooKeeper.getZNodePaths().getRsPath(serverName);</span>
+<span class="source-line-no">3347</span><span id="line-3347">  void removeFromMovedRegions(String encodedName) {</span>
+<span class="source-line-no">3348</span><span id="line-3348">    movedRegionInfoCache.invalidate(encodedName);</span>
+<span class="source-line-no">3349</span><span id="line-3349">  }</span>
+<span class="source-line-no">3350</span><span id="line-3350"></span>
+<span class="source-line-no">3351</span><span id="line-3351">  @InterfaceAudience.Private</span>
+<span class="source-line-no">3352</span><span id="line-3352">  public MovedRegionInfo getMovedRegion(String encodedRegionName) {</span>
+<span class="source-line-no">3353</span><span id="line-3353">    return movedRegionInfoCache.getIfPresent(encodedRegionName);</span>
+<span class="source-line-no">3354</span><span id="line-3354">  }</span>
+<span class="source-line-no">3355</span><span id="line-3355"></span>
+<span class="source-line-no">3356</span><span id="line-3356">  @InterfaceAudience.Private</span>
+<span class="source-line-no">3357</span><span id="line-3357">  public int movedRegionCacheExpiredTime() {</span>
+<span class="source-line-no">3358</span><span id="line-3358">    return TIMEOUT_REGION_MOVED;</span>
 <span class="source-line-no">3359</span><span id="line-3359">  }</span>
 <span class="source-line-no">3360</span><span id="line-3360"></span>
-<span class="source-line-no">3361</span><span id="line-3361">  private boolean isHealthCheckerConfigured() {</span>
-<span class="source-line-no">3362</span><span id="line-3362">    String healthScriptLocation = this.conf.get(HConstants.HEALTH_SCRIPT_LOC);</span>
-<span class="source-line-no">3363</span><span id="line-3363">    return org.apache.commons.lang3.StringUtils.isNotBlank(healthScriptLocation);</span>
-<span class="source-line-no">3364</span><span id="line-3364">  }</span>
-<span class="source-line-no">3365</span><span id="line-3365"></span>
-<span class="source-line-no">3366</span><span id="line-3366">  /** Returns the underlying {@link CompactSplit} for the servers */</span>
-<span class="source-line-no">3367</span><span id="line-3367">  public CompactSplit getCompactSplitThread() {</span>
-<span class="source-line-no">3368</span><span id="line-3368">    return this.compactSplitThread;</span>
-<span class="source-line-no">3369</span><span id="line-3369">  }</span>
-<span class="source-line-no">3370</span><span id="line-3370"></span>
-<span class="source-line-no">3371</span><span id="line-3371">  CoprocessorServiceResponse execRegionServerService(</span>
-<span class="source-line-no">3372</span><span id="line-3372">    @SuppressWarnings("UnusedParameters") final RpcController controller,</span>
-<span class="source-line-no">3373</span><span id="line-3373">    final CoprocessorServiceRequest serviceRequest) throws ServiceException {</span>
-<span class="source-line-no">3374</span><span id="line-3374">    try {</span>
-<span class="source-line-no">3375</span><span id="line-3375">      ServerRpcController serviceController = new ServerRpcController();</span>
-<span class="source-line-no">3376</span><span id="line-3376">      CoprocessorServiceCall call = serviceRequest.getCall();</span>
-<span class="source-line-no">3377</span><span id="line-3377">      String serviceName = call.getServiceName();</span>
-<span class="source-line-no">3378</span><span id="line-3378">      Service service = coprocessorServiceHandlers.get(serviceName);</span>
-<span class="source-line-no">3379</span><span id="line-3379">      if (service == null) {</span>
-<span class="source-line-no">3380</span><span id="line-3380">        throw new UnknownProtocolException(null,</span>
-<span class="source-line-no">3381</span><span id="line-3381">          "No registered coprocessor executorService found for " + serviceName);</span>
-<span class="source-line-no">3382</span><span id="line-3382">      }</span>
-<span class="source-line-no">3383</span><span id="line-3383">      ServiceDescriptor serviceDesc = service.getDescriptorForType();</span>
-<span class="source-line-no">3384</span><span id="line-3384"></span>
-<span class="source-line-no">3385</span><span id="line-3385">      String methodName = call.getMethodName();</span>
-<span class="source-line-no">3386</span><span id="line-3386">      MethodDescriptor methodDesc = serviceDesc.findMethodByName(methodName);</span>
-<span class="source-line-no">3387</span><span id="line-3387">      if (methodDesc == null) {</span>
-<span class="source-line-no">3388</span><span id="line-3388">        throw new UnknownProtocolException(service.getClass(),</span>
-<span class="source-line-no">3389</span><span id="line-3389">          "Unknown method " + methodName + " called on executorService " + serviceName);</span>
-<span class="source-line-no">3390</span><span id="line-3390">      }</span>
-<span class="source-line-no">3391</span><span id="line-3391"></span>
-<span class="source-line-no">3392</span><span id="line-3392">      Message request = CoprocessorRpcUtils.getRequest(service, methodDesc, call.getRequest());</span>
-<span class="source-line-no">3393</span><span id="line-3393">      final Message.Builder responseBuilder =</span>
-<span class="source-line-no">3394</span><span id="line-3394">        service.getResponsePrototype(methodDesc).newBuilderForType();</span>
-<span class="source-line-no">3395</span><span id="line-3395">      service.callMethod(methodDesc, serviceController, request, message -&gt; {</span>
-<span class="source-line-no">3396</span><span id="line-3396">        if (message != null) {</span>
-<span class="source-line-no">3397</span><span id="line-3397">          responseBuilder.mergeFrom(message);</span>
-<span class="source-line-no">3398</span><span id="line-3398">        }</span>
-<span class="source-line-no">3399</span><span id="line-3399">      });</span>
-<span class="source-line-no">3400</span><span id="line-3400">      IOException exception = CoprocessorRpcUtils.getControllerException(serviceController);</span>
-<span class="source-line-no">3401</span><span id="line-3401">      if (exception != null) {</span>
-<span class="source-line-no">3402</span><span id="line-3402">        throw exception;</span>
-<span class="source-line-no">3403</span><span id="line-3403">      }</span>
-<span class="source-line-no">3404</span><span id="line-3404">      return CoprocessorRpcUtils.getResponse(responseBuilder.build(), HConstants.EMPTY_BYTE_ARRAY);</span>
-<span class="source-line-no">3405</span><span id="line-3405">    } catch (IOException ie) {</span>
-<span class="source-line-no">3406</span><span id="line-3406">      throw new ServiceException(ie);</span>
-<span class="source-line-no">3407</span><span id="line-3407">    }</span>
-<span class="source-line-no">3408</span><span id="line-3408">  }</span>
-<span class="source-line-no">3409</span><span id="line-3409"></span>
-<span class="source-line-no">3410</span><span id="line-3410">  /**</span>
-<span class="source-line-no">3411</span><span id="line-3411">   * May be null if this is a master which not carry table.</span>
-<span class="source-line-no">3412</span><span id="line-3412">   * @return The block cache instance used by the regionserver.</span>
-<span class="source-line-no">3413</span><span id="line-3413">   */</span>
-<span class="source-line-no">3414</span><span id="line-3414">  @Override</span>
-<span class="source-line-no">3415</span><span id="line-3415">  public Optional&lt;BlockCache&gt; getBlockCache() {</span>
-<span class="source-line-no">3416</span><span id="line-3416">    return Optional.ofNullable(this.blockCache);</span>
-<span class="source-line-no">3417</span><span id="line-3417">  }</span>
-<span class="source-line-no">3418</span><span id="line-3418"></span>
-<span class="source-line-no">3419</span><span id="line-3419">  /**</span>
-<span class="source-line-no">3420</span><span id="line-3420">   * May be null if this is a master which not carry table.</span>
-<span class="source-line-no">3421</span><span id="line-3421">   * @return The cache for mob files used by the regionserver.</span>
-<span class="source-line-no">3422</span><span id="line-3422">   */</span>
-<span class="source-line-no">3423</span><span id="line-3423">  @Override</span>
-<span class="source-line-no">3424</span><span id="line-3424">  public Optional&lt;MobFileCache&gt; getMobFileCache() {</span>
-<span class="source-line-no">3425</span><span id="line-3425">    return Optional.ofNullable(this.mobFileCache);</span>
-<span class="source-line-no">3426</span><span id="line-3426">  }</span>
-<span class="source-line-no">3427</span><span id="line-3427"></span>
-<span class="source-line-no">3428</span><span id="line-3428">  CacheEvictionStats clearRegionBlockCache(Region region) {</span>
-<span class="source-line-no">3429</span><span id="line-3429">    long evictedBlocks = 0;</span>
-<span class="source-line-no">3430</span><span id="line-3430"></span>
-<span class="source-line-no">3431</span><span id="line-3431">    for (Store store : region.getStores()) {</span>
-<span class="source-line-no">3432</span><span id="line-3432">      for (StoreFile hFile : store.getStorefiles()) {</span>
-<span class="source-line-no">3433</span><span id="line-3433">        evictedBlocks += blockCache.evictBlocksByHfileName(hFile.getPath().getName());</span>
-<span class="source-line-no">3434</span><span id="line-3434">      }</span>
-<span class="source-line-no">3435</span><span id="line-3435">    }</span>
-<span class="source-line-no">3436</span><span id="line-3436"></span>
-<span class="source-line-no">3437</span><span id="line-3437">    return CacheEvictionStats.builder().withEvictedBlocks(evictedBlocks).build();</span>
-<span class="source-line-no">3438</span><span id="line-3438">  }</span>
-<span class="source-line-no">3439</span><span id="line-3439"></span>
-<span class="source-line-no">3440</span><span id="line-3440">  @Override</span>
-<span class="source-line-no">3441</span><span id="line-3441">  public double getCompactionPressure() {</span>
-<span class="source-line-no">3442</span><span id="line-3442">    double max = 0;</span>
-<span class="source-line-no">3443</span><span id="line-3443">    for (Region region : onlineRegions.values()) {</span>
-<span class="source-line-no">3444</span><span id="line-3444">      for (Store store : region.getStores()) {</span>
-<span class="source-line-no">3445</span><span id="line-3445">        double normCount = store.getCompactionPressure();</span>
-<span class="source-line-no">3446</span><span id="line-3446">        if (normCount &gt; max) {</span>
-<span class="source-line-no">3447</span><span id="line-3447">          max = normCount;</span>
-<span class="source-line-no">3448</span><span id="line-3448">        }</span>
-<span class="source-line-no">3449</span><span id="line-3449">      }</span>
-<span class="source-line-no">3450</span><span id="line-3450">    }</span>
-<span class="source-line-no">3451</span><span id="line-3451">    return max;</span>
-<span class="source-line-no">3452</span><span id="line-3452">  }</span>
-<span class="source-line-no">3453</span><span id="line-3453"></span>
-<span class="source-line-no">3454</span><span id="line-3454">  @Override</span>
-<span class="source-line-no">3455</span><span id="line-3455">  public HeapMemoryManager getHeapMemoryManager() {</span>
-<span class="source-line-no">3456</span><span id="line-3456">    return hMemManager;</span>
-<span class="source-line-no">3457</span><span id="line-3457">  }</span>
-<span class="source-line-no">3458</span><span id="line-3458"></span>
-<span class="source-line-no">3459</span><span id="line-3459">  public MemStoreFlusher getMemStoreFlusher() {</span>
-<span class="source-line-no">3460</span><span id="line-3460">    return cacheFlusher;</span>
+<span class="source-line-no">3361</span><span id="line-3361">  private String getMyEphemeralNodePath() {</span>
+<span class="source-line-no">3362</span><span id="line-3362">    return zooKeeper.getZNodePaths().getRsPath(serverName);</span>
+<span class="source-line-no">3363</span><span id="line-3363">  }</span>
+<span class="source-line-no">3364</span><span id="line-3364"></span>
+<span class="source-line-no">3365</span><span id="line-3365">  private boolean isHealthCheckerConfigured() {</span>
+<span class="source-line-no">3366</span><span id="line-3366">    String healthScriptLocation = this.conf.get(HConstants.HEALTH_SCRIPT_LOC);</span>
+<span class="source-line-no">3367</span><span id="line-3367">    return org.apache.commons.lang3.StringUtils.isNotBlank(healthScriptLocation);</span>
+<span class="source-line-no">3368</span><span id="line-3368">  }</span>
+<span class="source-line-no">3369</span><span id="line-3369"></span>
+<span class="source-line-no">3370</span><span id="line-3370">  /** Returns the underlying {@link CompactSplit} for the servers */</span>
+<span class="source-line-no">3371</span><span id="line-3371">  public CompactSplit getCompactSplitThread() {</span>
+<span class="source-line-no">3372</span><span id="line-3372">    return this.compactSplitThread;</span>
+<span class="source-line-no">3373</span><span id="line-3373">  }</span>
+<span class="source-line-no">3374</span><span id="line-3374"></span>
+<span class="source-line-no">3375</span><span id="line-3375">  CoprocessorServiceResponse execRegionServerService(</span>
+<span class="source-line-no">3376</span><span id="line-3376">    @SuppressWarnings("UnusedParameters") final RpcController controller,</span>
+<span class="source-line-no">3377</span><span id="line-3377">    final CoprocessorServiceRequest serviceRequest) throws ServiceException {</span>
+<span class="source-line-no">3378</span><span id="line-3378">    try {</span>
+<span class="source-line-no">3379</span><span id="line-3379">      ServerRpcController serviceController = new ServerRpcController();</span>
+<span class="source-line-no">3380</span><span id="line-3380">      CoprocessorServiceCall call = serviceRequest.getCall();</span>
+<span class="source-line-no">3381</span><span id="line-3381">      String serviceName = call.getServiceName();</span>
+<span class="source-line-no">3382</span><span id="line-3382">      Service service = coprocessorServiceHandlers.get(serviceName);</span>
+<span class="source-line-no">3383</span><span id="line-3383">      if (service == null) {</span>
+<span class="source-line-no">3384</span><span id="line-3384">        throw new UnknownProtocolException(null,</span>
+<span class="source-line-no">3385</span><span id="line-3385">          "No registered coprocessor executorService found for " + serviceName);</span>
+<span class="source-line-no">3386</span><span id="line-3386">      }</span>
+<span class="source-line-no">3387</span><span id="line-3387">      ServiceDescriptor serviceDesc = service.getDescriptorForType();</span>
+<span class="source-line-no">3388</span><span id="line-3388"></span>
+<span class="source-line-no">3389</span><span id="line-3389">      String methodName = call.getMethodName();</span>
+<span class="source-line-no">3390</span><span id="line-3390">      MethodDescriptor methodDesc = serviceDesc.findMethodByName(methodName);</span>
+<span class="source-line-no">3391</span><span id="line-3391">      if (methodDesc == null) {</span>
+<span class="source-line-no">3392</span><span id="line-3392">        throw new UnknownProtocolException(service.getClass(),</span>
+<span class="source-line-no">3393</span><span id="line-3393">          "Unknown method " + methodName + " called on executorService " + serviceName);</span>
+<span class="source-line-no">3394</span><span id="line-3394">      }</span>
+<span class="source-line-no">3395</span><span id="line-3395"></span>
+<span class="source-line-no">3396</span><span id="line-3396">      Message request = CoprocessorRpcUtils.getRequest(service, methodDesc, call.getRequest());</span>
+<span class="source-line-no">3397</span><span id="line-3397">      final Message.Builder responseBuilder =</span>
+<span class="source-line-no">3398</span><span id="line-3398">        service.getResponsePrototype(methodDesc).newBuilderForType();</span>
+<span class="source-line-no">3399</span><span id="line-3399">      service.callMethod(methodDesc, serviceController, request, message -&gt; {</span>
+<span class="source-line-no">3400</span><span id="line-3400">        if (message != null) {</span>
+<span class="source-line-no">3401</span><span id="line-3401">          responseBuilder.mergeFrom(message);</span>
+<span class="source-line-no">3402</span><span id="line-3402">        }</span>
+<span class="source-line-no">3403</span><span id="line-3403">      });</span>
+<span class="source-line-no">3404</span><span id="line-3404">      IOException exception = CoprocessorRpcUtils.getControllerException(serviceController);</span>
+<span class="source-line-no">3405</span><span id="line-3405">      if (exception != null) {</span>
+<span class="source-line-no">3406</span><span id="line-3406">        throw exception;</span>
+<span class="source-line-no">3407</span><span id="line-3407">      }</span>
+<span class="source-line-no">3408</span><span id="line-3408">      return CoprocessorRpcUtils.getResponse(responseBuilder.build(), HConstants.EMPTY_BYTE_ARRAY);</span>
+<span class="source-line-no">3409</span><span id="line-3409">    } catch (IOException ie) {</span>
+<span class="source-line-no">3410</span><span id="line-3410">      throw new ServiceException(ie);</span>
+<span class="source-line-no">3411</span><span id="line-3411">    }</span>
+<span class="source-line-no">3412</span><span id="line-3412">  }</span>
+<span class="source-line-no">3413</span><span id="line-3413"></span>
+<span class="source-line-no">3414</span><span id="line-3414">  /**</span>
+<span class="source-line-no">3415</span><span id="line-3415">   * May be null if this is a master which not carry table.</span>
+<span class="source-line-no">3416</span><span id="line-3416">   * @return The block cache instance used by the regionserver.</span>
+<span class="source-line-no">3417</span><span id="line-3417">   */</span>
+<span class="source-line-no">3418</span><span id="line-3418">  @Override</span>
+<span class="source-line-no">3419</span><span id="line-3419">  public Optional&lt;BlockCache&gt; getBlockCache() {</span>
+<span class="source-line-no">3420</span><span id="line-3420">    return Optional.ofNullable(this.blockCache);</span>
+<span class="source-line-no">3421</span><span id="line-3421">  }</span>
+<span class="source-line-no">3422</span><span id="line-3422"></span>
+<span class="source-line-no">3423</span><span id="line-3423">  /**</span>
+<span class="source-line-no">3424</span><span id="line-3424">   * May be null if this is a master which not carry table.</span>
+<span class="source-line-no">3425</span><span id="line-3425">   * @return The cache for mob files used by the regionserver.</span>
+<span class="source-line-no">3426</span><span id="line-3426">   */</span>
+<span class="source-line-no">3427</span><span id="line-3427">  @Override</span>
+<span class="source-line-no">3428</span><span id="line-3428">  public Optional&lt;MobFileCache&gt; getMobFileCache() {</span>
+<span class="source-line-no">3429</span><span id="line-3429">    return Optional.ofNullable(this.mobFileCache);</span>
+<span class="source-line-no">3430</span><span id="line-3430">  }</span>
+<span class="source-line-no">3431</span><span id="line-3431"></span>
+<span class="source-line-no">3432</span><span id="line-3432">  CacheEvictionStats clearRegionBlockCache(Region region) {</span>
+<span class="source-line-no">3433</span><span id="line-3433">    long evictedBlocks = 0;</span>
+<span class="source-line-no">3434</span><span id="line-3434"></span>
+<span class="source-line-no">3435</span><span id="line-3435">    for (Store store : region.getStores()) {</span>
+<span class="source-line-no">3436</span><span id="line-3436">      for (StoreFile hFile : store.getStorefiles()) {</span>
+<span class="source-line-no">3437</span><span id="line-3437">        evictedBlocks += blockCache.evictBlocksByHfileName(hFile.getPath().getName());</span>
+<span class="source-line-no">3438</span><span id="line-3438">      }</span>
+<span class="source-line-no">3439</span><span id="line-3439">    }</span>
+<span class="source-line-no">3440</span><span id="line-3440"></span>
+<span class="source-line-no">3441</span><span id="line-3441">    return CacheEvictionStats.builder().withEvictedBlocks(evictedBlocks).build();</span>
+<span class="source-line-no">3442</span><span id="line-3442">  }</span>
+<span class="source-line-no">3443</span><span id="line-3443"></span>
+<span class="source-line-no">3444</span><span id="line-3444">  @Override</span>
+<span class="source-line-no">3445</span><span id="line-3445">  public double getCompactionPressure() {</span>
+<span class="source-line-no">3446</span><span id="line-3446">    double max = 0;</span>
+<span class="source-line-no">3447</span><span id="line-3447">    for (Region region : onlineRegions.values()) {</span>
+<span class="source-line-no">3448</span><span id="line-3448">      for (Store store : region.getStores()) {</span>
+<span class="source-line-no">3449</span><span id="line-3449">        double normCount = store.getCompactionPressure();</span>
+<span class="source-line-no">3450</span><span id="line-3450">        if (normCount &gt; max) {</span>
+<span class="source-line-no">3451</span><span id="line-3451">          max = normCount;</span>
+<span class="source-line-no">3452</span><span id="line-3452">        }</span>
+<span class="source-line-no">3453</span><span id="line-3453">      }</span>
+<span class="source-line-no">3454</span><span id="line-3454">    }</span>
+<span class="source-line-no">3455</span><span id="line-3455">    return max;</span>
+<span class="source-line-no">3456</span><span id="line-3456">  }</span>
+<span class="source-line-no">3457</span><span id="line-3457"></span>
+<span class="source-line-no">3458</span><span id="line-3458">  @Override</span>
+<span class="source-line-no">3459</span><span id="line-3459">  public HeapMemoryManager getHeapMemoryManager() {</span>
+<span class="source-line-no">3460</span><span id="line-3460">    return hMemManager;</span>
 <span class="source-line-no">3461</span><span id="line-3461">  }</span>
 <span class="source-line-no">3462</span><span id="line-3462"></span>
-<span class="source-line-no">3463</span><span id="line-3463">  /**</span>
-<span class="source-line-no">3464</span><span id="line-3464">   * For testing</span>
-<span class="source-line-no">3465</span><span id="line-3465">   * @return whether all wal roll request finished for this regionserver</span>
-<span class="source-line-no">3466</span><span id="line-3466">   */</span>
-<span class="source-line-no">3467</span><span id="line-3467">  @InterfaceAudience.Private</span>
-<span class="source-line-no">3468</span><span id="line-3468">  public boolean walRollRequestFinished() {</span>
-<span class="source-line-no">3469</span><span id="line-3469">    return this.walRoller.walRollFinished();</span>
-<span class="source-line-no">3470</span><span id="line-3470">  }</span>
-<span class="source-line-no">3471</span><span id="line-3471"></span>
-<span class="source-line-no">3472</span><span id="line-3472">  @Override</span>
-<span class="source-line-no">3473</span><span id="line-3473">  public ThroughputController getFlushThroughputController() {</span>
-<span class="source-line-no">3474</span><span id="line-3474">    return flushThroughputController;</span>
-<span class="source-line-no">3475</span><span id="line-3475">  }</span>
-<span class="source-line-no">3476</span><span id="line-3476"></span>
-<span class="source-line-no">3477</span><span id="line-3477">  @Override</span>
-<span class="source-line-no">3478</span><span id="line-3478">  public double getFlushPressure() {</span>
-<span class="source-line-no">3479</span><span id="line-3479">    if (getRegionServerAccounting() == null || cacheFlusher == null) {</span>
-<span class="source-line-no">3480</span><span id="line-3480">      // return 0 during RS initialization</span>
-<span class="source-line-no">3481</span><span id="line-3481">      return 0.0;</span>
-<span class="source-line-no">3482</span><span id="line-3482">    }</span>
-<span class="source-line-no">3483</span><span id="line-3483">    return getRegionServerAccounting().getFlushPressure();</span>
-<span class="source-line-no">3484</span><span id="line-3484">  }</span>
-<span class="source-line-no">3485</span><span id="line-3485"></span>
-<span class="source-line-no">3486</span><span id="line-3486">  /**</span>
-<span class="source-line-no">3487</span><span id="line-3487">   * Dynamically updates HRegionServer's configuration. Since HRegionServer inherits from</span>
-<span class="source-line-no">3488</span><span id="line-3488">   * {@link HBaseServerBase}, the {@code updatedConf} parameter references the same</span>
-<span class="source-line-no">3489</span><span id="line-3489">   * {@link Configuration} object as HRegionServer's {@code this.conf} instance variable in a real</span>
-<span class="source-line-no">3490</span><span id="line-3490">   * HBase deployment. This isn't necessarily the case in unit tests.</span>
-<span class="source-line-no">3491</span><span id="line-3491">   * @param updatedConf the dynamically updated configuration</span>
-<span class="source-line-no">3492</span><span id="line-3492">   */</span>
-<span class="source-line-no">3493</span><span id="line-3493">  @Override</span>
-<span class="source-line-no">3494</span><span id="line-3494">  public void onConfigurationChange(Configuration updatedConf) {</span>
-<span class="source-line-no">3495</span><span id="line-3495">    ThroughputController old = this.flushThroughputController;</span>
-<span class="source-line-no">3496</span><span id="line-3496">    if (old != null) {</span>
-<span class="source-line-no">3497</span><span id="line-3497">      old.stop("configuration change");</span>
-<span class="source-line-no">3498</span><span id="line-3498">    }</span>
-<span class="source-line-no">3499</span><span id="line-3499">    this.flushThroughputController = FlushThroughputControllerFactory.create(this, updatedConf);</span>
-<span class="source-line-no">3500</span><span id="line-3500">    try {</span>
-<span class="source-line-no">3501</span><span id="line-3501">      Superusers.initialize(updatedConf);</span>
-<span class="source-line-no">3502</span><span id="line-3502">    } catch (IOException e) {</span>
-<span class="source-line-no">3503</span><span id="line-3503">      LOG.warn("Failed to initialize SuperUsers on reloading of the configuration");</span>
-<span class="source-line-no">3504</span><span id="line-3504">    }</span>
-<span class="source-line-no">3505</span><span id="line-3505"></span>
-<span class="source-line-no">3506</span><span id="line-3506">    boolean originalIsReadOnlyEnabled = CoprocessorConfigurationUtil</span>
-<span class="source-line-no">3507</span><span id="line-3507">      .areReadOnlyCoprocessorsLoaded(this.conf, CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY);</span>
-<span class="source-line-no">3508</span><span id="line-3508"></span>
-<span class="source-line-no">3509</span><span id="line-3509">    // updatedConf and this.conf reference the same Configuration object in an actual HBase</span>
-<span class="source-line-no">3510</span><span id="line-3510">    // deployment. However, in unit test cases they reference different Configuration objects, so</span>
-<span class="source-line-no">3511</span><span id="line-3511">    // this.conf needs to be updated.</span>
-<span class="source-line-no">3512</span><span id="line-3512">    CoprocessorConfigurationUtil.maybeUpdateCoprocessors(updatedConf, this.conf,</span>
-<span class="source-line-no">3513</span><span id="line-3513">      originalIsReadOnlyEnabled, this.rsHost, CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,</span>
-<span class="source-line-no">3514</span><span id="line-3514">      false, this.toString(), conf -&gt; this.rsHost = new RegionServerCoprocessorHost(this, conf));</span>
-<span class="source-line-no">3515</span><span id="line-3515">  }</span>
-<span class="source-line-no">3516</span><span id="line-3516"></span>
-<span class="source-line-no">3517</span><span id="line-3517">  @Override</span>
-<span class="source-line-no">3518</span><span id="line-3518">  public MetricsRegionServer getMetrics() {</span>
-<span class="source-line-no">3519</span><span id="line-3519">    return metricsRegionServer;</span>
-<span class="source-line-no">3520</span><span id="line-3520">  }</span>
-<span class="source-line-no">3521</span><span id="line-3521"></span>
-<span class="source-line-no">3522</span><span id="line-3522">  @Override</span>
-<span class="source-line-no">3523</span><span id="line-3523">  public SecureBulkLoadManager getSecureBulkLoadManager() {</span>
-<span class="source-line-no">3524</span><span id="line-3524">    return this.secureBulkLoadManager;</span>
-<span class="source-line-no">3525</span><span id="line-3525">  }</span>
-<span class="source-line-no">3526</span><span id="line-3526"></span>
-<span class="source-line-no">3527</span><span id="line-3527">  @Override</span>
-<span class="source-line-no">3528</span><span id="line-3528">  public EntityLock regionLock(final List&lt;RegionInfo&gt; regionInfo, final String description,</span>
-<span class="source-line-no">3529</span><span id="line-3529">    final Abortable abort) {</span>
-<span class="source-line-no">3530</span><span id="line-3530">    final LockServiceClient client =</span>
-<span class="source-line-no">3531</span><span id="line-3531">      new LockServiceClient(conf, lockStub, asyncClusterConnection.getNonceGenerator());</span>
-<span class="source-line-no">3532</span><span id="line-3532">    return client.regionLock(regionInfo, description, abort);</span>
-<span class="source-line-no">3533</span><span id="line-3533">  }</span>
-<span class="source-line-no">3534</span><span id="line-3534"></span>
-<span class="source-line-no">3535</span><span id="line-3535">  @Override</span>
-<span class="source-line-no">3536</span><span id="line-3536">  public void unassign(byte[] regionName) throws IOException {</span>
-<span class="source-line-no">3537</span><span id="line-3537">    FutureUtils.get(asyncClusterConnection.getAdmin().unassign(regionName, false));</span>
-<span class="source-line-no">3538</span><span id="line-3538">  }</span>
-<span class="source-line-no">3539</span><span id="line-3539"></span>
-<span class="source-line-no">3540</span><span id="line-3540">  @Override</span>
-<span class="source-line-no">3541</span><span id="line-3541">  public RegionServerSpaceQuotaManager getRegionServerSpaceQuotaManager() {</span>
-<span class="source-line-no">3542</span><span id="line-3542">    return this.rsSpaceQuotaManager;</span>
-<span class="source-line-no">3543</span><span id="line-3543">  }</span>
-<span class="source-line-no">3544</span><span id="line-3544"></span>
-<span class="source-line-no">3545</span><span id="line-3545">  @Override</span>
-<span class="source-line-no">3546</span><span id="line-3546">  public boolean reportFileArchivalForQuotas(TableName tableName,</span>
-<span class="source-line-no">3547</span><span id="line-3547">    Collection&lt;Entry&lt;String, Long&gt;&gt; archivedFiles) {</span>
-<span class="source-line-no">3548</span><span id="line-3548">    if (TEST_SKIP_REPORTING_TRANSITION) {</span>
-<span class="source-line-no">3549</span><span id="line-3549">      return false;</span>
-<span class="source-line-no">3550</span><span id="line-3550">    }</span>
-<span class="source-line-no">3551</span><span id="line-3551">    RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">3552</span><span id="line-3552">    if (rss == null || rsSpaceQuotaManager == null) {</span>
-<span class="source-line-no">3553</span><span id="line-3553">      // the current server could be stopping.</span>
-<span class="source-line-no">3554</span><span id="line-3554">      LOG.trace("Skipping file archival reporting to HMaster as stub is null");</span>
-<span class="source-line-no">3555</span><span id="line-3555">      return false;</span>
-<span class="source-line-no">3556</span><span id="line-3556">    }</span>
-<span class="source-line-no">3557</span><span id="line-3557">    try {</span>
-<span class="source-line-no">3558</span><span id="line-3558">      RegionServerStatusProtos.FileArchiveNotificationRequest request =</span>
-<span class="source-line-no">3559</span><span id="line-3559">        rsSpaceQuotaManager.buildFileArchiveRequest(tableName, archivedFiles);</span>
-<span class="source-line-no">3560</span><span id="line-3560">      rss.reportFileArchival(null, request);</span>
-<span class="source-line-no">3561</span><span id="line-3561">    } catch (ServiceException se) {</span>
-<span class="source-line-no">3562</span><span id="line-3562">      IOException ioe = ProtobufUtil.getRemoteException(se);</span>
-<span class="source-line-no">3563</span><span id="line-3563">      if (ioe instanceof PleaseHoldException) {</span>
-<span class="source-line-no">3564</span><span id="line-3564">        if (LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">3565</span><span id="line-3565">          LOG.trace("Failed to report file archival(s) to Master because it is initializing."</span>
-<span class="source-line-no">3566</span><span id="line-3566">            + " This will be retried.", ioe);</span>
-<span class="source-line-no">3567</span><span id="line-3567">        }</span>
-<span class="source-line-no">3568</span><span id="line-3568">        // The Master is coming up. Will retry the report later. Avoid re-creating the stub.</span>
-<span class="source-line-no">3569</span><span id="line-3569">        return false;</span>
-<span class="source-line-no">3570</span><span id="line-3570">      }</span>
-<span class="source-line-no">3571</span><span id="line-3571">      if (rssStub == rss) {</span>
-<span class="source-line-no">3572</span><span id="line-3572">        rssStub = null;</span>
-<span class="source-line-no">3573</span><span id="line-3573">      }</span>
-<span class="source-line-no">3574</span><span id="line-3574">      // re-create the stub if we failed to report the archival</span>
-<span class="source-line-no">3575</span><span id="line-3575">      createRegionServerStatusStub(true);</span>
-<span class="source-line-no">3576</span><span id="line-3576">      LOG.debug("Failed to report file archival(s) to Master. This will be retried.", ioe);</span>
-<span class="source-line-no">3577</span><span id="line-3577">      return false;</span>
-<span class="source-line-no">3578</span><span id="line-3578">    }</span>
-<span class="source-line-no">3579</span><span id="line-3579">    return true;</span>
-<span class="source-line-no">3580</span><span id="line-3580">  }</span>
-<span class="source-line-no">3581</span><span id="line-3581"></span>
-<span class="source-line-no">3582</span><span id="line-3582">  void executeProcedure(long procId, long initiatingMasterActiveTime,</span>
-<span class="source-line-no">3583</span><span id="line-3583">    RSProcedureCallable callable) {</span>
-<span class="source-line-no">3584</span><span id="line-3584">    executorService</span>
-<span class="source-line-no">3585</span><span id="line-3585">      .submit(new RSProcedureHandler(this, procId, initiatingMasterActiveTime, callable));</span>
-<span class="source-line-no">3586</span><span id="line-3586">  }</span>
-<span class="source-line-no">3587</span><span id="line-3587"></span>
-<span class="source-line-no">3588</span><span id="line-3588">  public void remoteProcedureComplete(long procId, long initiatingMasterActiveTime, Throwable error,</span>
-<span class="source-line-no">3589</span><span id="line-3589">    byte[] procResultData) {</span>
-<span class="source-line-no">3590</span><span id="line-3590">    procedureResultReporter.complete(procId, initiatingMasterActiveTime, error, procResultData);</span>
-<span class="source-line-no">3591</span><span id="line-3591">  }</span>
-<span class="source-line-no">3592</span><span id="line-3592"></span>
-<span class="source-line-no">3593</span><span id="line-3593">  void reportProcedureDone(ReportProcedureDoneRequest request) throws IOException {</span>
-<span class="source-line-no">3594</span><span id="line-3594">    RegionServerStatusService.BlockingInterface rss;</span>
-<span class="source-line-no">3595</span><span id="line-3595">    // TODO: juggling class state with an instance variable, outside of a synchronized block :'(</span>
-<span class="source-line-no">3596</span><span id="line-3596">    for (;;) {</span>
-<span class="source-line-no">3597</span><span id="line-3597">      rss = rssStub;</span>
-<span class="source-line-no">3598</span><span id="line-3598">      if (rss != null) {</span>
-<span class="source-line-no">3599</span><span id="line-3599">        break;</span>
-<span class="source-line-no">3600</span><span id="line-3600">      }</span>
-<span class="source-line-no">3601</span><span id="line-3601">      createRegionServerStatusStub();</span>
-<span class="source-line-no">3602</span><span id="line-3602">    }</span>
-<span class="source-line-no">3603</span><span id="line-3603">    try {</span>
-<span class="source-line-no">3604</span><span id="line-3604">      rss.reportProcedureDone(null, request);</span>
-<span class="source-line-no">3605</span><span id="line-3605">    } catch (ServiceException se) {</span>
-<span class="source-line-no">3606</span><span id="line-3606">      if (rssStub == rss) {</span>
-<span class="source-line-no">3607</span><span id="line-3607">        rssStub = null;</span>
-<span class="source-line-no">3608</span><span id="line-3608">      }</span>
-<span class="source-line-no">3609</span><span id="line-3609">      throw ProtobufUtil.getRemoteException(se);</span>
-<span class="source-line-no">3610</span><span id="line-3610">    }</span>
-<span class="source-line-no">3611</span><span id="line-3611">  }</span>
-<span class="source-line-no">3612</span><span id="line-3612"></span>
-<span class="source-line-no">3613</span><span id="line-3613">  /**</span>
-<span class="source-line-no">3614</span><span id="line-3614">   * Will ignore the open/close region procedures which already submitted or executed. When master</span>
-<span class="source-line-no">3615</span><span id="line-3615">   * had unfinished open/close region procedure and restarted, new active master may send duplicate</span>
-<span class="source-line-no">3616</span><span id="line-3616">   * open/close region request to regionserver. The open/close request is submitted to a thread pool</span>
-<span class="source-line-no">3617</span><span id="line-3617">   * and execute. So first need a cache for submitted open/close region procedures. After the</span>
-<span class="source-line-no">3618</span><span id="line-3618">   * open/close region request executed and report region transition succeed, cache it in executed</span>
-<span class="source-line-no">3619</span><span id="line-3619">   * region procedures cache. See {@link #finishRegionProcedure(long)}. After report region</span>
-<span class="source-line-no">3620</span><span id="line-3620">   * transition succeed, master will not send the open/close region request to regionserver again.</span>
-<span class="source-line-no">3621</span><span id="line-3621">   * And we thought that the ongoing duplicate open/close region request should not be delayed more</span>
-<span class="source-line-no">3622</span><span id="line-3622">   * than 600 seconds. So the executed region procedures cache will expire after 600 seconds. See</span>
-<span class="source-line-no">3623</span><span id="line-3623">   * HBASE-22404 for more details.</span>
-<span class="source-line-no">3624</span><span id="line-3624">   * @param procId the id of the open/close region procedure</span>
-<span class="source-line-no">3625</span><span id="line-3625">   * @return true if the procedure can be submitted.</span>
-<span class="source-line-no">3626</span><span id="line-3626">   */</span>
-<span class="source-line-no">3627</span><span id="line-3627">  boolean submitRegionProcedure(long procId) {</span>
-<span class="source-line-no">3628</span><span id="line-3628">    if (procId == -1) {</span>
-<span class="source-line-no">3629</span><span id="line-3629">      return true;</span>
-<span class="source-line-no">3630</span><span id="line-3630">    }</span>
-<span class="source-line-no">3631</span><span id="line-3631">    // Ignore the region procedures which already submitted.</span>
-<span class="source-line-no">3632</span><span id="line-3632">    Long previous = submittedRegionProcedures.putIfAbsent(procId, procId);</span>
-<span class="source-line-no">3633</span><span id="line-3633">    if (previous != null) {</span>
-<span class="source-line-no">3634</span><span id="line-3634">      LOG.warn("Received procedure pid={}, which already submitted, just ignore it", procId);</span>
-<span class="source-line-no">3635</span><span id="line-3635">      return false;</span>
-<span class="source-line-no">3636</span><span id="line-3636">    }</span>
-<span class="source-line-no">3637</span><span id="line-3637">    // Ignore the region procedures which already executed.</span>
-<span class="source-line-no">3638</span><span id="line-3638">    if (executedRegionProcedures.getIfPresent(procId) != null) {</span>
-<span class="source-line-no">3639</span><span id="line-3639">      LOG.warn("Received procedure pid={}, which already executed, just ignore it", procId);</span>
-<span class="source-line-no">3640</span><span id="line-3640">      return false;</span>
-<span class="source-line-no">3641</span><span id="line-3641">    }</span>
-<span class="source-line-no">3642</span><span id="line-3642">    return true;</span>
-<span class="source-line-no">3643</span><span id="line-3643">  }</span>
-<span class="source-line-no">3644</span><span id="line-3644"></span>
-<span class="source-line-no">3645</span><span id="line-3645">  /**</span>
-<span class="source-line-no">3646</span><span id="line-3646">   * See {@link #submitRegionProcedure(long)}.</span>
-<span class="source-line-no">3647</span><span id="line-3647">   * @param procId the id of the open/close region procedure</span>
-<span class="source-line-no">3648</span><span id="line-3648">   */</span>
-<span class="source-line-no">3649</span><span id="line-3649">  public void finishRegionProcedure(long procId) {</span>
-<span class="source-line-no">3650</span><span id="line-3650">    executedRegionProcedures.put(procId, procId);</span>
-<span class="source-line-no">3651</span><span id="line-3651">    submittedRegionProcedures.remove(procId);</span>
-<span class="source-line-no">3652</span><span id="line-3652">  }</span>
-<span class="source-line-no">3653</span><span id="line-3653"></span>
-<span class="source-line-no">3654</span><span id="line-3654">  /**</span>
-<span class="source-line-no">3655</span><span id="line-3655">   * Force to terminate region server when abort timeout.</span>
-<span class="source-line-no">3656</span><span id="line-3656">   */</span>
-<span class="source-line-no">3657</span><span id="line-3657">  private static class SystemExitWhenAbortTimeout extends TimerTask {</span>
-<span class="source-line-no">3658</span><span id="line-3658"></span>
-<span class="source-line-no">3659</span><span id="line-3659">    public SystemExitWhenAbortTimeout() {</span>
-<span class="source-line-no">3660</span><span id="line-3660">    }</span>
-<span class="source-line-no">3661</span><span id="line-3661"></span>
-<span class="source-line-no">3662</span><span id="line-3662">    @Override</span>
-<span class="source-line-no">3663</span><span id="line-3663">    public void run() {</span>
-<span class="source-line-no">3664</span><span id="line-3664">      LOG.warn("Aborting region server timed out, terminating forcibly"</span>
-<span class="source-line-no">3665</span><span id="line-3665">        + " and does not wait for any running shutdown hooks or finalizers to finish their work."</span>
-<span class="source-line-no">3666</span><span id="line-3666">        + " Thread dump to stdout.");</span>
-<span class="source-line-no">3667</span><span id="line-3667">      Threads.printThreadInfo(System.out, "Zombie HRegionServer");</span>
-<span class="source-line-no">3668</span><span id="line-3668">      Runtime.getRuntime().halt(1);</span>
-<span class="source-line-no">3669</span><span id="line-3669">    }</span>
-<span class="source-line-no">3670</span><span id="line-3670">  }</span>
-<span class="source-line-no">3671</span><span id="line-3671"></span>
-<span class="source-line-no">3672</span><span id="line-3672">  @InterfaceAudience.Private</span>
-<span class="source-line-no">3673</span><span id="line-3673">  public CompactedHFilesDischarger getCompactedHFilesDischarger() {</span>
-<span class="source-line-no">3674</span><span id="line-3674">    return compactedFileDischarger;</span>
-<span class="source-line-no">3675</span><span id="line-3675">  }</span>
-<span class="source-line-no">3676</span><span id="line-3676"></span>
-<span class="source-line-no">3677</span><span id="line-3677">  /**</span>
-<span class="source-line-no">3678</span><span id="line-3678">   * Return pause time configured in {@link HConstants#HBASE_RPC_SHORTOPERATION_RETRY_PAUSE_TIME}}</span>
-<span class="source-line-no">3679</span><span id="line-3679">   * @return pause time</span>
-<span class="source-line-no">3680</span><span id="line-3680">   */</span>
-<span class="source-line-no">3681</span><span id="line-3681">  @InterfaceAudience.Private</span>
-<span class="source-line-no">3682</span><span id="line-3682">  public long getRetryPauseTime() {</span>
-<span class="source-line-no">3683</span><span id="line-3683">    return this.retryPauseTime;</span>
-<span class="source-line-no">3684</span><span id="line-3684">  }</span>
-<span class="source-line-no">3685</span><span id="line-3685"></span>
-<span class="source-line-no">3686</span><span id="line-3686">  @Override</span>
-<span class="source-line-no">3687</span><span id="line-3687">  public Optional&lt;ServerName&gt; getActiveMaster() {</span>
-<span class="source-line-no">3688</span><span id="line-3688">    return Optional.ofNullable(masterAddressTracker.getMasterAddress());</span>
-<span class="source-line-no">3689</span><span id="line-3689">  }</span>
-<span class="source-line-no">3690</span><span id="line-3690"></span>
-<span class="source-line-no">3691</span><span id="line-3691">  @Override</span>
-<span class="source-line-no">3692</span><span id="line-3692">  public List&lt;ServerName&gt; getBackupMasters() {</span>
-<span class="source-line-no">3693</span><span id="line-3693">    return masterAddressTracker.getBackupMasters();</span>
-<span class="source-line-no">3694</span><span id="line-3694">  }</span>
-<span class="source-line-no">3695</span><span id="line-3695"></span>
-<span class="source-line-no">3696</span><span id="line-3696">  @Override</span>
-<span class="source-line-no">3697</span><span id="line-3697">  public Iterator&lt;ServerName&gt; getBootstrapNodes() {</span>
-<span class="source-line-no">3698</span><span id="line-3698">    return bootstrapNodeManager.getBootstrapNodes().iterator();</span>
-<span class="source-line-no">3699</span><span id="line-3699">  }</span>
-<span class="source-line-no">3700</span><span id="line-3700"></span>
-<span class="source-line-no">3701</span><span id="line-3701">  @Override</span>
-<span class="source-line-no">3702</span><span id="line-3702">  public List&lt;HRegionLocation&gt; getMetaLocations() {</span>
-<span class="source-line-no">3703</span><span id="line-3703">    return metaRegionLocationCache.getMetaRegionLocations();</span>
-<span class="source-line-no">3704</span><span id="line-3704">  }</span>
-<span class="source-line-no">3705</span><span id="line-3705"></span>
-<span class="source-line-no">3706</span><span id="line-3706">  @Override</span>
-<span class="source-line-no">3707</span><span id="line-3707">  protected NamedQueueRecorder createNamedQueueRecord() {</span>
-<span class="source-line-no">3708</span><span id="line-3708">    return NamedQueueRecorder.getInstance(conf);</span>
-<span class="source-line-no">3709</span><span id="line-3709">  }</span>
-<span class="source-line-no">3710</span><span id="line-3710"></span>
-<span class="source-line-no">3711</span><span id="line-3711">  @Override</span>
-<span class="source-line-no">3712</span><span id="line-3712">  protected boolean clusterMode() {</span>
-<span class="source-line-no">3713</span><span id="line-3713">    // this method will be called in the constructor of super class, so we can not return masterless</span>
-<span class="source-line-no">3714</span><span id="line-3714">    // directly here, as it will always be false.</span>
-<span class="source-line-no">3715</span><span id="line-3715">    return !conf.getBoolean(MASTERLESS_CONFIG_NAME, false);</span>
-<span class="source-line-no">3716</span><span id="line-3716">  }</span>
-<span class="source-line-no">3717</span><span id="line-3717"></span>
-<span class="source-line-no">3718</span><span id="line-3718">  @InterfaceAudience.Private</span>
-<span class="source-line-no">3719</span><span id="line-3719">  public BrokenStoreFileCleaner getBrokenStoreFileCleaner() {</span>
-<span class="source-line-no">3720</span><span id="line-3720">    return brokenStoreFileCleaner;</span>
-<span class="source-line-no">3721</span><span id="line-3721">  }</span>
-<span class="source-line-no">3722</span><span id="line-3722"></span>
-<span class="source-line-no">3723</span><span id="line-3723">  @InterfaceAudience.Private</span>
-<span class="source-line-no">3724</span><span id="line-3724">  public RSMobFileCleanerChore getRSMobFileCleanerChore() {</span>
-<span class="source-line-no">3725</span><span id="line-3725">    return rsMobFileCleanerChore;</span>
-<span class="source-line-no">3726</span><span id="line-3726">  }</span>
-<span class="source-line-no">3727</span><span id="line-3727"></span>
-<span class="source-line-no">3728</span><span id="line-3728">  RSSnapshotVerifier getRsSnapshotVerifier() {</span>
-<span class="source-line-no">3729</span><span id="line-3729">    return rsSnapshotVerifier;</span>
+<span class="source-line-no">3463</span><span id="line-3463">  public MemStoreFlusher getMemStoreFlusher() {</span>
+<span class="source-line-no">3464</span><span id="line-3464">    return cacheFlusher;</span>
+<span class="source-line-no">3465</span><span id="line-3465">  }</span>
+<span class="source-line-no">3466</span><span id="line-3466"></span>
+<span class="source-line-no">3467</span><span id="line-3467">  /**</span>
+<span class="source-line-no">3468</span><span id="line-3468">   * For testing</span>
+<span class="source-line-no">3469</span><span id="line-3469">   * @return whether all wal roll request finished for this regionserver</span>
+<span class="source-line-no">3470</span><span id="line-3470">   */</span>
+<span class="source-line-no">3471</span><span id="line-3471">  @InterfaceAudience.Private</span>
+<span class="source-line-no">3472</span><span id="line-3472">  public boolean walRollRequestFinished() {</span>
+<span class="source-line-no">3473</span><span id="line-3473">    return this.walRoller.walRollFinished();</span>
+<span class="source-line-no">3474</span><span id="line-3474">  }</span>
+<span class="source-line-no">3475</span><span id="line-3475"></span>
+<span class="source-line-no">3476</span><span id="line-3476">  @Override</span>
+<span class="source-line-no">3477</span><span id="line-3477">  public ThroughputController getFlushThroughputController() {</span>
+<span class="source-line-no">3478</span><span id="line-3478">    return flushThroughputController;</span>
+<span class="source-line-no">3479</span><span id="line-3479">  }</span>
+<span class="source-line-no">3480</span><span id="line-3480"></span>
+<span class="source-line-no">3481</span><span id="line-3481">  @Override</span>
+<span class="source-line-no">3482</span><span id="line-3482">  public double getFlushPressure() {</span>
+<span class="source-line-no">3483</span><span id="line-3483">    if (getRegionServerAccounting() == null || cacheFlusher == null) {</span>
+<span class="source-line-no">3484</span><span id="line-3484">      // return 0 during RS initialization</span>
+<span class="source-line-no">3485</span><span id="line-3485">      return 0.0;</span>
+<span class="source-line-no">3486</span><span id="line-3486">    }</span>
+<span class="source-line-no">3487</span><span id="line-3487">    return getRegionServerAccounting().getFlushPressure();</span>
+<span class="source-line-no">3488</span><span id="line-3488">  }</span>
+<span class="source-line-no">3489</span><span id="line-3489"></span>
+<span class="source-line-no">3490</span><span id="line-3490">  /**</span>
+<span class="source-line-no">3491</span><span id="line-3491">   * Dynamically updates HRegionServer's configuration. Since HRegionServer inherits from</span>
+<span class="source-line-no">3492</span><span id="line-3492">   * {@link HBaseServerBase}, the {@code updatedConf} parameter references the same</span>
+<span class="source-line-no">3493</span><span id="line-3493">   * {@link Configuration} object as HRegionServer's {@code this.conf} instance variable in a real</span>
+<span class="source-line-no">3494</span><span id="line-3494">   * HBase deployment. This isn't necessarily the case in unit tests.</span>
+<span class="source-line-no">3495</span><span id="line-3495">   * @param updatedConf the dynamically updated configuration</span>
+<span class="source-line-no">3496</span><span id="line-3496">   */</span>
+<span class="source-line-no">3497</span><span id="line-3497">  @Override</span>
+<span class="source-line-no">3498</span><span id="line-3498">  public void onConfigurationChange(Configuration updatedConf) {</span>
+<span class="source-line-no">3499</span><span id="line-3499">    ThroughputController old = this.flushThroughputController;</span>
+<span class="source-line-no">3500</span><span id="line-3500">    if (old != null) {</span>
+<span class="source-line-no">3501</span><span id="line-3501">      old.stop("configuration change");</span>
+<span class="source-line-no">3502</span><span id="line-3502">    }</span>
+<span class="source-line-no">3503</span><span id="line-3503">    this.flushThroughputController = FlushThroughputControllerFactory.create(this, updatedConf);</span>
+<span class="source-line-no">3504</span><span id="line-3504">    try {</span>
+<span class="source-line-no">3505</span><span id="line-3505">      Superusers.initialize(updatedConf);</span>
+<span class="source-line-no">3506</span><span id="line-3506">    } catch (IOException e) {</span>
+<span class="source-line-no">3507</span><span id="line-3507">      LOG.warn("Failed to initialize SuperUsers on reloading of the configuration");</span>
+<span class="source-line-no">3508</span><span id="line-3508">    }</span>
+<span class="source-line-no">3509</span><span id="line-3509"></span>
+<span class="source-line-no">3510</span><span id="line-3510">    boolean originalIsReadOnlyEnabled = CoprocessorConfigurationUtil</span>
+<span class="source-line-no">3511</span><span id="line-3511">      .areReadOnlyCoprocessorsLoaded(this.conf, CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY);</span>
+<span class="source-line-no">3512</span><span id="line-3512"></span>
+<span class="source-line-no">3513</span><span id="line-3513">    // updatedConf and this.conf reference the same Configuration object in an actual HBase</span>
+<span class="source-line-no">3514</span><span id="line-3514">    // deployment. However, in unit test cases they reference different Configuration objects, so</span>
+<span class="source-line-no">3515</span><span id="line-3515">    // this.conf needs to be updated.</span>
+<span class="source-line-no">3516</span><span id="line-3516">    CoprocessorConfigurationUtil.maybeUpdateCoprocessors(updatedConf, this.conf,</span>
+<span class="source-line-no">3517</span><span id="line-3517">      originalIsReadOnlyEnabled, this.rsHost, CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,</span>
+<span class="source-line-no">3518</span><span id="line-3518">      false, this.toString(), conf -&gt; this.rsHost = new RegionServerCoprocessorHost(this, conf));</span>
+<span class="source-line-no">3519</span><span id="line-3519">  }</span>
+<span class="source-line-no">3520</span><span id="line-3520"></span>
+<span class="source-line-no">3521</span><span id="line-3521">  @Override</span>
+<span class="source-line-no">3522</span><span id="line-3522">  public MetricsRegionServer getMetrics() {</span>
+<span class="source-line-no">3523</span><span id="line-3523">    return metricsRegionServer;</span>
+<span class="source-line-no">3524</span><span id="line-3524">  }</span>
+<span class="source-line-no">3525</span><span id="line-3525"></span>
+<span class="source-line-no">3526</span><span id="line-3526">  @Override</span>
+<span class="source-line-no">3527</span><span id="line-3527">  public SecureBulkLoadManager getSecureBulkLoadManager() {</span>
+<span class="source-line-no">3528</span><span id="line-3528">    return this.secureBulkLoadManager;</span>
+<span class="source-line-no">3529</span><span id="line-3529">  }</span>
+<span class="source-line-no">3530</span><span id="line-3530"></span>
+<span class="source-line-no">3531</span><span id="line-3531">  @Override</span>
+<span class="source-line-no">3532</span><span id="line-3532">  public EntityLock regionLock(final List&lt;RegionInfo&gt; regionInfo, final String description,</span>
+<span class="source-line-no">3533</span><span id="line-3533">    final Abortable abort) {</span>
+<span class="source-line-no">3534</span><span id="line-3534">    final LockServiceClient client =</span>
+<span class="source-line-no">3535</span><span id="line-3535">      new LockServiceClient(conf, lockStub, asyncClusterConnection.getNonceGenerator());</span>
+<span class="source-line-no">3536</span><span id="line-3536">    return client.regionLock(regionInfo, description, abort);</span>
+<span class="source-line-no">3537</span><span id="line-3537">  }</span>
+<span class="source-line-no">3538</span><span id="line-3538"></span>
+<span class="source-line-no">3539</span><span id="line-3539">  @Override</span>
+<span class="source-line-no">3540</span><span id="line-3540">  public void unassign(byte[] regionName) throws IOException {</span>
+<span class="source-line-no">3541</span><span id="line-3541">    FutureUtils.get(asyncClusterConnection.getAdmin().unassign(regionName, false));</span>
+<span class="source-line-no">3542</span><span id="line-3542">  }</span>
+<span class="source-line-no">3543</span><span id="line-3543"></span>
+<span class="source-line-no">3544</span><span id="line-3544">  @Override</span>
+<span class="source-line-no">3545</span><span id="line-3545">  public RegionServerSpaceQuotaManager getRegionServerSpaceQuotaManager() {</span>
+<span class="source-line-no">3546</span><span id="line-3546">    return this.rsSpaceQuotaManager;</span>
+<span class="source-line-no">3547</span><span id="line-3547">  }</span>
+<span class="source-line-no">3548</span><span id="line-3548"></span>
+<span class="source-line-no">3549</span><span id="line-3549">  @Override</span>
+<span class="source-line-no">3550</span><span id="line-3550">  public boolean reportFileArchivalForQuotas(TableName tableName,</span>
+<span class="source-line-no">3551</span><span id="line-3551">    Collection&lt;Entry&lt;String, Long&gt;&gt; archivedFiles) {</span>
+<span class="source-line-no">3552</span><span id="line-3552">    if (TEST_SKIP_REPORTING_TRANSITION) {</span>
+<span class="source-line-no">3553</span><span id="line-3553">      return false;</span>
+<span class="source-line-no">3554</span><span id="line-3554">    }</span>
+<span class="source-line-no">3555</span><span id="line-3555">    RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">3556</span><span id="line-3556">    if (rss == null || rsSpaceQuotaManager == null) {</span>
+<span class="source-line-no">3557</span><span id="line-3557">      // the current server could be stopping.</span>
+<span class="source-line-no">3558</span><span id="line-3558">      LOG.trace("Skipping file archival reporting to HMaster as stub is null");</span>
+<span class="source-line-no">3559</span><span id="line-3559">      return false;</span>
+<span class="source-line-no">3560</span><span id="line-3560">    }</span>
+<span class="source-line-no">3561</span><span id="line-3561">    try {</span>
+<span class="source-line-no">3562</span><span id="line-3562">      RegionServerStatusProtos.FileArchiveNotificationRequest request =</span>
+<span class="source-line-no">3563</span><span id="line-3563">        rsSpaceQuotaManager.buildFileArchiveRequest(tableName, archivedFiles);</span>
+<span class="source-line-no">3564</span><span id="line-3564">      rss.reportFileArchival(null, request);</span>
+<span class="source-line-no">3565</span><span id="line-3565">    } catch (ServiceException se) {</span>
+<span class="source-line-no">3566</span><span id="line-3566">      IOException ioe = ProtobufUtil.getRemoteException(se);</span>
+<span class="source-line-no">3567</span><span id="line-3567">      if (ioe instanceof PleaseHoldException) {</span>
+<span class="source-line-no">3568</span><span id="line-3568">        if (LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">3569</span><span id="line-3569">          LOG.trace("Failed to report file archival(s) to Master because it is initializing."</span>
+<span class="source-line-no">3570</span><span id="line-3570">            + " This will be retried.", ioe);</span>
+<span class="source-line-no">3571</span><span id="line-3571">        }</span>
+<span class="source-line-no">3572</span><span id="line-3572">        // The Master is coming up. Will retry the report later. Avoid re-creating the stub.</span>
+<span class="source-line-no">3573</span><span id="line-3573">        return false;</span>
+<span class="source-line-no">3574</span><span id="line-3574">      }</span>
+<span class="source-line-no">3575</span><span id="line-3575">      if (rssStub == rss) {</span>
+<span class="source-line-no">3576</span><span id="line-3576">        rssStub = null;</span>
+<span class="source-line-no">3577</span><span id="line-3577">      }</span>
+<span class="source-line-no">3578</span><span id="line-3578">      // re-create the stub if we failed to report the archival</span>
+<span class="source-line-no">3579</span><span id="line-3579">      createRegionServerStatusStub(true);</span>
+<span class="source-line-no">3580</span><span id="line-3580">      LOG.debug("Failed to report file archival(s) to Master. This will be retried.", ioe);</span>
+<span class="source-line-no">3581</span><span id="line-3581">      return false;</span>
+<span class="source-line-no">3582</span><span id="line-3582">    }</span>
+<span class="source-line-no">3583</span><span id="line-3583">    return true;</span>
+<span class="source-line-no">3584</span><span id="line-3584">  }</span>
+<span class="source-line-no">3585</span><span id="line-3585"></span>
+<span class="source-line-no">3586</span><span id="line-3586">  void executeProcedure(long procId, long initiatingMasterActiveTime,</span>
+<span class="source-line-no">3587</span><span id="line-3587">    RSProcedureCallable callable) {</span>
+<span class="source-line-no">3588</span><span id="line-3588">    executorService</span>
+<span class="source-line-no">3589</span><span id="line-3589">      .submit(new RSProcedureHandler(this, procId, initiatingMasterActiveTime, callable));</span>
+<span class="source-line-no">3590</span><span id="line-3590">  }</span>
+<span class="source-line-no">3591</span><span id="line-3591"></span>
+<span class="source-line-no">3592</span><span id="line-3592">  public void remoteProcedureComplete(long procId, long initiatingMasterActiveTime, Throwable error,</span>
+<span class="source-line-no">3593</span><span id="line-3593">    byte[] procResultData) {</span>
+<span class="source-line-no">3594</span><span id="line-3594">    procedureResultReporter.complete(procId, initiatingMasterActiveTime, error, procResultData);</span>
+<span class="source-line-no">3595</span><span id="line-3595">  }</span>
+<span class="source-line-no">3596</span><span id="line-3596"></span>
+<span class="source-line-no">3597</span><span id="line-3597">  void reportProcedureDone(ReportProcedureDoneRequest request) throws IOException {</span>
+<span class="source-line-no">3598</span><span id="line-3598">    RegionServerStatusService.BlockingInterface rss;</span>
+<span class="source-line-no">3599</span><span id="line-3599">    // TODO: juggling class state with an instance variable, outside of a synchronized block :'(</span>
+<span class="source-line-no">3600</span><span id="line-3600">    for (;;) {</span>
+<span class="source-line-no">3601</span><span id="line-3601">      rss = rssStub;</span>
+<span class="source-line-no">3602</span><span id="line-3602">      if (rss != null) {</span>
+<span class="source-line-no">3603</span><span id="line-3603">        break;</span>
+<span class="source-line-no">3604</span><span id="line-3604">      }</span>
+<span class="source-line-no">3605</span><span id="line-3605">      createRegionServerStatusStub();</span>
+<span class="source-line-no">3606</span><span id="line-3606">    }</span>
+<span class="source-line-no">3607</span><span id="line-3607">    try {</span>
+<span class="source-line-no">3608</span><span id="line-3608">      rss.reportProcedureDone(null, request);</span>
+<span class="source-line-no">3609</span><span id="line-3609">    } catch (ServiceException se) {</span>
+<span class="source-line-no">3610</span><span id="line-3610">      if (rssStub == rss) {</span>
+<span class="source-line-no">3611</span><span id="line-3611">        rssStub = null;</span>
+<span class="source-line-no">3612</span><span id="line-3612">      }</span>
+<span class="source-line-no">3613</span><span id="line-3613">      throw ProtobufUtil.getRemoteException(se);</span>
+<span class="source-line-no">3614</span><span id="line-3614">    }</span>
+<span class="source-line-no">3615</span><span id="line-3615">  }</span>
+<span class="source-line-no">3616</span><span id="line-3616"></span>
+<span class="source-line-no">3617</span><span id="line-3617">  /**</span>
+<span class="source-line-no">3618</span><span id="line-3618">   * Will ignore the open/close region procedures which already submitted or executed. When master</span>
+<span class="source-line-no">3619</span><span id="line-3619">   * had unfinished open/close region procedure and restarted, new active master may send duplicate</span>
+<span class="source-line-no">3620</span><span id="line-3620">   * open/close region request to regionserver. The open/close request is submitted to a thread pool</span>
+<span class="source-line-no">3621</span><span id="line-3621">   * and execute. So first need a cache for submitted open/close region procedures. After the</span>
+<span class="source-line-no">3622</span><span id="line-3622">   * open/close region request executed and report region transition succeed, cache it in executed</span>
+<span class="source-line-no">3623</span><span id="line-3623">   * region procedures cache. See {@link #finishRegionProcedure(long)}. After report region</span>
+<span class="source-line-no">3624</span><span id="line-3624">   * transition succeed, master will not send the open/close region request to regionserver again.</span>
+<span class="source-line-no">3625</span><span id="line-3625">   * And we thought that the ongoing duplicate open/close region request should not be delayed more</span>
+<span class="source-line-no">3626</span><span id="line-3626">   * than 600 seconds. So the executed region procedures cache will expire after 600 seconds. See</span>
+<span class="source-line-no">3627</span><span id="line-3627">   * HBASE-22404 for more details.</span>
+<span class="source-line-no">3628</span><span id="line-3628">   * @param procId the id of the open/close region procedure</span>
+<span class="source-line-no">3629</span><span id="line-3629">   * @return true if the procedure can be submitted.</span>
+<span class="source-line-no">3630</span><span id="line-3630">   */</span>
+<span class="source-line-no">3631</span><span id="line-3631">  boolean submitRegionProcedure(long procId) {</span>
+<span class="source-line-no">3632</span><span id="line-3632">    if (procId == -1) {</span>
+<span class="source-line-no">3633</span><span id="line-3633">      return true;</span>
+<span class="source-line-no">3634</span><span id="line-3634">    }</span>
+<span class="source-line-no">3635</span><span id="line-3635">    // Ignore the region procedures which already submitted.</span>
+<span class="source-line-no">3636</span><span id="line-3636">    Long previous = submittedRegionProcedures.putIfAbsent(procId, procId);</span>
+<span class="source-line-no">3637</span><span id="line-3637">    if (previous != null) {</span>
+<span class="source-line-no">3638</span><span id="line-3638">      LOG.warn("Received procedure pid={}, which already submitted, just ignore it", procId);</span>
+<span class="source-line-no">3639</span><span id="line-3639">      return false;</span>
+<span class="source-line-no">3640</span><span id="line-3640">    }</span>
+<span class="source-line-no">3641</span><span id="line-3641">    // Ignore the region procedures which already executed.</span>
+<span class="source-line-no">3642</span><span id="line-3642">    if (executedRegionProcedures.getIfPresent(procId) != null) {</span>
+<span class="source-line-no">3643</span><span id="line-3643">      LOG.warn("Received procedure pid={}, which already executed, just ignore it", procId);</span>
+<span class="source-line-no">3644</span><span id="line-3644">      return false;</span>
+<span class="source-line-no">3645</span><span id="line-3645">    }</span>
+<span class="source-line-no">3646</span><span id="line-3646">    return true;</span>
+<span class="source-line-no">3647</span><span id="line-3647">  }</span>
+<span class="source-line-no">3648</span><span id="line-3648"></span>
+<span class="source-line-no">3649</span><span id="line-3649">  /**</span>
+<span class="source-line-no">3650</span><span id="line-3650">   * See {@link #submitRegionProcedure(long)}.</span>
+<span class="source-line-no">3651</span><span id="line-3651">   * @param procId the id of the open/close region procedure</span>
+<span class="source-line-no">3652</span><span id="line-3652">   */</span>
+<span class="source-line-no">3653</span><span id="line-3653">  public void finishRegionProcedure(long procId) {</span>
+<span class="source-line-no">3654</span><span id="line-3654">    executedRegionProcedures.put(procId, procId);</span>
+<span class="source-line-no">3655</span><span id="line-3655">    submittedRegionProcedures.remove(procId);</span>
+<span class="source-line-no">3656</span><span id="line-3656">  }</span>
+<span class="source-line-no">3657</span><span id="line-3657"></span>
+<span class="source-line-no">3658</span><span id="line-3658">  /**</span>
+<span class="source-line-no">3659</span><span id="line-3659">   * Force to terminate region server when abort timeout.</span>
+<span class="source-line-no">3660</span><span id="line-3660">   */</span>
+<span class="source-line-no">3661</span><span id="line-3661">  private static class SystemExitWhenAbortTimeout extends TimerTask {</span>
+<span class="source-line-no">3662</span><span id="line-3662"></span>
+<span class="source-line-no">3663</span><span id="line-3663">    public SystemExitWhenAbortTimeout() {</span>
+<span class="source-line-no">3664</span><span id="line-3664">    }</span>
+<span class="source-line-no">3665</span><span id="line-3665"></span>
+<span class="source-line-no">3666</span><span id="line-3666">    @Override</span>
+<span class="source-line-no">3667</span><span id="line-3667">    public void run() {</span>
+<span class="source-line-no">3668</span><span id="line-3668">      LOG.warn("Aborting region server timed out, terminating forcibly"</span>
+<span class="source-line-no">3669</span><span id="line-3669">        + " and does not wait for any running shutdown hooks or finalizers to finish their work."</span>
+<span class="source-line-no">3670</span><span id="line-3670">        + " Thread dump to stdout.");</span>
+<span class="source-line-no">3671</span><span id="line-3671">      Threads.printThreadInfo(System.out, "Zombie HRegionServer");</span>
+<span class="source-line-no">3672</span><span id="line-3672">      Runtime.getRuntime().halt(1);</span>
+<span class="source-line-no">3673</span><span id="line-3673">    }</span>
+<span class="source-line-no">3674</span><span id="line-3674">  }</span>
+<span class="source-line-no">3675</span><span id="line-3675"></span>
+<span class="source-line-no">3676</span><span id="line-3676">  @InterfaceAudience.Private</span>
+<span class="source-line-no">3677</span><span id="line-3677">  public CompactedHFilesDischarger getCompactedHFilesDischarger() {</span>
+<span class="source-line-no">3678</span><span id="line-3678">    return compactedFileDischarger;</span>
+<span class="source-line-no">3679</span><span id="line-3679">  }</span>
+<span class="source-line-no">3680</span><span id="line-3680"></span>
+<span class="source-line-no">3681</span><span id="line-3681">  /**</span>
+<span class="source-line-no">3682</span><span id="line-3682">   * Return pause time configured in {@link HConstants#HBASE_RPC_SHORTOPERATION_RETRY_PAUSE_TIME}}</span>
+<span class="source-line-no">3683</span><span id="line-3683">   * @return pause time</span>
+<span class="source-line-no">3684</span><span id="line-3684">   */</span>
+<span class="source-line-no">3685</span><span id="line-3685">  @InterfaceAudience.Private</span>
+<span class="source-line-no">3686</span><span id="line-3686">  public long getRetryPauseTime() {</span>
+<span class="source-line-no">3687</span><span id="line-3687">    return this.retryPauseTime;</span>
+<span class="source-line-no">3688</span><span id="line-3688">  }</span>
+<span class="source-line-no">3689</span><span id="line-3689"></span>
+<span class="source-line-no">3690</span><span id="line-3690">  @Override</span>
+<span class="source-line-no">3691</span><span id="line-3691">  public Optional&lt;ServerName&gt; getActiveMaster() {</span>
+<span class="source-line-no">3692</span><span id="line-3692">    return Optional.ofNullable(masterAddressTracker.getMasterAddress());</span>
+<span class="source-line-no">3693</span><span id="line-3693">  }</span>
+<span class="source-line-no">3694</span><span id="line-3694"></span>
+<span class="source-line-no">3695</span><span id="line-3695">  @Override</span>
+<span class="source-line-no">3696</span><span id="line-3696">  public List&lt;ServerName&gt; getBackupMasters() {</span>
+<span class="source-line-no">3697</span><span id="line-3697">    return masterAddressTracker.getBackupMasters();</span>
+<span class="source-line-no">3698</span><span id="line-3698">  }</span>
+<span class="source-line-no">3699</span><span id="line-3699"></span>
+<span class="source-line-no">3700</span><span id="line-3700">  @Override</span>
+<span class="source-line-no">3701</span><span id="line-3701">  public Iterator&lt;ServerName&gt; getBootstrapNodes() {</span>
+<span class="source-line-no">3702</span><span id="line-3702">    return bootstrapNodeManager.getBootstrapNodes().iterator();</span>
+<span class="source-line-no">3703</span><span id="line-3703">  }</span>
+<span class="source-line-no">3704</span><span id="line-3704"></span>
+<span class="source-line-no">3705</span><span id="line-3705">  @Override</span>
+<span class="source-line-no">3706</span><span id="line-3706">  public List&lt;HRegionLocation&gt; getMetaLocations() {</span>
+<span class="source-line-no">3707</span><span id="line-3707">    return metaRegionLocationCache.getMetaRegionLocations();</span>
+<span class="source-line-no">3708</span><span id="line-3708">  }</span>
+<span class="source-line-no">3709</span><span id="line-3709"></span>
+<span class="source-line-no">3710</span><span id="line-3710">  @Override</span>
+<span class="source-line-no">3711</span><span id="line-3711">  protected NamedQueueRecorder createNamedQueueRecord() {</span>
+<span class="source-line-no">3712</span><span id="line-3712">    return NamedQueueRecorder.getInstance(conf);</span>
+<span class="source-line-no">3713</span><span id="line-3713">  }</span>
+<span class="source-line-no">3714</span><span id="line-3714"></span>
+<span class="source-line-no">3715</span><span id="line-3715">  @Override</span>
+<span class="source-line-no">3716</span><span id="line-3716">  protected boolean clusterMode() {</span>
+<span class="source-line-no">3717</span><span id="line-3717">    // this method will be called in the constructor of super class, so we can not return masterless</span>
+<span class="source-line-no">3718</span><span id="line-3718">    // directly here, as it will always be false.</span>
+<span class="source-line-no">3719</span><span id="line-3719">    return !conf.getBoolean(MASTERLESS_CONFIG_NAME, false);</span>
+<span class="source-line-no">3720</span><span id="line-3720">  }</span>
+<span class="source-line-no">3721</span><span id="line-3721"></span>
+<span class="source-line-no">3722</span><span id="line-3722">  @InterfaceAudience.Private</span>
+<span class="source-line-no">3723</span><span id="line-3723">  public BrokenStoreFileCleaner getBrokenStoreFileCleaner() {</span>
+<span class="source-line-no">3724</span><span id="line-3724">    return brokenStoreFileCleaner;</span>
+<span class="source-line-no">3725</span><span id="line-3725">  }</span>
+<span class="source-line-no">3726</span><span id="line-3726"></span>
+<span class="source-line-no">3727</span><span id="line-3727">  @InterfaceAudience.Private</span>
+<span class="source-line-no">3728</span><span id="line-3728">  public RSMobFileCleanerChore getRSMobFileCleanerChore() {</span>
+<span class="source-line-no">3729</span><span id="line-3729">    return rsMobFileCleanerChore;</span>
 <span class="source-line-no">3730</span><span id="line-3730">  }</span>
 <span class="source-line-no">3731</span><span id="line-3731"></span>
-<span class="source-line-no">3732</span><span id="line-3732">  @Override</span>
-<span class="source-line-no">3733</span><span id="line-3733">  protected void stopChores() {</span>
-<span class="source-line-no">3734</span><span id="line-3734">    shutdownChore(nonceManagerChore);</span>
-<span class="source-line-no">3735</span><span id="line-3735">    shutdownChore(compactionChecker);</span>
-<span class="source-line-no">3736</span><span id="line-3736">    shutdownChore(compactedFileDischarger);</span>
-<span class="source-line-no">3737</span><span id="line-3737">    shutdownChore(periodicFlusher);</span>
-<span class="source-line-no">3738</span><span id="line-3738">    shutdownChore(healthCheckChore);</span>
-<span class="source-line-no">3739</span><span id="line-3739">    shutdownChore(executorStatusChore);</span>
-<span class="source-line-no">3740</span><span id="line-3740">    shutdownChore(storefileRefresher);</span>
-<span class="source-line-no">3741</span><span id="line-3741">    shutdownChore(fsUtilizationChore);</span>
-<span class="source-line-no">3742</span><span id="line-3742">    shutdownChore(namedQueueServiceChore);</span>
-<span class="source-line-no">3743</span><span id="line-3743">    shutdownChore(brokenStoreFileCleaner);</span>
-<span class="source-line-no">3744</span><span id="line-3744">    shutdownChore(rsMobFileCleanerChore);</span>
-<span class="source-line-no">3745</span><span id="line-3745">    shutdownChore(replicationMarkerChore);</span>
-<span class="source-line-no">3746</span><span id="line-3746">  }</span>
-<span class="source-line-no">3747</span><span id="line-3747"></span>
-<span class="source-line-no">3748</span><span id="line-3748">  @Override</span>
-<span class="source-line-no">3749</span><span id="line-3749">  public RegionReplicationBufferManager getRegionReplicationBufferManager() {</span>
-<span class="source-line-no">3750</span><span id="line-3750">    return regionReplicationBufferManager;</span>
-<span class="source-line-no">3751</span><span id="line-3751">  }</span>
-<span class="source-line-no">3752</span><span id="line-3752">}</span>
+<span class="source-line-no">3732</span><span id="line-3732">  RSSnapshotVerifier getRsSnapshotVerifier() {</span>
+<span class="source-line-no">3733</span><span id="line-3733">    return rsSnapshotVerifier;</span>
+<span class="source-line-no">3734</span><span id="line-3734">  }</span>
+<span class="source-line-no">3735</span><span id="line-3735"></span>
+<span class="source-line-no">3736</span><span id="line-3736">  @Override</span>
+<span class="source-line-no">3737</span><span id="line-3737">  protected void stopChores() {</span>
+<span class="source-line-no">3738</span><span id="line-3738">    shutdownChore(nonceManagerChore);</span>
+<span class="source-line-no">3739</span><span id="line-3739">    shutdownChore(compactionChecker);</span>
+<span class="source-line-no">3740</span><span id="line-3740">    shutdownChore(compactedFileDischarger);</span>
+<span class="source-line-no">3741</span><span id="line-3741">    shutdownChore(periodicFlusher);</span>
+<span class="source-line-no">3742</span><span id="line-3742">    shutdownChore(healthCheckChore);</span>
+<span class="source-line-no">3743</span><span id="line-3743">    shutdownChore(executorStatusChore);</span>
+<span class="source-line-no">3744</span><span id="line-3744">    shutdownChore(storefileRefresher);</span>
+<span class="source-line-no">3745</span><span id="line-3745">    shutdownChore(fsUtilizationChore);</span>
+<span class="source-line-no">3746</span><span id="line-3746">    shutdownChore(namedQueueServiceChore);</span>
+<span class="source-line-no">3747</span><span id="line-3747">    shutdownChore(brokenStoreFileCleaner);</span>
+<span class="source-line-no">3748</span><span id="line-3748">    shutdownChore(rsMobFileCleanerChore);</span>
+<span class="source-line-no">3749</span><span id="line-3749">    shutdownChore(replicationMarkerChore);</span>
+<span class="source-line-no">3750</span><span id="line-3750">  }</span>
+<span class="source-line-no">3751</span><span id="line-3751"></span>
+<span class="source-line-no">3752</span><span id="line-3752">  @Override</span>
+<span class="source-line-no">3753</span><span id="line-3753">  public RegionReplicationBufferManager getRegionReplicationBufferManager() {</span>
+<span class="source-line-no">3754</span><span id="line-3754">    return regionReplicationBufferManager;</span>
+<span class="source-line-no">3755</span><span id="line-3755">  }</span>
+<span class="source-line-no">3756</span><span id="line-3756">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserAggregateImpl.html b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserAggregateImpl.html
index 8537a9ff325..86e293eeda2 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserAggregateImpl.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserAggregateImpl.html
@@ -36,177 +36,233 @@
 <span class="source-line-no">023</span><span id="line-23">import org.apache.hadoop.conf.Configuration;</span>
 <span class="source-line-no">024</span><span id="line-24">import org.apache.hadoop.hbase.CompatibilitySingletonFactory;</span>
 <span class="source-line-no">025</span><span id="line-25">import org.apache.hadoop.hbase.ipc.RpcServer;</span>
-<span class="source-line-no">026</span><span id="line-26">import org.apache.hadoop.hbase.security.User;</span>
-<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.security.UserProvider;</span>
-<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.util.LossyCounting;</span>
-<span class="source-line-no">029</span><span id="line-29">import org.apache.yetus.audience.InterfaceAudience;</span>
-<span class="source-line-no">030</span><span id="line-30"></span>
-<span class="source-line-no">031</span><span id="line-31">@InterfaceAudience.Private</span>
-<span class="source-line-no">032</span><span id="line-32">public class MetricsUserAggregateImpl implements MetricsUserAggregate {</span>
+<span class="source-line-no">026</span><span id="line-26">import org.apache.hadoop.hbase.ipc.ServerRpcConnection;</span>
+<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.security.User;</span>
+<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.security.UserProvider;</span>
+<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.util.LossyCounting;</span>
+<span class="source-line-no">030</span><span id="line-30">import org.apache.yetus.audience.InterfaceAudience;</span>
+<span class="source-line-no">031</span><span id="line-31"></span>
+<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos;</span>
 <span class="source-line-no">033</span><span id="line-33"></span>
-<span class="source-line-no">034</span><span id="line-34">  /** Provider for mapping principal names to Users */</span>
-<span class="source-line-no">035</span><span id="line-35">  private final UserProvider userProvider;</span>
+<span class="source-line-no">034</span><span id="line-34">@InterfaceAudience.Private</span>
+<span class="source-line-no">035</span><span id="line-35">public class MetricsUserAggregateImpl implements MetricsUserAggregate {</span>
 <span class="source-line-no">036</span><span id="line-36"></span>
-<span class="source-line-no">037</span><span id="line-37">  private final MetricsUserAggregateSource source;</span>
-<span class="source-line-no">038</span><span id="line-38">  private final LossyCounting&lt;MetricsUserSource&gt; userMetricLossyCounting;</span>
+<span class="source-line-no">037</span><span id="line-37">  /** Provider for mapping principal names to Users */</span>
+<span class="source-line-no">038</span><span id="line-38">  private final UserProvider userProvider;</span>
 <span class="source-line-no">039</span><span id="line-39"></span>
-<span class="source-line-no">040</span><span id="line-40">  public MetricsUserAggregateImpl(Configuration conf) {</span>
-<span class="source-line-no">041</span><span id="line-41">    source = CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)</span>
-<span class="source-line-no">042</span><span id="line-42">      .getUserAggregate();</span>
-<span class="source-line-no">043</span><span id="line-43">    userMetricLossyCounting = new LossyCounting&lt;&gt;("userMetrics", conf, source::deregister);</span>
-<span class="source-line-no">044</span><span id="line-44">    this.userProvider = UserProvider.instantiate(conf);</span>
-<span class="source-line-no">045</span><span id="line-45">  }</span>
-<span class="source-line-no">046</span><span id="line-46"></span>
-<span class="source-line-no">047</span><span id="line-47">  /**</span>
-<span class="source-line-no">048</span><span id="line-48">   * Returns the active user to which authorization checks should be applied. If we are in the</span>
-<span class="source-line-no">049</span><span id="line-49">   * context of an RPC call, the remote user is used, otherwise the currently logged in user is</span>
-<span class="source-line-no">050</span><span id="line-50">   * used.</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 String getActiveUser() {</span>
-<span class="source-line-no">053</span><span id="line-53">    Optional&lt;User&gt; user = RpcServer.getRequestUser();</span>
-<span class="source-line-no">054</span><span id="line-54">    if (!user.isPresent()) {</span>
-<span class="source-line-no">055</span><span id="line-55">      // for non-rpc handling, fallback to system user</span>
-<span class="source-line-no">056</span><span id="line-56">      try {</span>
-<span class="source-line-no">057</span><span id="line-57">        user = Optional.of(userProvider.getCurrent());</span>
-<span class="source-line-no">058</span><span id="line-58">      } catch (IOException ignore) {</span>
-<span class="source-line-no">059</span><span id="line-59">      }</span>
-<span class="source-line-no">060</span><span id="line-60">    }</span>
-<span class="source-line-no">061</span><span id="line-61">    return user.map(User::getShortName).orElse(null);</span>
-<span class="source-line-no">062</span><span id="line-62">  }</span>
-<span class="source-line-no">063</span><span id="line-63"></span>
-<span class="source-line-no">064</span><span id="line-64">  @Override</span>
-<span class="source-line-no">065</span><span id="line-65">  public MetricsUserAggregateSource getSource() {</span>
-<span class="source-line-no">066</span><span id="line-66">    return source;</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">  @Override</span>
-<span class="source-line-no">070</span><span id="line-70">  public void updatePut(long t) {</span>
-<span class="source-line-no">071</span><span id="line-71">    String user = getActiveUser();</span>
-<span class="source-line-no">072</span><span id="line-72">    if (user != null) {</span>
-<span class="source-line-no">073</span><span id="line-73">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">074</span><span id="line-74">      userSource.updatePut(t);</span>
-<span class="source-line-no">075</span><span id="line-75">      incrementClientWriteMetrics(userSource);</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">  }</span>
-<span class="source-line-no">079</span><span id="line-79"></span>
-<span class="source-line-no">080</span><span id="line-80">  private String getClient() {</span>
-<span class="source-line-no">081</span><span id="line-81">    Optional&lt;InetAddress&gt; ipOptional = RpcServer.getRemoteAddress();</span>
-<span class="source-line-no">082</span><span id="line-82">    return ipOptional.map(InetAddress::getHostName).orElse(null);</span>
-<span class="source-line-no">083</span><span id="line-83">  }</span>
-<span class="source-line-no">084</span><span id="line-84"></span>
-<span class="source-line-no">085</span><span id="line-85">  private void incrementClientReadMetrics(MetricsUserSource userSource) {</span>
-<span class="source-line-no">086</span><span id="line-86">    String client = getClient();</span>
-<span class="source-line-no">087</span><span id="line-87">    if (client != null &amp;&amp; userSource != null) {</span>
-<span class="source-line-no">088</span><span id="line-88">      userSource.getOrCreateMetricsClient(client).incrementReadRequest();</span>
-<span class="source-line-no">089</span><span id="line-89">    }</span>
-<span class="source-line-no">090</span><span id="line-90">  }</span>
-<span class="source-line-no">091</span><span id="line-91"></span>
-<span class="source-line-no">092</span><span id="line-92">  private void incrementFilteredReadRequests(MetricsUserSource userSource) {</span>
-<span class="source-line-no">093</span><span id="line-93">    String client = getClient();</span>
-<span class="source-line-no">094</span><span id="line-94">    if (client != null &amp;&amp; userSource != null) {</span>
-<span class="source-line-no">095</span><span id="line-95">      userSource.getOrCreateMetricsClient(client).incrementFilteredReadRequests();</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"></span>
-<span class="source-line-no">099</span><span id="line-99">  private void incrementClientWriteMetrics(MetricsUserSource userSource) {</span>
-<span class="source-line-no">100</span><span id="line-100">    String client = getClient();</span>
-<span class="source-line-no">101</span><span id="line-101">    if (client != null &amp;&amp; userSource != null) {</span>
-<span class="source-line-no">102</span><span id="line-102">      userSource.getOrCreateMetricsClient(client).incrementWriteRequest();</span>
+<span class="source-line-no">040</span><span id="line-40">  private final MetricsUserAggregateSource source;</span>
+<span class="source-line-no">041</span><span id="line-41">  private final LossyCounting&lt;MetricsUserSource&gt; userMetricLossyCounting;</span>
+<span class="source-line-no">042</span><span id="line-42"></span>
+<span class="source-line-no">043</span><span id="line-43">  public MetricsUserAggregateImpl(Configuration conf) {</span>
+<span class="source-line-no">044</span><span id="line-44">    source = CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)</span>
+<span class="source-line-no">045</span><span id="line-45">      .getUserAggregate();</span>
+<span class="source-line-no">046</span><span id="line-46">    userMetricLossyCounting = new LossyCounting&lt;&gt;("userMetrics", conf, source::deregister);</span>
+<span class="source-line-no">047</span><span id="line-47">    this.userProvider = UserProvider.instantiate(conf);</span>
+<span class="source-line-no">048</span><span id="line-48">  }</span>
+<span class="source-line-no">049</span><span id="line-49"></span>
+<span class="source-line-no">050</span><span id="line-50">  /**</span>
+<span class="source-line-no">051</span><span id="line-51">   * Returns the active user to which authorization checks should be applied. If we are in the</span>
+<span class="source-line-no">052</span><span id="line-52">   * context of an RPC call, the remote user is used, otherwise the currently logged in user is</span>
+<span class="source-line-no">053</span><span id="line-53">   * used.</span>
+<span class="source-line-no">054</span><span id="line-54">   */</span>
+<span class="source-line-no">055</span><span id="line-55">  private String getActiveUser() {</span>
+<span class="source-line-no">056</span><span id="line-56">    Optional&lt;User&gt; user = RpcServer.getRequestUser();</span>
+<span class="source-line-no">057</span><span id="line-57">    if (!user.isPresent()) {</span>
+<span class="source-line-no">058</span><span id="line-58">      // for non-rpc handling, fallback to system user</span>
+<span class="source-line-no">059</span><span id="line-59">      try {</span>
+<span class="source-line-no">060</span><span id="line-60">        user = Optional.of(userProvider.getCurrent());</span>
+<span class="source-line-no">061</span><span id="line-61">      } catch (IOException ignore) {</span>
+<span class="source-line-no">062</span><span id="line-62">      }</span>
+<span class="source-line-no">063</span><span id="line-63">    }</span>
+<span class="source-line-no">064</span><span id="line-64">    return user.map(User::getShortName).orElse(null);</span>
+<span class="source-line-no">065</span><span id="line-65">  }</span>
+<span class="source-line-no">066</span><span id="line-66"></span>
+<span class="source-line-no">067</span><span id="line-67">  @Override</span>
+<span class="source-line-no">068</span><span id="line-68">  public MetricsUserAggregateSource getSource() {</span>
+<span class="source-line-no">069</span><span id="line-69">    return source;</span>
+<span class="source-line-no">070</span><span id="line-70">  }</span>
+<span class="source-line-no">071</span><span id="line-71"></span>
+<span class="source-line-no">072</span><span id="line-72">  @Override</span>
+<span class="source-line-no">073</span><span id="line-73">  public void updatePut(long t) {</span>
+<span class="source-line-no">074</span><span id="line-74">    String user = getActiveUser();</span>
+<span class="source-line-no">075</span><span id="line-75">    if (user != null) {</span>
+<span class="source-line-no">076</span><span id="line-76">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">077</span><span id="line-77">      userSource.updatePut(t);</span>
+<span class="source-line-no">078</span><span id="line-78">      incrementClientWriteMetrics(userSource);</span>
+<span class="source-line-no">079</span><span id="line-79">    }</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"></span>
+<span class="source-line-no">083</span><span id="line-83">  private String getClient() {</span>
+<span class="source-line-no">084</span><span id="line-84">    Optional&lt;InetAddress&gt; ipOptional = RpcServer.getRemoteAddress();</span>
+<span class="source-line-no">085</span><span id="line-85">    return ipOptional.map(InetAddress::getHostName).orElse(null);</span>
+<span class="source-line-no">086</span><span id="line-86">  }</span>
+<span class="source-line-no">087</span><span id="line-87"></span>
+<span class="source-line-no">088</span><span id="line-88">  private void incrementClientReadMetrics(MetricsUserSource userSource) {</span>
+<span class="source-line-no">089</span><span id="line-89">    ClientConnectionContext ctx = getClientConnectionContext();</span>
+<span class="source-line-no">090</span><span id="line-90">    String client = getClient();</span>
+<span class="source-line-no">091</span><span id="line-91">    if (client != null &amp;&amp; userSource != null) {</span>
+<span class="source-line-no">092</span><span id="line-92">      userSource.getOrCreateMetricsClient(client, ctx.hostAddress, ctx.userName, ctx.clientVersion,</span>
+<span class="source-line-no">093</span><span id="line-93">        ctx.serviceName).incrementReadRequest();</span>
+<span class="source-line-no">094</span><span id="line-94">    }</span>
+<span class="source-line-no">095</span><span id="line-95">  }</span>
+<span class="source-line-no">096</span><span id="line-96"></span>
+<span class="source-line-no">097</span><span id="line-97">  private void incrementFilteredReadRequests(MetricsUserSource userSource) {</span>
+<span class="source-line-no">098</span><span id="line-98">    ClientConnectionContext ctx = getClientConnectionContext();</span>
+<span class="source-line-no">099</span><span id="line-99">    String client = getClient();</span>
+<span class="source-line-no">100</span><span id="line-100">    if (client != null &amp;&amp; userSource != null) {</span>
+<span class="source-line-no">101</span><span id="line-101">      userSource.getOrCreateMetricsClient(client, ctx.hostAddress, ctx.userName, ctx.clientVersion,</span>
+<span class="source-line-no">102</span><span id="line-102">        ctx.serviceName).incrementFilteredReadRequests();</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"></span>
-<span class="source-line-no">106</span><span id="line-106">  @Override</span>
-<span class="source-line-no">107</span><span id="line-107">  public void updateDelete(long t) {</span>
-<span class="source-line-no">108</span><span id="line-108">    String user = getActiveUser();</span>
-<span class="source-line-no">109</span><span id="line-109">    if (user != null) {</span>
-<span class="source-line-no">110</span><span id="line-110">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">111</span><span id="line-111">      userSource.updateDelete(t);</span>
-<span class="source-line-no">112</span><span id="line-112">      incrementClientWriteMetrics(userSource);</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">  @Override</span>
-<span class="source-line-no">117</span><span id="line-117">  public void updateGet(long time, long blockBytesScanned) {</span>
-<span class="source-line-no">118</span><span id="line-118">    String user = getActiveUser();</span>
-<span class="source-line-no">119</span><span id="line-119">    if (user != null) {</span>
-<span class="source-line-no">120</span><span id="line-120">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">121</span><span id="line-121">      userSource.updateGet(time, blockBytesScanned);</span>
+<span class="source-line-no">106</span><span id="line-106">  private void incrementClientWriteMetrics(MetricsUserSource userSource) {</span>
+<span class="source-line-no">107</span><span id="line-107">    ClientConnectionContext ctx = getClientConnectionContext();</span>
+<span class="source-line-no">108</span><span id="line-108">    String client = getClient();</span>
+<span class="source-line-no">109</span><span id="line-109">    if (client != null &amp;&amp; userSource != null) {</span>
+<span class="source-line-no">110</span><span id="line-110">      userSource.getOrCreateMetricsClient(client, ctx.hostAddress, ctx.userName, ctx.clientVersion,</span>
+<span class="source-line-no">111</span><span id="line-111">        ctx.serviceName).incrementWriteRequest();</span>
+<span class="source-line-no">112</span><span id="line-112">    }</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">  @Override</span>
+<span class="source-line-no">116</span><span id="line-116">  public void updateDelete(long t) {</span>
+<span class="source-line-no">117</span><span id="line-117">    String user = getActiveUser();</span>
+<span class="source-line-no">118</span><span id="line-118">    if (user != null) {</span>
+<span class="source-line-no">119</span><span id="line-119">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">120</span><span id="line-120">      userSource.updateDelete(t);</span>
+<span class="source-line-no">121</span><span id="line-121">      incrementClientWriteMetrics(userSource);</span>
 <span class="source-line-no">122</span><span id="line-122">    }</span>
 <span class="source-line-no">123</span><span id="line-123">  }</span>
 <span class="source-line-no">124</span><span id="line-124"></span>
 <span class="source-line-no">125</span><span id="line-125">  @Override</span>
-<span class="source-line-no">126</span><span id="line-126">  public void updateIncrement(long time, long blockBytesScanned) {</span>
+<span class="source-line-no">126</span><span id="line-126">  public void updateGet(long time, long blockBytesScanned) {</span>
 <span class="source-line-no">127</span><span id="line-127">    String user = getActiveUser();</span>
 <span class="source-line-no">128</span><span id="line-128">    if (user != null) {</span>
 <span class="source-line-no">129</span><span id="line-129">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">130</span><span id="line-130">      userSource.updateIncrement(time, blockBytesScanned);</span>
-<span class="source-line-no">131</span><span id="line-131">      incrementClientWriteMetrics(userSource);</span>
-<span class="source-line-no">132</span><span id="line-132">    }</span>
-<span class="source-line-no">133</span><span id="line-133">  }</span>
-<span class="source-line-no">134</span><span id="line-134"></span>
-<span class="source-line-no">135</span><span id="line-135">  @Override</span>
-<span class="source-line-no">136</span><span id="line-136">  public void updateAppend(long time, long blockBytesScanned) {</span>
-<span class="source-line-no">137</span><span id="line-137">    String user = getActiveUser();</span>
-<span class="source-line-no">138</span><span id="line-138">    if (user != null) {</span>
-<span class="source-line-no">139</span><span id="line-139">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">140</span><span id="line-140">      userSource.updateAppend(time, blockBytesScanned);</span>
-<span class="source-line-no">141</span><span id="line-141">      incrementClientWriteMetrics(userSource);</span>
-<span class="source-line-no">142</span><span id="line-142">    }</span>
-<span class="source-line-no">143</span><span id="line-143">  }</span>
-<span class="source-line-no">144</span><span id="line-144"></span>
-<span class="source-line-no">145</span><span id="line-145">  @Override</span>
-<span class="source-line-no">146</span><span id="line-146">  public void updateReplay(long t) {</span>
-<span class="source-line-no">147</span><span id="line-147">    String user = getActiveUser();</span>
-<span class="source-line-no">148</span><span id="line-148">    if (user != null) {</span>
-<span class="source-line-no">149</span><span id="line-149">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">150</span><span id="line-150">      userSource.updateReplay(t);</span>
-<span class="source-line-no">151</span><span id="line-151">      incrementClientWriteMetrics(userSource);</span>
-<span class="source-line-no">152</span><span id="line-152">    }</span>
-<span class="source-line-no">153</span><span id="line-153">  }</span>
-<span class="source-line-no">154</span><span id="line-154"></span>
-<span class="source-line-no">155</span><span id="line-155">  @Override</span>
-<span class="source-line-no">156</span><span id="line-156">  public void updateScan(long time, long blockBytesScanned) {</span>
-<span class="source-line-no">157</span><span id="line-157">    String user = getActiveUser();</span>
-<span class="source-line-no">158</span><span id="line-158">    if (user != null) {</span>
-<span class="source-line-no">159</span><span id="line-159">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">160</span><span id="line-160">      userSource.updateScan(time, blockBytesScanned);</span>
+<span class="source-line-no">130</span><span id="line-130">      userSource.updateGet(time, blockBytesScanned);</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"></span>
+<span class="source-line-no">134</span><span id="line-134">  @Override</span>
+<span class="source-line-no">135</span><span id="line-135">  public void updateIncrement(long time, long blockBytesScanned) {</span>
+<span class="source-line-no">136</span><span id="line-136">    String user = getActiveUser();</span>
+<span class="source-line-no">137</span><span id="line-137">    if (user != null) {</span>
+<span class="source-line-no">138</span><span id="line-138">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">139</span><span id="line-139">      userSource.updateIncrement(time, blockBytesScanned);</span>
+<span class="source-line-no">140</span><span id="line-140">      incrementClientWriteMetrics(userSource);</span>
+<span class="source-line-no">141</span><span id="line-141">    }</span>
+<span class="source-line-no">142</span><span id="line-142">  }</span>
+<span class="source-line-no">143</span><span id="line-143"></span>
+<span class="source-line-no">144</span><span id="line-144">  @Override</span>
+<span class="source-line-no">145</span><span id="line-145">  public void updateAppend(long time, long blockBytesScanned) {</span>
+<span class="source-line-no">146</span><span id="line-146">    String user = getActiveUser();</span>
+<span class="source-line-no">147</span><span id="line-147">    if (user != null) {</span>
+<span class="source-line-no">148</span><span id="line-148">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">149</span><span id="line-149">      userSource.updateAppend(time, blockBytesScanned);</span>
+<span class="source-line-no">150</span><span id="line-150">      incrementClientWriteMetrics(userSource);</span>
+<span class="source-line-no">151</span><span id="line-151">    }</span>
+<span class="source-line-no">152</span><span id="line-152">  }</span>
+<span class="source-line-no">153</span><span id="line-153"></span>
+<span class="source-line-no">154</span><span id="line-154">  @Override</span>
+<span class="source-line-no">155</span><span id="line-155">  public void updateReplay(long t) {</span>
+<span class="source-line-no">156</span><span id="line-156">    String user = getActiveUser();</span>
+<span class="source-line-no">157</span><span id="line-157">    if (user != null) {</span>
+<span class="source-line-no">158</span><span id="line-158">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">159</span><span id="line-159">      userSource.updateReplay(t);</span>
+<span class="source-line-no">160</span><span id="line-160">      incrementClientWriteMetrics(userSource);</span>
 <span class="source-line-no">161</span><span id="line-161">    }</span>
 <span class="source-line-no">162</span><span id="line-162">  }</span>
 <span class="source-line-no">163</span><span id="line-163"></span>
 <span class="source-line-no">164</span><span id="line-164">  @Override</span>
-<span class="source-line-no">165</span><span id="line-165">  public void updateCheckAndMutate(long blockBytesScanned) {</span>
+<span class="source-line-no">165</span><span id="line-165">  public void updateScan(long time, long blockBytesScanned) {</span>
 <span class="source-line-no">166</span><span id="line-166">    String user = getActiveUser();</span>
 <span class="source-line-no">167</span><span id="line-167">    if (user != null) {</span>
 <span class="source-line-no">168</span><span id="line-168">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">169</span><span id="line-169">      userSource.updateCheckAndMutate(blockBytesScanned);</span>
+<span class="source-line-no">169</span><span id="line-169">      userSource.updateScan(time, blockBytesScanned);</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"></span>
 <span class="source-line-no">173</span><span id="line-173">  @Override</span>
-<span class="source-line-no">174</span><span id="line-174">  public void updateFilteredReadRequests() {</span>
+<span class="source-line-no">174</span><span id="line-174">  public void updateCheckAndMutate(long blockBytesScanned) {</span>
 <span class="source-line-no">175</span><span id="line-175">    String user = getActiveUser();</span>
 <span class="source-line-no">176</span><span id="line-176">    if (user != null) {</span>
 <span class="source-line-no">177</span><span id="line-177">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">178</span><span id="line-178">      incrementFilteredReadRequests(userSource);</span>
+<span class="source-line-no">178</span><span id="line-178">      userSource.updateCheckAndMutate(blockBytesScanned);</span>
 <span class="source-line-no">179</span><span id="line-179">    }</span>
 <span class="source-line-no">180</span><span id="line-180">  }</span>
 <span class="source-line-no">181</span><span id="line-181"></span>
 <span class="source-line-no">182</span><span id="line-182">  @Override</span>
-<span class="source-line-no">183</span><span id="line-183">  public void updateReadRequestCount() {</span>
+<span class="source-line-no">183</span><span id="line-183">  public void updateFilteredReadRequests() {</span>
 <span class="source-line-no">184</span><span id="line-184">    String user = getActiveUser();</span>
 <span class="source-line-no">185</span><span id="line-185">    if (user != null) {</span>
 <span class="source-line-no">186</span><span id="line-186">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">187</span><span id="line-187">      incrementClientReadMetrics(userSource);</span>
+<span class="source-line-no">187</span><span id="line-187">      incrementFilteredReadRequests(userSource);</span>
 <span class="source-line-no">188</span><span id="line-188">    }</span>
 <span class="source-line-no">189</span><span id="line-189">  }</span>
 <span class="source-line-no">190</span><span id="line-190"></span>
-<span class="source-line-no">191</span><span id="line-191">  private MetricsUserSource getOrCreateMetricsUser(String user) {</span>
-<span class="source-line-no">192</span><span id="line-192">    MetricsUserSource userSource = source.getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">193</span><span id="line-193">    userMetricLossyCounting.add(userSource);</span>
-<span class="source-line-no">194</span><span id="line-194">    return userSource;</span>
-<span class="source-line-no">195</span><span id="line-195">  }</span>
-<span class="source-line-no">196</span><span id="line-196">}</span>
+<span class="source-line-no">191</span><span id="line-191">  @Override</span>
+<span class="source-line-no">192</span><span id="line-192">  public void updateReadRequestCount() {</span>
+<span class="source-line-no">193</span><span id="line-193">    String user = getActiveUser();</span>
+<span class="source-line-no">194</span><span id="line-194">    if (user != null) {</span>
+<span class="source-line-no">195</span><span id="line-195">      MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">196</span><span id="line-196">      incrementClientReadMetrics(userSource);</span>
+<span class="source-line-no">197</span><span id="line-197">    }</span>
+<span class="source-line-no">198</span><span id="line-198">  }</span>
+<span class="source-line-no">199</span><span id="line-199"></span>
+<span class="source-line-no">200</span><span id="line-200">  private MetricsUserSource getOrCreateMetricsUser(String user) {</span>
+<span class="source-line-no">201</span><span id="line-201">    MetricsUserSource userSource = source.getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">202</span><span id="line-202">    userMetricLossyCounting.add(userSource);</span>
+<span class="source-line-no">203</span><span id="line-203">    return userSource;</span>
+<span class="source-line-no">204</span><span id="line-204">  }</span>
+<span class="source-line-no">205</span><span id="line-205"></span>
+<span class="source-line-no">206</span><span id="line-206">  private ClientConnectionContext getClientConnectionContext() {</span>
+<span class="source-line-no">207</span><span id="line-207">    String hostAddress = null;</span>
+<span class="source-line-no">208</span><span id="line-208">    String userName = "Unknown";</span>
+<span class="source-line-no">209</span><span id="line-209">    String clientVersion = "Unknown";</span>
+<span class="source-line-no">210</span><span id="line-210">    String serviceName = "Unknown";</span>
+<span class="source-line-no">211</span><span id="line-211"></span>
+<span class="source-line-no">212</span><span id="line-212">    Optional&lt;ServerRpcConnection&gt; rpcConnectionOptional = RpcServer.getCurrentServerRpcConnection();</span>
+<span class="source-line-no">213</span><span id="line-213">    if (rpcConnectionOptional.isPresent()) {</span>
+<span class="source-line-no">214</span><span id="line-214">      ServerRpcConnection rpcConnection = rpcConnectionOptional.get();</span>
+<span class="source-line-no">215</span><span id="line-215">      hostAddress = rpcConnection.getHostAddress();</span>
+<span class="source-line-no">216</span><span id="line-216">      RPCProtos.ConnectionHeader connectionHeader = rpcConnection.getConnectionHeader();</span>
+<span class="source-line-no">217</span><span id="line-217">      if (connectionHeader.hasUserInfo()) {</span>
+<span class="source-line-no">218</span><span id="line-218">        RPCProtos.UserInformation userInfoProto = connectionHeader.getUserInfo();</span>
+<span class="source-line-no">219</span><span id="line-219">        if (userInfoProto.hasEffectiveUser()) {</span>
+<span class="source-line-no">220</span><span id="line-220">          userName = userInfoProto.getEffectiveUser();</span>
+<span class="source-line-no">221</span><span id="line-221">        }</span>
+<span class="source-line-no">222</span><span id="line-222">      }</span>
+<span class="source-line-no">223</span><span id="line-223">      if (connectionHeader.hasVersionInfo()) {</span>
+<span class="source-line-no">224</span><span id="line-224">        clientVersion = connectionHeader.getVersionInfo().getVersion();</span>
+<span class="source-line-no">225</span><span id="line-225">      }</span>
+<span class="source-line-no">226</span><span id="line-226">      if (connectionHeader.hasServiceName()) {</span>
+<span class="source-line-no">227</span><span id="line-227">        serviceName = connectionHeader.getServiceName();</span>
+<span class="source-line-no">228</span><span id="line-228">      }</span>
+<span class="source-line-no">229</span><span id="line-229">    }</span>
+<span class="source-line-no">230</span><span id="line-230">    return new ClientConnectionContext(hostAddress, userName, clientVersion, serviceName);</span>
+<span class="source-line-no">231</span><span id="line-231">  }</span>
+<span class="source-line-no">232</span><span id="line-232"></span>
+<span class="source-line-no">233</span><span id="line-233">  private static class ClientConnectionContext {</span>
+<span class="source-line-no">234</span><span id="line-234">    final String hostAddress;</span>
+<span class="source-line-no">235</span><span id="line-235">    final String userName;</span>
+<span class="source-line-no">236</span><span id="line-236">    final String clientVersion;</span>
+<span class="source-line-no">237</span><span id="line-237">    final String serviceName;</span>
+<span class="source-line-no">238</span><span id="line-238"></span>
+<span class="source-line-no">239</span><span id="line-239">    ClientConnectionContext(String hostAddress, String userName, String clientVersion,</span>
+<span class="source-line-no">240</span><span id="line-240">      String serviceName) {</span>
+<span class="source-line-no">241</span><span id="line-241">      this.hostAddress = hostAddress;</span>
+<span class="source-line-no">242</span><span id="line-242">      this.userName = userName;</span>
+<span class="source-line-no">243</span><span id="line-243">      this.clientVersion = clientVersion;</span>
+<span class="source-line-no">244</span><span id="line-244">      this.serviceName = serviceName;</span>
+<span class="source-line-no">245</span><span id="line-245">    }</span>
+<span class="source-line-no">246</span><span id="line-246"></span>
+<span class="source-line-no">247</span><span id="line-247">    public String toString() {</span>
+<span class="source-line-no">248</span><span id="line-248">      return "ClientConnectionContext{hostAddress=" + hostAddress + ", userName=" + userName</span>
+<span class="source-line-no">249</span><span id="line-249">        + ", clientVersion=" + clientVersion + ", serviceName=" + serviceName + "}";</span>
+<span class="source-line-no">250</span><span id="line-250">    }</span>
+<span class="source-line-no">251</span><span id="line-251">  }</span>
+<span class="source-line-no">252</span><span id="line-252">}</span>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserSource.ClientMetrics.html b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserSource.ClientMetrics.html
index 8f6e2708192..9937914a699 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserSource.ClientMetrics.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserSource.ClientMetrics.html
@@ -52,46 +52,55 @@
 <span class="source-line-no">039</span><span id="line-39">    void incrementFilteredReadRequests();</span>
 <span class="source-line-no">040</span><span id="line-40"></span>
 <span class="source-line-no">041</span><span id="line-41">    long getFilteredReadRequests();</span>
-<span class="source-line-no">042</span><span id="line-42">  }</span>
-<span class="source-line-no">043</span><span id="line-43"></span>
-<span class="source-line-no">044</span><span id="line-44">  String getUser();</span>
-<span class="source-line-no">045</span><span id="line-45"></span>
-<span class="source-line-no">046</span><span id="line-46">  void register();</span>
-<span class="source-line-no">047</span><span id="line-47"></span>
-<span class="source-line-no">048</span><span id="line-48">  void deregister();</span>
... 72718 lines suppressed ...