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 2018/09/21 14:53:16 UTC
[10/15] hbase-site git commit: Published site at
ddd30a2241ce625e178571bb7fc8984846b5432b.
http://git-wip-us.apache.org/repos/asf/hbase-site/blob/b8bb8088/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannerHolder.html
----------------------------------------------------------------------
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannerHolder.html b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannerHolder.html
index 58769da..25f458d 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannerHolder.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RSRpcServices.RegionScannerHolder.html
@@ -3290,437 +3290,449 @@
<span class="sourceLineNo">3282</span> break;<a name="line.3282"></a>
<span class="sourceLineNo">3283</span> }<a name="line.3283"></a>
<span class="sourceLineNo">3284</span> }<a name="line.3284"></a>
-<span class="sourceLineNo">3285</span> }<a name="line.3285"></a>
-<span class="sourceLineNo">3286</span> boolean sizeLimitReached = scannerContext.checkSizeLimit(LimitScope.BETWEEN_ROWS);<a name="line.3286"></a>
-<span class="sourceLineNo">3287</span> boolean timeLimitReached = scannerContext.checkTimeLimit(LimitScope.BETWEEN_ROWS);<a name="line.3287"></a>
-<span class="sourceLineNo">3288</span> boolean resultsLimitReached = numOfResults >= maxResults;<a name="line.3288"></a>
-<span class="sourceLineNo">3289</span> limitReached = sizeLimitReached || timeLimitReached || resultsLimitReached;<a name="line.3289"></a>
-<span class="sourceLineNo">3290</span><a name="line.3290"></a>
-<span class="sourceLineNo">3291</span> if (limitReached || !moreRows) {<a name="line.3291"></a>
-<span class="sourceLineNo">3292</span> if (LOG.isTraceEnabled()) {<a name="line.3292"></a>
-<span class="sourceLineNo">3293</span> LOG.trace("Done scanning. limitReached: " + limitReached + " moreRows: " + moreRows<a name="line.3293"></a>
-<span class="sourceLineNo">3294</span> + " scannerContext: " + scannerContext);<a name="line.3294"></a>
-<span class="sourceLineNo">3295</span> }<a name="line.3295"></a>
-<span class="sourceLineNo">3296</span> // We only want to mark a ScanResponse as a heartbeat message in the event that<a name="line.3296"></a>
-<span class="sourceLineNo">3297</span> // there are more values to be read server side. If there aren't more values,<a name="line.3297"></a>
-<span class="sourceLineNo">3298</span> // marking it as a heartbeat is wasteful because the client will need to issue<a name="line.3298"></a>
-<span class="sourceLineNo">3299</span> // another ScanRequest only to realize that they already have all the values<a name="line.3299"></a>
-<span class="sourceLineNo">3300</span> if (moreRows) {<a name="line.3300"></a>
-<span class="sourceLineNo">3301</span> // Heartbeat messages occur when the time limit has been reached.<a name="line.3301"></a>
-<span class="sourceLineNo">3302</span> builder.setHeartbeatMessage(timeLimitReached);<a name="line.3302"></a>
-<span class="sourceLineNo">3303</span> if (timeLimitReached && rsh.needCursor) {<a name="line.3303"></a>
-<span class="sourceLineNo">3304</span> Cell cursorCell = scannerContext.getLastPeekedCell();<a name="line.3304"></a>
-<span class="sourceLineNo">3305</span> if (cursorCell != null ) {<a name="line.3305"></a>
-<span class="sourceLineNo">3306</span> builder.setCursor(ProtobufUtil.toCursor(cursorCell));<a name="line.3306"></a>
-<span class="sourceLineNo">3307</span> }<a name="line.3307"></a>
-<span class="sourceLineNo">3308</span> }<a name="line.3308"></a>
-<span class="sourceLineNo">3309</span> }<a name="line.3309"></a>
-<span class="sourceLineNo">3310</span> break;<a name="line.3310"></a>
-<span class="sourceLineNo">3311</span> }<a name="line.3311"></a>
-<span class="sourceLineNo">3312</span> values.clear();<a name="line.3312"></a>
-<span class="sourceLineNo">3313</span> }<a name="line.3313"></a>
-<span class="sourceLineNo">3314</span> builder.setMoreResultsInRegion(moreRows);<a name="line.3314"></a>
-<span class="sourceLineNo">3315</span> // Check to see if the client requested that we track metrics server side. If the<a name="line.3315"></a>
-<span class="sourceLineNo">3316</span> // client requested metrics, retrieve the metrics from the scanner context.<a name="line.3316"></a>
-<span class="sourceLineNo">3317</span> if (trackMetrics) {<a name="line.3317"></a>
-<span class="sourceLineNo">3318</span> Map<String, Long> metrics = scannerContext.getMetrics().getMetricsMap();<a name="line.3318"></a>
-<span class="sourceLineNo">3319</span> ScanMetrics.Builder metricBuilder = ScanMetrics.newBuilder();<a name="line.3319"></a>
-<span class="sourceLineNo">3320</span> NameInt64Pair.Builder pairBuilder = NameInt64Pair.newBuilder();<a name="line.3320"></a>
-<span class="sourceLineNo">3321</span><a name="line.3321"></a>
-<span class="sourceLineNo">3322</span> for (Entry<String, Long> entry : metrics.entrySet()) {<a name="line.3322"></a>
-<span class="sourceLineNo">3323</span> pairBuilder.setName(entry.getKey());<a name="line.3323"></a>
-<span class="sourceLineNo">3324</span> pairBuilder.setValue(entry.getValue());<a name="line.3324"></a>
-<span class="sourceLineNo">3325</span> metricBuilder.addMetrics(pairBuilder.build());<a name="line.3325"></a>
-<span class="sourceLineNo">3326</span> }<a name="line.3326"></a>
-<span class="sourceLineNo">3327</span><a name="line.3327"></a>
-<span class="sourceLineNo">3328</span> builder.setScanMetrics(metricBuilder.build());<a name="line.3328"></a>
-<span class="sourceLineNo">3329</span> }<a name="line.3329"></a>
-<span class="sourceLineNo">3330</span> }<a name="line.3330"></a>
-<span class="sourceLineNo">3331</span> long end = EnvironmentEdgeManager.currentTime();<a name="line.3331"></a>
-<span class="sourceLineNo">3332</span> long responseCellSize = context != null ? context.getResponseCellSize() : 0;<a name="line.3332"></a>
-<span class="sourceLineNo">3333</span> region.getMetrics().updateScanTime(end - before);<a name="line.3333"></a>
-<span class="sourceLineNo">3334</span> if (regionServer.metricsRegionServer != null) {<a name="line.3334"></a>
-<span class="sourceLineNo">3335</span> regionServer.metricsRegionServer.updateScanSize(<a name="line.3335"></a>
-<span class="sourceLineNo">3336</span> region.getTableDescriptor().getTableName(), responseCellSize);<a name="line.3336"></a>
-<span class="sourceLineNo">3337</span> regionServer.metricsRegionServer.updateScanTime(<a name="line.3337"></a>
-<span class="sourceLineNo">3338</span> region.getTableDescriptor().getTableName(), end - before);<a name="line.3338"></a>
-<span class="sourceLineNo">3339</span> }<a name="line.3339"></a>
-<span class="sourceLineNo">3340</span> } finally {<a name="line.3340"></a>
-<span class="sourceLineNo">3341</span> region.closeRegionOperation();<a name="line.3341"></a>
-<span class="sourceLineNo">3342</span> }<a name="line.3342"></a>
-<span class="sourceLineNo">3343</span> // coprocessor postNext hook<a name="line.3343"></a>
-<span class="sourceLineNo">3344</span> if (region.getCoprocessorHost() != null) {<a name="line.3344"></a>
-<span class="sourceLineNo">3345</span> region.getCoprocessorHost().postScannerNext(scanner, results, maxResults, true);<a name="line.3345"></a>
-<span class="sourceLineNo">3346</span> }<a name="line.3346"></a>
-<span class="sourceLineNo">3347</span> }<a name="line.3347"></a>
-<span class="sourceLineNo">3348</span><a name="line.3348"></a>
-<span class="sourceLineNo">3349</span> /**<a name="line.3349"></a>
-<span class="sourceLineNo">3350</span> * Scan data in a table.<a name="line.3350"></a>
-<span class="sourceLineNo">3351</span> *<a name="line.3351"></a>
-<span class="sourceLineNo">3352</span> * @param controller the RPC controller<a name="line.3352"></a>
-<span class="sourceLineNo">3353</span> * @param request the scan request<a name="line.3353"></a>
-<span class="sourceLineNo">3354</span> * @throws ServiceException<a name="line.3354"></a>
-<span class="sourceLineNo">3355</span> */<a name="line.3355"></a>
-<span class="sourceLineNo">3356</span> @Override<a name="line.3356"></a>
-<span class="sourceLineNo">3357</span> public ScanResponse scan(final RpcController controller, final ScanRequest request)<a name="line.3357"></a>
-<span class="sourceLineNo">3358</span> throws ServiceException {<a name="line.3358"></a>
-<span class="sourceLineNo">3359</span> if (controller != null && !(controller instanceof HBaseRpcController)) {<a name="line.3359"></a>
-<span class="sourceLineNo">3360</span> throw new UnsupportedOperationException(<a name="line.3360"></a>
-<span class="sourceLineNo">3361</span> "We only do " + "HBaseRpcControllers! FIX IF A PROBLEM: " + controller);<a name="line.3361"></a>
-<span class="sourceLineNo">3362</span> }<a name="line.3362"></a>
-<span class="sourceLineNo">3363</span> if (!request.hasScannerId() && !request.hasScan()) {<a name="line.3363"></a>
-<span class="sourceLineNo">3364</span> throw new ServiceException(<a name="line.3364"></a>
-<span class="sourceLineNo">3365</span> new DoNotRetryIOException("Missing required input: scannerId or scan"));<a name="line.3365"></a>
-<span class="sourceLineNo">3366</span> }<a name="line.3366"></a>
-<span class="sourceLineNo">3367</span> try {<a name="line.3367"></a>
-<span class="sourceLineNo">3368</span> checkOpen();<a name="line.3368"></a>
-<span class="sourceLineNo">3369</span> } catch (IOException e) {<a name="line.3369"></a>
-<span class="sourceLineNo">3370</span> if (request.hasScannerId()) {<a name="line.3370"></a>
-<span class="sourceLineNo">3371</span> String scannerName = Long.toString(request.getScannerId());<a name="line.3371"></a>
-<span class="sourceLineNo">3372</span> if (LOG.isDebugEnabled()) {<a name="line.3372"></a>
-<span class="sourceLineNo">3373</span> LOG.debug(<a name="line.3373"></a>
-<span class="sourceLineNo">3374</span> "Server shutting down and client tried to access missing scanner " + scannerName);<a name="line.3374"></a>
-<span class="sourceLineNo">3375</span> }<a name="line.3375"></a>
-<span class="sourceLineNo">3376</span> if (regionServer.leases != null) {<a name="line.3376"></a>
-<span class="sourceLineNo">3377</span> try {<a name="line.3377"></a>
-<span class="sourceLineNo">3378</span> regionServer.leases.cancelLease(scannerName);<a name="line.3378"></a>
-<span class="sourceLineNo">3379</span> } catch (LeaseException le) {<a name="line.3379"></a>
-<span class="sourceLineNo">3380</span> // No problem, ignore<a name="line.3380"></a>
-<span class="sourceLineNo">3381</span> if (LOG.isTraceEnabled()) {<a name="line.3381"></a>
-<span class="sourceLineNo">3382</span> LOG.trace("Un-able to cancel lease of scanner. It could already be closed.");<a name="line.3382"></a>
-<span class="sourceLineNo">3383</span> }<a name="line.3383"></a>
-<span class="sourceLineNo">3384</span> }<a name="line.3384"></a>
-<span class="sourceLineNo">3385</span> }<a name="line.3385"></a>
-<span class="sourceLineNo">3386</span> }<a name="line.3386"></a>
-<span class="sourceLineNo">3387</span> throw new ServiceException(e);<a name="line.3387"></a>
-<span class="sourceLineNo">3388</span> }<a name="line.3388"></a>
-<span class="sourceLineNo">3389</span> requestCount.increment();<a name="line.3389"></a>
-<span class="sourceLineNo">3390</span> rpcScanRequestCount.increment();<a name="line.3390"></a>
-<span class="sourceLineNo">3391</span> RegionScannerHolder rsh;<a name="line.3391"></a>
-<span class="sourceLineNo">3392</span> ScanResponse.Builder builder = ScanResponse.newBuilder();<a name="line.3392"></a>
-<span class="sourceLineNo">3393</span> try {<a name="line.3393"></a>
-<span class="sourceLineNo">3394</span> if (request.hasScannerId()) {<a name="line.3394"></a>
-<span class="sourceLineNo">3395</span> // The downstream projects such as AsyncHBase in OpenTSDB need this value. See HBASE-18000<a name="line.3395"></a>
-<span class="sourceLineNo">3396</span> // for more details.<a name="line.3396"></a>
-<span class="sourceLineNo">3397</span> builder.setScannerId(request.getScannerId());<a name="line.3397"></a>
-<span class="sourceLineNo">3398</span> rsh = getRegionScanner(request);<a name="line.3398"></a>
-<span class="sourceLineNo">3399</span> } else {<a name="line.3399"></a>
-<span class="sourceLineNo">3400</span> rsh = newRegionScanner(request, builder);<a name="line.3400"></a>
-<span class="sourceLineNo">3401</span> }<a name="line.3401"></a>
-<span class="sourceLineNo">3402</span> } catch (IOException e) {<a name="line.3402"></a>
-<span class="sourceLineNo">3403</span> if (e == SCANNER_ALREADY_CLOSED) {<a name="line.3403"></a>
-<span class="sourceLineNo">3404</span> // Now we will close scanner automatically if there are no more results for this region but<a name="line.3404"></a>
-<span class="sourceLineNo">3405</span> // the old client will still send a close request to us. Just ignore it and return.<a name="line.3405"></a>
-<span class="sourceLineNo">3406</span> return builder.build();<a name="line.3406"></a>
-<span class="sourceLineNo">3407</span> }<a name="line.3407"></a>
-<span class="sourceLineNo">3408</span> throw new ServiceException(e);<a name="line.3408"></a>
-<span class="sourceLineNo">3409</span> }<a name="line.3409"></a>
-<span class="sourceLineNo">3410</span> HRegion region = rsh.r;<a name="line.3410"></a>
-<span class="sourceLineNo">3411</span> String scannerName = rsh.scannerName;<a name="line.3411"></a>
-<span class="sourceLineNo">3412</span> Leases.Lease lease;<a name="line.3412"></a>
-<span class="sourceLineNo">3413</span> try {<a name="line.3413"></a>
-<span class="sourceLineNo">3414</span> // Remove lease while its being processed in server; protects against case<a name="line.3414"></a>
-<span class="sourceLineNo">3415</span> // where processing of request takes > lease expiration time.<a name="line.3415"></a>
-<span class="sourceLineNo">3416</span> lease = regionServer.leases.removeLease(scannerName);<a name="line.3416"></a>
-<span class="sourceLineNo">3417</span> } catch (LeaseException e) {<a name="line.3417"></a>
-<span class="sourceLineNo">3418</span> throw new ServiceException(e);<a name="line.3418"></a>
-<span class="sourceLineNo">3419</span> }<a name="line.3419"></a>
-<span class="sourceLineNo">3420</span> if (request.hasRenew() && request.getRenew()) {<a name="line.3420"></a>
-<span class="sourceLineNo">3421</span> // add back and return<a name="line.3421"></a>
-<span class="sourceLineNo">3422</span> addScannerLeaseBack(lease);<a name="line.3422"></a>
-<span class="sourceLineNo">3423</span> try {<a name="line.3423"></a>
-<span class="sourceLineNo">3424</span> checkScanNextCallSeq(request, rsh);<a name="line.3424"></a>
-<span class="sourceLineNo">3425</span> } catch (OutOfOrderScannerNextException e) {<a name="line.3425"></a>
-<span class="sourceLineNo">3426</span> throw new ServiceException(e);<a name="line.3426"></a>
-<span class="sourceLineNo">3427</span> }<a name="line.3427"></a>
-<span class="sourceLineNo">3428</span> return builder.build();<a name="line.3428"></a>
-<span class="sourceLineNo">3429</span> }<a name="line.3429"></a>
-<span class="sourceLineNo">3430</span> OperationQuota quota;<a name="line.3430"></a>
-<span class="sourceLineNo">3431</span> try {<a name="line.3431"></a>
-<span class="sourceLineNo">3432</span> quota = getRpcQuotaManager().checkQuota(region, OperationQuota.OperationType.SCAN);<a name="line.3432"></a>
-<span class="sourceLineNo">3433</span> } catch (IOException e) {<a name="line.3433"></a>
+<span class="sourceLineNo">3285</span> } else if (!moreRows && !results.isEmpty()) {<a name="line.3285"></a>
+<span class="sourceLineNo">3286</span> // No more cells for the scan here, we need to ensure that the mayHaveMoreCellsInRow of<a name="line.3286"></a>
+<span class="sourceLineNo">3287</span> // last result is false. Otherwise it's possible that: the first nextRaw returned<a name="line.3287"></a>
+<span class="sourceLineNo">3288</span> // because BATCH_LIMIT_REACHED (BTW it happen to exhaust all cells of the scan),so the<a name="line.3288"></a>
+<span class="sourceLineNo">3289</span> // last result's mayHaveMoreCellsInRow will be true. while the following nextRaw will<a name="line.3289"></a>
+<span class="sourceLineNo">3290</span> // return with moreRows=false, which means moreResultsInRegion would be false, it will<a name="line.3290"></a>
+<span class="sourceLineNo">3291</span> // be a contradictory state (HBASE-21206).<a name="line.3291"></a>
+<span class="sourceLineNo">3292</span> int lastIdx = results.size() - 1;<a name="line.3292"></a>
+<span class="sourceLineNo">3293</span> Result r = results.get(lastIdx);<a name="line.3293"></a>
+<span class="sourceLineNo">3294</span> if (r.mayHaveMoreCellsInRow()) {<a name="line.3294"></a>
+<span class="sourceLineNo">3295</span> results.set(lastIdx, Result.create(r.rawCells(), r.getExists(), r.isStale(), false));<a name="line.3295"></a>
+<span class="sourceLineNo">3296</span> }<a name="line.3296"></a>
+<span class="sourceLineNo">3297</span> }<a name="line.3297"></a>
+<span class="sourceLineNo">3298</span> boolean sizeLimitReached = scannerContext.checkSizeLimit(LimitScope.BETWEEN_ROWS);<a name="line.3298"></a>
+<span class="sourceLineNo">3299</span> boolean timeLimitReached = scannerContext.checkTimeLimit(LimitScope.BETWEEN_ROWS);<a name="line.3299"></a>
+<span class="sourceLineNo">3300</span> boolean resultsLimitReached = numOfResults >= maxResults;<a name="line.3300"></a>
+<span class="sourceLineNo">3301</span> limitReached = sizeLimitReached || timeLimitReached || resultsLimitReached;<a name="line.3301"></a>
+<span class="sourceLineNo">3302</span><a name="line.3302"></a>
+<span class="sourceLineNo">3303</span> if (limitReached || !moreRows) {<a name="line.3303"></a>
+<span class="sourceLineNo">3304</span> if (LOG.isTraceEnabled()) {<a name="line.3304"></a>
+<span class="sourceLineNo">3305</span> LOG.trace("Done scanning. limitReached: " + limitReached + " moreRows: " + moreRows<a name="line.3305"></a>
+<span class="sourceLineNo">3306</span> + " scannerContext: " + scannerContext);<a name="line.3306"></a>
+<span class="sourceLineNo">3307</span> }<a name="line.3307"></a>
+<span class="sourceLineNo">3308</span> // We only want to mark a ScanResponse as a heartbeat message in the event that<a name="line.3308"></a>
+<span class="sourceLineNo">3309</span> // there are more values to be read server side. If there aren't more values,<a name="line.3309"></a>
+<span class="sourceLineNo">3310</span> // marking it as a heartbeat is wasteful because the client will need to issue<a name="line.3310"></a>
+<span class="sourceLineNo">3311</span> // another ScanRequest only to realize that they already have all the values<a name="line.3311"></a>
+<span class="sourceLineNo">3312</span> if (moreRows && timeLimitReached) {<a name="line.3312"></a>
+<span class="sourceLineNo">3313</span> // Heartbeat messages occur when the time limit has been reached.<a name="line.3313"></a>
+<span class="sourceLineNo">3314</span> builder.setHeartbeatMessage(true);<a name="line.3314"></a>
+<span class="sourceLineNo">3315</span> if (rsh.needCursor) {<a name="line.3315"></a>
+<span class="sourceLineNo">3316</span> Cell cursorCell = scannerContext.getLastPeekedCell();<a name="line.3316"></a>
+<span class="sourceLineNo">3317</span> if (cursorCell != null) {<a name="line.3317"></a>
+<span class="sourceLineNo">3318</span> builder.setCursor(ProtobufUtil.toCursor(cursorCell));<a name="line.3318"></a>
+<span class="sourceLineNo">3319</span> }<a name="line.3319"></a>
+<span class="sourceLineNo">3320</span> }<a name="line.3320"></a>
+<span class="sourceLineNo">3321</span> }<a name="line.3321"></a>
+<span class="sourceLineNo">3322</span> break;<a name="line.3322"></a>
+<span class="sourceLineNo">3323</span> }<a name="line.3323"></a>
+<span class="sourceLineNo">3324</span> values.clear();<a name="line.3324"></a>
+<span class="sourceLineNo">3325</span> }<a name="line.3325"></a>
+<span class="sourceLineNo">3326</span> builder.setMoreResultsInRegion(moreRows);<a name="line.3326"></a>
+<span class="sourceLineNo">3327</span> // Check to see if the client requested that we track metrics server side. If the<a name="line.3327"></a>
+<span class="sourceLineNo">3328</span> // client requested metrics, retrieve the metrics from the scanner context.<a name="line.3328"></a>
+<span class="sourceLineNo">3329</span> if (trackMetrics) {<a name="line.3329"></a>
+<span class="sourceLineNo">3330</span> Map<String, Long> metrics = scannerContext.getMetrics().getMetricsMap();<a name="line.3330"></a>
+<span class="sourceLineNo">3331</span> ScanMetrics.Builder metricBuilder = ScanMetrics.newBuilder();<a name="line.3331"></a>
+<span class="sourceLineNo">3332</span> NameInt64Pair.Builder pairBuilder = NameInt64Pair.newBuilder();<a name="line.3332"></a>
+<span class="sourceLineNo">3333</span><a name="line.3333"></a>
+<span class="sourceLineNo">3334</span> for (Entry<String, Long> entry : metrics.entrySet()) {<a name="line.3334"></a>
+<span class="sourceLineNo">3335</span> pairBuilder.setName(entry.getKey());<a name="line.3335"></a>
+<span class="sourceLineNo">3336</span> pairBuilder.setValue(entry.getValue());<a name="line.3336"></a>
+<span class="sourceLineNo">3337</span> metricBuilder.addMetrics(pairBuilder.build());<a name="line.3337"></a>
+<span class="sourceLineNo">3338</span> }<a name="line.3338"></a>
+<span class="sourceLineNo">3339</span><a name="line.3339"></a>
+<span class="sourceLineNo">3340</span> builder.setScanMetrics(metricBuilder.build());<a name="line.3340"></a>
+<span class="sourceLineNo">3341</span> }<a name="line.3341"></a>
+<span class="sourceLineNo">3342</span> }<a name="line.3342"></a>
+<span class="sourceLineNo">3343</span> long end = EnvironmentEdgeManager.currentTime();<a name="line.3343"></a>
+<span class="sourceLineNo">3344</span> long responseCellSize = context != null ? context.getResponseCellSize() : 0;<a name="line.3344"></a>
+<span class="sourceLineNo">3345</span> region.getMetrics().updateScanTime(end - before);<a name="line.3345"></a>
+<span class="sourceLineNo">3346</span> if (regionServer.metricsRegionServer != null) {<a name="line.3346"></a>
+<span class="sourceLineNo">3347</span> regionServer.metricsRegionServer.updateScanSize(<a name="line.3347"></a>
+<span class="sourceLineNo">3348</span> region.getTableDescriptor().getTableName(), responseCellSize);<a name="line.3348"></a>
+<span class="sourceLineNo">3349</span> regionServer.metricsRegionServer.updateScanTime(<a name="line.3349"></a>
+<span class="sourceLineNo">3350</span> region.getTableDescriptor().getTableName(), end - before);<a name="line.3350"></a>
+<span class="sourceLineNo">3351</span> }<a name="line.3351"></a>
+<span class="sourceLineNo">3352</span> } finally {<a name="line.3352"></a>
+<span class="sourceLineNo">3353</span> region.closeRegionOperation();<a name="line.3353"></a>
+<span class="sourceLineNo">3354</span> }<a name="line.3354"></a>
+<span class="sourceLineNo">3355</span> // coprocessor postNext hook<a name="line.3355"></a>
+<span class="sourceLineNo">3356</span> if (region.getCoprocessorHost() != null) {<a name="line.3356"></a>
+<span class="sourceLineNo">3357</span> region.getCoprocessorHost().postScannerNext(scanner, results, maxResults, true);<a name="line.3357"></a>
+<span class="sourceLineNo">3358</span> }<a name="line.3358"></a>
+<span class="sourceLineNo">3359</span> }<a name="line.3359"></a>
+<span class="sourceLineNo">3360</span><a name="line.3360"></a>
+<span class="sourceLineNo">3361</span> /**<a name="line.3361"></a>
+<span class="sourceLineNo">3362</span> * Scan data in a table.<a name="line.3362"></a>
+<span class="sourceLineNo">3363</span> *<a name="line.3363"></a>
+<span class="sourceLineNo">3364</span> * @param controller the RPC controller<a name="line.3364"></a>
+<span class="sourceLineNo">3365</span> * @param request the scan request<a name="line.3365"></a>
+<span class="sourceLineNo">3366</span> * @throws ServiceException<a name="line.3366"></a>
+<span class="sourceLineNo">3367</span> */<a name="line.3367"></a>
+<span class="sourceLineNo">3368</span> @Override<a name="line.3368"></a>
+<span class="sourceLineNo">3369</span> public ScanResponse scan(final RpcController controller, final ScanRequest request)<a name="line.3369"></a>
+<span class="sourceLineNo">3370</span> throws ServiceException {<a name="line.3370"></a>
+<span class="sourceLineNo">3371</span> if (controller != null && !(controller instanceof HBaseRpcController)) {<a name="line.3371"></a>
+<span class="sourceLineNo">3372</span> throw new UnsupportedOperationException(<a name="line.3372"></a>
+<span class="sourceLineNo">3373</span> "We only do " + "HBaseRpcControllers! FIX IF A PROBLEM: " + controller);<a name="line.3373"></a>
+<span class="sourceLineNo">3374</span> }<a name="line.3374"></a>
+<span class="sourceLineNo">3375</span> if (!request.hasScannerId() && !request.hasScan()) {<a name="line.3375"></a>
+<span class="sourceLineNo">3376</span> throw new ServiceException(<a name="line.3376"></a>
+<span class="sourceLineNo">3377</span> new DoNotRetryIOException("Missing required input: scannerId or scan"));<a name="line.3377"></a>
+<span class="sourceLineNo">3378</span> }<a name="line.3378"></a>
+<span class="sourceLineNo">3379</span> try {<a name="line.3379"></a>
+<span class="sourceLineNo">3380</span> checkOpen();<a name="line.3380"></a>
+<span class="sourceLineNo">3381</span> } catch (IOException e) {<a name="line.3381"></a>
+<span class="sourceLineNo">3382</span> if (request.hasScannerId()) {<a name="line.3382"></a>
+<span class="sourceLineNo">3383</span> String scannerName = Long.toString(request.getScannerId());<a name="line.3383"></a>
+<span class="sourceLineNo">3384</span> if (LOG.isDebugEnabled()) {<a name="line.3384"></a>
+<span class="sourceLineNo">3385</span> LOG.debug(<a name="line.3385"></a>
+<span class="sourceLineNo">3386</span> "Server shutting down and client tried to access missing scanner " + scannerName);<a name="line.3386"></a>
+<span class="sourceLineNo">3387</span> }<a name="line.3387"></a>
+<span class="sourceLineNo">3388</span> if (regionServer.leases != null) {<a name="line.3388"></a>
+<span class="sourceLineNo">3389</span> try {<a name="line.3389"></a>
+<span class="sourceLineNo">3390</span> regionServer.leases.cancelLease(scannerName);<a name="line.3390"></a>
+<span class="sourceLineNo">3391</span> } catch (LeaseException le) {<a name="line.3391"></a>
+<span class="sourceLineNo">3392</span> // No problem, ignore<a name="line.3392"></a>
+<span class="sourceLineNo">3393</span> if (LOG.isTraceEnabled()) {<a name="line.3393"></a>
+<span class="sourceLineNo">3394</span> LOG.trace("Un-able to cancel lease of scanner. It could already be closed.");<a name="line.3394"></a>
+<span class="sourceLineNo">3395</span> }<a name="line.3395"></a>
+<span class="sourceLineNo">3396</span> }<a name="line.3396"></a>
+<span class="sourceLineNo">3397</span> }<a name="line.3397"></a>
+<span class="sourceLineNo">3398</span> }<a name="line.3398"></a>
+<span class="sourceLineNo">3399</span> throw new ServiceException(e);<a name="line.3399"></a>
+<span class="sourceLineNo">3400</span> }<a name="line.3400"></a>
+<span class="sourceLineNo">3401</span> requestCount.increment();<a name="line.3401"></a>
+<span class="sourceLineNo">3402</span> rpcScanRequestCount.increment();<a name="line.3402"></a>
+<span class="sourceLineNo">3403</span> RegionScannerHolder rsh;<a name="line.3403"></a>
+<span class="sourceLineNo">3404</span> ScanResponse.Builder builder = ScanResponse.newBuilder();<a name="line.3404"></a>
+<span class="sourceLineNo">3405</span> try {<a name="line.3405"></a>
+<span class="sourceLineNo">3406</span> if (request.hasScannerId()) {<a name="line.3406"></a>
+<span class="sourceLineNo">3407</span> // The downstream projects such as AsyncHBase in OpenTSDB need this value. See HBASE-18000<a name="line.3407"></a>
+<span class="sourceLineNo">3408</span> // for more details.<a name="line.3408"></a>
+<span class="sourceLineNo">3409</span> builder.setScannerId(request.getScannerId());<a name="line.3409"></a>
+<span class="sourceLineNo">3410</span> rsh = getRegionScanner(request);<a name="line.3410"></a>
+<span class="sourceLineNo">3411</span> } else {<a name="line.3411"></a>
+<span class="sourceLineNo">3412</span> rsh = newRegionScanner(request, builder);<a name="line.3412"></a>
+<span class="sourceLineNo">3413</span> }<a name="line.3413"></a>
+<span class="sourceLineNo">3414</span> } catch (IOException e) {<a name="line.3414"></a>
+<span class="sourceLineNo">3415</span> if (e == SCANNER_ALREADY_CLOSED) {<a name="line.3415"></a>
+<span class="sourceLineNo">3416</span> // Now we will close scanner automatically if there are no more results for this region but<a name="line.3416"></a>
+<span class="sourceLineNo">3417</span> // the old client will still send a close request to us. Just ignore it and return.<a name="line.3417"></a>
+<span class="sourceLineNo">3418</span> return builder.build();<a name="line.3418"></a>
+<span class="sourceLineNo">3419</span> }<a name="line.3419"></a>
+<span class="sourceLineNo">3420</span> throw new ServiceException(e);<a name="line.3420"></a>
+<span class="sourceLineNo">3421</span> }<a name="line.3421"></a>
+<span class="sourceLineNo">3422</span> HRegion region = rsh.r;<a name="line.3422"></a>
+<span class="sourceLineNo">3423</span> String scannerName = rsh.scannerName;<a name="line.3423"></a>
+<span class="sourceLineNo">3424</span> Leases.Lease lease;<a name="line.3424"></a>
+<span class="sourceLineNo">3425</span> try {<a name="line.3425"></a>
+<span class="sourceLineNo">3426</span> // Remove lease while its being processed in server; protects against case<a name="line.3426"></a>
+<span class="sourceLineNo">3427</span> // where processing of request takes > lease expiration time.<a name="line.3427"></a>
+<span class="sourceLineNo">3428</span> lease = regionServer.leases.removeLease(scannerName);<a name="line.3428"></a>
+<span class="sourceLineNo">3429</span> } catch (LeaseException e) {<a name="line.3429"></a>
+<span class="sourceLineNo">3430</span> throw new ServiceException(e);<a name="line.3430"></a>
+<span class="sourceLineNo">3431</span> }<a name="line.3431"></a>
+<span class="sourceLineNo">3432</span> if (request.hasRenew() && request.getRenew()) {<a name="line.3432"></a>
+<span class="sourceLineNo">3433</span> // add back and return<a name="line.3433"></a>
<span class="sourceLineNo">3434</span> addScannerLeaseBack(lease);<a name="line.3434"></a>
-<span class="sourceLineNo">3435</span> throw new ServiceException(e);<a name="line.3435"></a>
-<span class="sourceLineNo">3436</span> }<a name="line.3436"></a>
-<span class="sourceLineNo">3437</span> try {<a name="line.3437"></a>
-<span class="sourceLineNo">3438</span> checkScanNextCallSeq(request, rsh);<a name="line.3438"></a>
-<span class="sourceLineNo">3439</span> } catch (OutOfOrderScannerNextException e) {<a name="line.3439"></a>
-<span class="sourceLineNo">3440</span> addScannerLeaseBack(lease);<a name="line.3440"></a>
-<span class="sourceLineNo">3441</span> throw new ServiceException(e);<a name="line.3441"></a>
-<span class="sourceLineNo">3442</span> }<a name="line.3442"></a>
-<span class="sourceLineNo">3443</span> // Now we have increased the next call sequence. If we give client an error, the retry will<a name="line.3443"></a>
-<span class="sourceLineNo">3444</span> // never success. So we'd better close the scanner and return a DoNotRetryIOException to client<a name="line.3444"></a>
-<span class="sourceLineNo">3445</span> // and then client will try to open a new scanner.<a name="line.3445"></a>
-<span class="sourceLineNo">3446</span> boolean closeScanner = request.hasCloseScanner() ? request.getCloseScanner() : false;<a name="line.3446"></a>
-<span class="sourceLineNo">3447</span> int rows; // this is scan.getCaching<a name="line.3447"></a>
-<span class="sourceLineNo">3448</span> if (request.hasNumberOfRows()) {<a name="line.3448"></a>
-<span class="sourceLineNo">3449</span> rows = request.getNumberOfRows();<a name="line.3449"></a>
-<span class="sourceLineNo">3450</span> } else {<a name="line.3450"></a>
-<span class="sourceLineNo">3451</span> rows = closeScanner ? 0 : 1;<a name="line.3451"></a>
-<span class="sourceLineNo">3452</span> }<a name="line.3452"></a>
-<span class="sourceLineNo">3453</span> RpcCallContext context = RpcServer.getCurrentCall().orElse(null);<a name="line.3453"></a>
-<span class="sourceLineNo">3454</span> // now let's do the real scan.<a name="line.3454"></a>
-<span class="sourceLineNo">3455</span> long maxQuotaResultSize = Math.min(maxScannerResultSize, quota.getReadAvailable());<a name="line.3455"></a>
-<span class="sourceLineNo">3456</span> RegionScanner scanner = rsh.s;<a name="line.3456"></a>
-<span class="sourceLineNo">3457</span> // this is the limit of rows for this scan, if we the number of rows reach this value, we will<a name="line.3457"></a>
-<span class="sourceLineNo">3458</span> // close the scanner.<a name="line.3458"></a>
-<span class="sourceLineNo">3459</span> int limitOfRows;<a name="line.3459"></a>
-<span class="sourceLineNo">3460</span> if (request.hasLimitOfRows()) {<a name="line.3460"></a>
-<span class="sourceLineNo">3461</span> limitOfRows = request.getLimitOfRows();<a name="line.3461"></a>
+<span class="sourceLineNo">3435</span> try {<a name="line.3435"></a>
+<span class="sourceLineNo">3436</span> checkScanNextCallSeq(request, rsh);<a name="line.3436"></a>
+<span class="sourceLineNo">3437</span> } catch (OutOfOrderScannerNextException e) {<a name="line.3437"></a>
+<span class="sourceLineNo">3438</span> throw new ServiceException(e);<a name="line.3438"></a>
+<span class="sourceLineNo">3439</span> }<a name="line.3439"></a>
+<span class="sourceLineNo">3440</span> return builder.build();<a name="line.3440"></a>
+<span class="sourceLineNo">3441</span> }<a name="line.3441"></a>
+<span class="sourceLineNo">3442</span> OperationQuota quota;<a name="line.3442"></a>
+<span class="sourceLineNo">3443</span> try {<a name="line.3443"></a>
+<span class="sourceLineNo">3444</span> quota = getRpcQuotaManager().checkQuota(region, OperationQuota.OperationType.SCAN);<a name="line.3444"></a>
+<span class="sourceLineNo">3445</span> } catch (IOException e) {<a name="line.3445"></a>
+<span class="sourceLineNo">3446</span> addScannerLeaseBack(lease);<a name="line.3446"></a>
+<span class="sourceLineNo">3447</span> throw new ServiceException(e);<a name="line.3447"></a>
+<span class="sourceLineNo">3448</span> }<a name="line.3448"></a>
+<span class="sourceLineNo">3449</span> try {<a name="line.3449"></a>
+<span class="sourceLineNo">3450</span> checkScanNextCallSeq(request, rsh);<a name="line.3450"></a>
+<span class="sourceLineNo">3451</span> } catch (OutOfOrderScannerNextException e) {<a name="line.3451"></a>
+<span class="sourceLineNo">3452</span> addScannerLeaseBack(lease);<a name="line.3452"></a>
+<span class="sourceLineNo">3453</span> throw new ServiceException(e);<a name="line.3453"></a>
+<span class="sourceLineNo">3454</span> }<a name="line.3454"></a>
+<span class="sourceLineNo">3455</span> // Now we have increased the next call sequence. If we give client an error, the retry will<a name="line.3455"></a>
+<span class="sourceLineNo">3456</span> // never success. So we'd better close the scanner and return a DoNotRetryIOException to client<a name="line.3456"></a>
+<span class="sourceLineNo">3457</span> // and then client will try to open a new scanner.<a name="line.3457"></a>
+<span class="sourceLineNo">3458</span> boolean closeScanner = request.hasCloseScanner() ? request.getCloseScanner() : false;<a name="line.3458"></a>
+<span class="sourceLineNo">3459</span> int rows; // this is scan.getCaching<a name="line.3459"></a>
+<span class="sourceLineNo">3460</span> if (request.hasNumberOfRows()) {<a name="line.3460"></a>
+<span class="sourceLineNo">3461</span> rows = request.getNumberOfRows();<a name="line.3461"></a>
<span class="sourceLineNo">3462</span> } else {<a name="line.3462"></a>
-<span class="sourceLineNo">3463</span> limitOfRows = -1;<a name="line.3463"></a>
+<span class="sourceLineNo">3463</span> rows = closeScanner ? 0 : 1;<a name="line.3463"></a>
<span class="sourceLineNo">3464</span> }<a name="line.3464"></a>
-<span class="sourceLineNo">3465</span> MutableObject<Object> lastBlock = new MutableObject<>();<a name="line.3465"></a>
-<span class="sourceLineNo">3466</span> boolean scannerClosed = false;<a name="line.3466"></a>
-<span class="sourceLineNo">3467</span> try {<a name="line.3467"></a>
-<span class="sourceLineNo">3468</span> List<Result> results = new ArrayList<>();<a name="line.3468"></a>
-<span class="sourceLineNo">3469</span> if (rows > 0) {<a name="line.3469"></a>
-<span class="sourceLineNo">3470</span> boolean done = false;<a name="line.3470"></a>
-<span class="sourceLineNo">3471</span> // Call coprocessor. Get region info from scanner.<a name="line.3471"></a>
-<span class="sourceLineNo">3472</span> if (region.getCoprocessorHost() != null) {<a name="line.3472"></a>
-<span class="sourceLineNo">3473</span> Boolean bypass = region.getCoprocessorHost().preScannerNext(scanner, results, rows);<a name="line.3473"></a>
-<span class="sourceLineNo">3474</span> if (!results.isEmpty()) {<a name="line.3474"></a>
-<span class="sourceLineNo">3475</span> for (Result r : results) {<a name="line.3475"></a>
-<span class="sourceLineNo">3476</span> lastBlock.setValue(addSize(context, r, lastBlock.getValue()));<a name="line.3476"></a>
-<span class="sourceLineNo">3477</span> }<a name="line.3477"></a>
-<span class="sourceLineNo">3478</span> }<a name="line.3478"></a>
-<span class="sourceLineNo">3479</span> if (bypass != null && bypass.booleanValue()) {<a name="line.3479"></a>
-<span class="sourceLineNo">3480</span> done = true;<a name="line.3480"></a>
-<span class="sourceLineNo">3481</span> }<a name="line.3481"></a>
-<span class="sourceLineNo">3482</span> }<a name="line.3482"></a>
-<span class="sourceLineNo">3483</span> if (!done) {<a name="line.3483"></a>
-<span class="sourceLineNo">3484</span> scan((HBaseRpcController) controller, request, rsh, maxQuotaResultSize, rows, limitOfRows,<a name="line.3484"></a>
-<span class="sourceLineNo">3485</span> results, builder, lastBlock, context);<a name="line.3485"></a>
-<span class="sourceLineNo">3486</span> } else {<a name="line.3486"></a>
-<span class="sourceLineNo">3487</span> builder.setMoreResultsInRegion(!results.isEmpty());<a name="line.3487"></a>
-<span class="sourceLineNo">3488</span> }<a name="line.3488"></a>
-<span class="sourceLineNo">3489</span> } else {<a name="line.3489"></a>
-<span class="sourceLineNo">3490</span> // This is a open scanner call with numberOfRow = 0, so set more results in region to true.<a name="line.3490"></a>
-<span class="sourceLineNo">3491</span> builder.setMoreResultsInRegion(true);<a name="line.3491"></a>
-<span class="sourceLineNo">3492</span> }<a name="line.3492"></a>
-<span class="sourceLineNo">3493</span><a name="line.3493"></a>
-<span class="sourceLineNo">3494</span> quota.addScanResult(results);<a name="line.3494"></a>
-<span class="sourceLineNo">3495</span> addResults(builder, results, (HBaseRpcController) controller,<a name="line.3495"></a>
-<span class="sourceLineNo">3496</span> RegionReplicaUtil.isDefaultReplica(region.getRegionInfo()),<a name="line.3496"></a>
-<span class="sourceLineNo">3497</span> isClientCellBlockSupport(context));<a name="line.3497"></a>
-<span class="sourceLineNo">3498</span> if (scanner.isFilterDone() && results.isEmpty()) {<a name="line.3498"></a>
-<span class="sourceLineNo">3499</span> // If the scanner's filter - if any - is done with the scan<a name="line.3499"></a>
-<span class="sourceLineNo">3500</span> // only set moreResults to false if the results is empty. This is used to keep compatible<a name="line.3500"></a>
-<span class="sourceLineNo">3501</span> // with the old scan implementation where we just ignore the returned results if moreResults<a name="line.3501"></a>
-<span class="sourceLineNo">3502</span> // is false. Can remove the isEmpty check after we get rid of the old implementation.<a name="line.3502"></a>
-<span class="sourceLineNo">3503</span> builder.setMoreResults(false);<a name="line.3503"></a>
+<span class="sourceLineNo">3465</span> RpcCallContext context = RpcServer.getCurrentCall().orElse(null);<a name="line.3465"></a>
+<span class="sourceLineNo">3466</span> // now let's do the real scan.<a name="line.3466"></a>
+<span class="sourceLineNo">3467</span> long maxQuotaResultSize = Math.min(maxScannerResultSize, quota.getReadAvailable());<a name="line.3467"></a>
+<span class="sourceLineNo">3468</span> RegionScanner scanner = rsh.s;<a name="line.3468"></a>
+<span class="sourceLineNo">3469</span> // this is the limit of rows for this scan, if we the number of rows reach this value, we will<a name="line.3469"></a>
+<span class="sourceLineNo">3470</span> // close the scanner.<a name="line.3470"></a>
+<span class="sourceLineNo">3471</span> int limitOfRows;<a name="line.3471"></a>
+<span class="sourceLineNo">3472</span> if (request.hasLimitOfRows()) {<a name="line.3472"></a>
+<span class="sourceLineNo">3473</span> limitOfRows = request.getLimitOfRows();<a name="line.3473"></a>
+<span class="sourceLineNo">3474</span> } else {<a name="line.3474"></a>
+<span class="sourceLineNo">3475</span> limitOfRows = -1;<a name="line.3475"></a>
+<span class="sourceLineNo">3476</span> }<a name="line.3476"></a>
+<span class="sourceLineNo">3477</span> MutableObject<Object> lastBlock = new MutableObject<>();<a name="line.3477"></a>
+<span class="sourceLineNo">3478</span> boolean scannerClosed = false;<a name="line.3478"></a>
+<span class="sourceLineNo">3479</span> try {<a name="line.3479"></a>
+<span class="sourceLineNo">3480</span> List<Result> results = new ArrayList<>();<a name="line.3480"></a>
+<span class="sourceLineNo">3481</span> if (rows > 0) {<a name="line.3481"></a>
+<span class="sourceLineNo">3482</span> boolean done = false;<a name="line.3482"></a>
+<span class="sourceLineNo">3483</span> // Call coprocessor. Get region info from scanner.<a name="line.3483"></a>
+<span class="sourceLineNo">3484</span> if (region.getCoprocessorHost() != null) {<a name="line.3484"></a>
+<span class="sourceLineNo">3485</span> Boolean bypass = region.getCoprocessorHost().preScannerNext(scanner, results, rows);<a name="line.3485"></a>
+<span class="sourceLineNo">3486</span> if (!results.isEmpty()) {<a name="line.3486"></a>
+<span class="sourceLineNo">3487</span> for (Result r : results) {<a name="line.3487"></a>
+<span class="sourceLineNo">3488</span> lastBlock.setValue(addSize(context, r, lastBlock.getValue()));<a name="line.3488"></a>
+<span class="sourceLineNo">3489</span> }<a name="line.3489"></a>
+<span class="sourceLineNo">3490</span> }<a name="line.3490"></a>
+<span class="sourceLineNo">3491</span> if (bypass != null && bypass.booleanValue()) {<a name="line.3491"></a>
+<span class="sourceLineNo">3492</span> done = true;<a name="line.3492"></a>
+<span class="sourceLineNo">3493</span> }<a name="line.3493"></a>
+<span class="sourceLineNo">3494</span> }<a name="line.3494"></a>
+<span class="sourceLineNo">3495</span> if (!done) {<a name="line.3495"></a>
+<span class="sourceLineNo">3496</span> scan((HBaseRpcController) controller, request, rsh, maxQuotaResultSize, rows, limitOfRows,<a name="line.3496"></a>
+<span class="sourceLineNo">3497</span> results, builder, lastBlock, context);<a name="line.3497"></a>
+<span class="sourceLineNo">3498</span> } else {<a name="line.3498"></a>
+<span class="sourceLineNo">3499</span> builder.setMoreResultsInRegion(!results.isEmpty());<a name="line.3499"></a>
+<span class="sourceLineNo">3500</span> }<a name="line.3500"></a>
+<span class="sourceLineNo">3501</span> } else {<a name="line.3501"></a>
+<span class="sourceLineNo">3502</span> // This is a open scanner call with numberOfRow = 0, so set more results in region to true.<a name="line.3502"></a>
+<span class="sourceLineNo">3503</span> builder.setMoreResultsInRegion(true);<a name="line.3503"></a>
<span class="sourceLineNo">3504</span> }<a name="line.3504"></a>
-<span class="sourceLineNo">3505</span> // Later we may close the scanner depending on this flag so here we need to make sure that we<a name="line.3505"></a>
-<span class="sourceLineNo">3506</span> // have already set this flag.<a name="line.3506"></a>
-<span class="sourceLineNo">3507</span> assert builder.hasMoreResultsInRegion();<a name="line.3507"></a>
-<span class="sourceLineNo">3508</span> // we only set moreResults to false in the above code, so set it to true if we haven't set it<a name="line.3508"></a>
-<span class="sourceLineNo">3509</span> // yet.<a name="line.3509"></a>
-<span class="sourceLineNo">3510</span> if (!builder.hasMoreResults()) {<a name="line.3510"></a>
-<span class="sourceLineNo">3511</span> builder.setMoreResults(true);<a name="line.3511"></a>
-<span class="sourceLineNo">3512</span> }<a name="line.3512"></a>
-<span class="sourceLineNo">3513</span> if (builder.getMoreResults() && builder.getMoreResultsInRegion() && !results.isEmpty()) {<a name="line.3513"></a>
-<span class="sourceLineNo">3514</span> // Record the last cell of the last result if it is a partial result<a name="line.3514"></a>
-<span class="sourceLineNo">3515</span> // We need this to calculate the complete rows we have returned to client as the<a name="line.3515"></a>
-<span class="sourceLineNo">3516</span> // mayHaveMoreCellsInRow is true does not mean that there will be extra cells for the<a name="line.3516"></a>
-<span class="sourceLineNo">3517</span> // current row. We may filter out all the remaining cells for the current row and just<a name="line.3517"></a>
-<span class="sourceLineNo">3518</span> // return the cells of the nextRow when calling RegionScanner.nextRaw. So here we need to<a name="line.3518"></a>
-<span class="sourceLineNo">3519</span> // check for row change.<a name="line.3519"></a>
-<span class="sourceLineNo">3520</span> Result lastResult = results.get(results.size() - 1);<a name="line.3520"></a>
-<span class="sourceLineNo">3521</span> if (lastResult.mayHaveMoreCellsInRow()) {<a name="line.3521"></a>
-<span class="sourceLineNo">3522</span> rsh.rowOfLastPartialResult = lastResult.getRow();<a name="line.3522"></a>
-<span class="sourceLineNo">3523</span> } else {<a name="line.3523"></a>
-<span class="sourceLineNo">3524</span> rsh.rowOfLastPartialResult = null;<a name="line.3524"></a>
-<span class="sourceLineNo">3525</span> }<a name="line.3525"></a>
-<span class="sourceLineNo">3526</span> }<a name="line.3526"></a>
-<span class="sourceLineNo">3527</span> if (!builder.getMoreResults() || !builder.getMoreResultsInRegion() || closeScanner) {<a name="line.3527"></a>
-<span class="sourceLineNo">3528</span> scannerClosed = true;<a name="line.3528"></a>
-<span class="sourceLineNo">3529</span> closeScanner(region, scanner, scannerName, context);<a name="line.3529"></a>
-<span class="sourceLineNo">3530</span> }<a name="line.3530"></a>
-<span class="sourceLineNo">3531</span> return builder.build();<a name="line.3531"></a>
-<span class="sourceLineNo">3532</span> } catch (IOException e) {<a name="line.3532"></a>
-<span class="sourceLineNo">3533</span> try {<a name="line.3533"></a>
-<span class="sourceLineNo">3534</span> // scanner is closed here<a name="line.3534"></a>
-<span class="sourceLineNo">3535</span> scannerClosed = true;<a name="line.3535"></a>
-<span class="sourceLineNo">3536</span> // The scanner state might be left in a dirty state, so we will tell the Client to<a name="line.3536"></a>
-<span class="sourceLineNo">3537</span> // fail this RPC and close the scanner while opening up another one from the start of<a name="line.3537"></a>
-<span class="sourceLineNo">3538</span> // row that the client has last seen.<a name="line.3538"></a>
-<span class="sourceLineNo">3539</span> closeScanner(region, scanner, scannerName, context);<a name="line.3539"></a>
-<span class="sourceLineNo">3540</span><a name="line.3540"></a>
-<span class="sourceLineNo">3541</span> // If it is a DoNotRetryIOException already, throw as it is. Unfortunately, DNRIOE is<a name="line.3541"></a>
-<span class="sourceLineNo">3542</span> // used in two different semantics.<a name="line.3542"></a>
-<span class="sourceLineNo">3543</span> // (1) The first is to close the client scanner and bubble up the exception all the way<a name="line.3543"></a>
-<span class="sourceLineNo">3544</span> // to the application. This is preferred when the exception is really un-recoverable<a name="line.3544"></a>
-<span class="sourceLineNo">3545</span> // (like CorruptHFileException, etc). Plain DoNotRetryIOException also falls into this<a name="line.3545"></a>
-<span class="sourceLineNo">3546</span> // bucket usually.<a name="line.3546"></a>
-<span class="sourceLineNo">3547</span> // (2) Second semantics is to close the current region scanner only, but continue the<a name="line.3547"></a>
-<span class="sourceLineNo">3548</span> // client scanner by overriding the exception. This is usually UnknownScannerException,<a name="line.3548"></a>
-<span class="sourceLineNo">3549</span> // OutOfOrderScannerNextException, etc where the region scanner has to be closed, but the<a name="line.3549"></a>
-<span class="sourceLineNo">3550</span> // application-level ClientScanner has to continue without bubbling up the exception to<a name="line.3550"></a>
-<span class="sourceLineNo">3551</span> // the client. See ClientScanner code to see how it deals with these special exceptions.<a name="line.3551"></a>
-<span class="sourceLineNo">3552</span> if (e instanceof DoNotRetryIOException) {<a name="line.3552"></a>
-<span class="sourceLineNo">3553</span> throw e;<a name="line.3553"></a>
-<span class="sourceLineNo">3554</span> }<a name="line.3554"></a>
-<span class="sourceLineNo">3555</span><a name="line.3555"></a>
-<span class="sourceLineNo">3556</span> // If it is a FileNotFoundException, wrap as a<a name="line.3556"></a>
-<span class="sourceLineNo">3557</span> // DoNotRetryIOException. This can avoid the retry in ClientScanner.<a name="line.3557"></a>
-<span class="sourceLineNo">3558</span> if (e instanceof FileNotFoundException) {<a name="line.3558"></a>
-<span class="sourceLineNo">3559</span> throw new DoNotRetryIOException(e);<a name="line.3559"></a>
-<span class="sourceLineNo">3560</span> }<a name="line.3560"></a>
-<span class="sourceLineNo">3561</span><a name="line.3561"></a>
-<span class="sourceLineNo">3562</span> // We closed the scanner already. Instead of throwing the IOException, and client<a name="line.3562"></a>
-<span class="sourceLineNo">3563</span> // retrying with the same scannerId only to get USE on the next RPC, we directly throw<a name="line.3563"></a>
-<span class="sourceLineNo">3564</span> // a special exception to save an RPC.<a name="line.3564"></a>
-<span class="sourceLineNo">3565</span> if (VersionInfoUtil.hasMinimumVersion(context.getClientVersionInfo(), 1, 4)) {<a name="line.3565"></a>
-<span class="sourceLineNo">3566</span> // 1.4.0+ clients know how to handle<a name="line.3566"></a>
-<span class="sourceLineNo">3567</span> throw new ScannerResetException("Scanner is closed on the server-side", e);<a name="line.3567"></a>
-<span class="sourceLineNo">3568</span> } else {<a name="line.3568"></a>
-<span class="sourceLineNo">3569</span> // older clients do not know about SRE. Just throw USE, which they will handle<a name="line.3569"></a>
-<span class="sourceLineNo">3570</span> throw new UnknownScannerException("Throwing UnknownScannerException to reset the client"<a name="line.3570"></a>
-<span class="sourceLineNo">3571</span> + " scanner state for clients older than 1.3.", e);<a name="line.3571"></a>
+<span class="sourceLineNo">3505</span><a name="line.3505"></a>
+<span class="sourceLineNo">3506</span> quota.addScanResult(results);<a name="line.3506"></a>
+<span class="sourceLineNo">3507</span> addResults(builder, results, (HBaseRpcController) controller,<a name="line.3507"></a>
+<span class="sourceLineNo">3508</span> RegionReplicaUtil.isDefaultReplica(region.getRegionInfo()),<a name="line.3508"></a>
+<span class="sourceLineNo">3509</span> isClientCellBlockSupport(context));<a name="line.3509"></a>
+<span class="sourceLineNo">3510</span> if (scanner.isFilterDone() && results.isEmpty()) {<a name="line.3510"></a>
+<span class="sourceLineNo">3511</span> // If the scanner's filter - if any - is done with the scan<a name="line.3511"></a>
+<span class="sourceLineNo">3512</span> // only set moreResults to false if the results is empty. This is used to keep compatible<a name="line.3512"></a>
+<span class="sourceLineNo">3513</span> // with the old scan implementation where we just ignore the returned results if moreResults<a name="line.3513"></a>
+<span class="sourceLineNo">3514</span> // is false. Can remove the isEmpty check after we get rid of the old implementation.<a name="line.3514"></a>
+<span class="sourceLineNo">3515</span> builder.setMoreResults(false);<a name="line.3515"></a>
+<span class="sourceLineNo">3516</span> }<a name="line.3516"></a>
+<span class="sourceLineNo">3517</span> // Later we may close the scanner depending on this flag so here we need to make sure that we<a name="line.3517"></a>
+<span class="sourceLineNo">3518</span> // have already set this flag.<a name="line.3518"></a>
+<span class="sourceLineNo">3519</span> assert builder.hasMoreResultsInRegion();<a name="line.3519"></a>
+<span class="sourceLineNo">3520</span> // we only set moreResults to false in the above code, so set it to true if we haven't set it<a name="line.3520"></a>
+<span class="sourceLineNo">3521</span> // yet.<a name="line.3521"></a>
+<span class="sourceLineNo">3522</span> if (!builder.hasMoreResults()) {<a name="line.3522"></a>
+<span class="sourceLineNo">3523</span> builder.setMoreResults(true);<a name="line.3523"></a>
+<span class="sourceLineNo">3524</span> }<a name="line.3524"></a>
+<span class="sourceLineNo">3525</span> if (builder.getMoreResults() && builder.getMoreResultsInRegion() && !results.isEmpty()) {<a name="line.3525"></a>
+<span class="sourceLineNo">3526</span> // Record the last cell of the last result if it is a partial result<a name="line.3526"></a>
+<span class="sourceLineNo">3527</span> // We need this to calculate the complete rows we have returned to client as the<a name="line.3527"></a>
+<span class="sourceLineNo">3528</span> // mayHaveMoreCellsInRow is true does not mean that there will be extra cells for the<a name="line.3528"></a>
+<span class="sourceLineNo">3529</span> // current row. We may filter out all the remaining cells for the current row and just<a name="line.3529"></a>
+<span class="sourceLineNo">3530</span> // return the cells of the nextRow when calling RegionScanner.nextRaw. So here we need to<a name="line.3530"></a>
+<span class="sourceLineNo">3531</span> // check for row change.<a name="line.3531"></a>
+<span class="sourceLineNo">3532</span> Result lastResult = results.get(results.size() - 1);<a name="line.3532"></a>
+<span class="sourceLineNo">3533</span> if (lastResult.mayHaveMoreCellsInRow()) {<a name="line.3533"></a>
+<span class="sourceLineNo">3534</span> rsh.rowOfLastPartialResult = lastResult.getRow();<a name="line.3534"></a>
+<span class="sourceLineNo">3535</span> } else {<a name="line.3535"></a>
+<span class="sourceLineNo">3536</span> rsh.rowOfLastPartialResult = null;<a name="line.3536"></a>
+<span class="sourceLineNo">3537</span> }<a name="line.3537"></a>
+<span class="sourceLineNo">3538</span> }<a name="line.3538"></a>
+<span class="sourceLineNo">3539</span> if (!builder.getMoreResults() || !builder.getMoreResultsInRegion() || closeScanner) {<a name="line.3539"></a>
+<span class="sourceLineNo">3540</span> scannerClosed = true;<a name="line.3540"></a>
+<span class="sourceLineNo">3541</span> closeScanner(region, scanner, scannerName, context);<a name="line.3541"></a>
+<span class="sourceLineNo">3542</span> }<a name="line.3542"></a>
+<span class="sourceLineNo">3543</span> return builder.build();<a name="line.3543"></a>
+<span class="sourceLineNo">3544</span> } catch (IOException e) {<a name="line.3544"></a>
+<span class="sourceLineNo">3545</span> try {<a name="line.3545"></a>
+<span class="sourceLineNo">3546</span> // scanner is closed here<a name="line.3546"></a>
+<span class="sourceLineNo">3547</span> scannerClosed = true;<a name="line.3547"></a>
+<span class="sourceLineNo">3548</span> // The scanner state might be left in a dirty state, so we will tell the Client to<a name="line.3548"></a>
+<span class="sourceLineNo">3549</span> // fail this RPC and close the scanner while opening up another one from the start of<a name="line.3549"></a>
+<span class="sourceLineNo">3550</span> // row that the client has last seen.<a name="line.3550"></a>
+<span class="sourceLineNo">3551</span> closeScanner(region, scanner, scannerName, context);<a name="line.3551"></a>
+<span class="sourceLineNo">3552</span><a name="line.3552"></a>
+<span class="sourceLineNo">3553</span> // If it is a DoNotRetryIOException already, throw as it is. Unfortunately, DNRIOE is<a name="line.3553"></a>
+<span class="sourceLineNo">3554</span> // used in two different semantics.<a name="line.3554"></a>
+<span class="sourceLineNo">3555</span> // (1) The first is to close the client scanner and bubble up the exception all the way<a name="line.3555"></a>
+<span class="sourceLineNo">3556</span> // to the application. This is preferred when the exception is really un-recoverable<a name="line.3556"></a>
+<span class="sourceLineNo">3557</span> // (like CorruptHFileException, etc). Plain DoNotRetryIOException also falls into this<a name="line.3557"></a>
+<span class="sourceLineNo">3558</span> // bucket usually.<a name="line.3558"></a>
+<span class="sourceLineNo">3559</span> // (2) Second semantics is to close the current region scanner only, but continue the<a name="line.3559"></a>
+<span class="sourceLineNo">3560</span> // client scanner by overriding the exception. This is usually UnknownScannerException,<a name="line.3560"></a>
+<span class="sourceLineNo">3561</span> // OutOfOrderScannerNextException, etc where the region scanner has to be closed, but the<a name="line.3561"></a>
+<span class="sourceLineNo">3562</span> // application-level ClientScanner has to continue without bubbling up the exception to<a name="line.3562"></a>
+<span class="sourceLineNo">3563</span> // the client. See ClientScanner code to see how it deals with these special exceptions.<a name="line.3563"></a>
+<span class="sourceLineNo">3564</span> if (e instanceof DoNotRetryIOException) {<a name="line.3564"></a>
+<span class="sourceLineNo">3565</span> throw e;<a name="line.3565"></a>
+<span class="sourceLineNo">3566</span> }<a name="line.3566"></a>
+<span class="sourceLineNo">3567</span><a name="line.3567"></a>
+<span class="sourceLineNo">3568</span> // If it is a FileNotFoundException, wrap as a<a name="line.3568"></a>
+<span class="sourceLineNo">3569</span> // DoNotRetryIOException. This can avoid the retry in ClientScanner.<a name="line.3569"></a>
+<span class="sourceLineNo">3570</span> if (e instanceof FileNotFoundException) {<a name="line.3570"></a>
+<span class="sourceLineNo">3571</span> throw new DoNotRetryIOException(e);<a name="line.3571"></a>
<span class="sourceLineNo">3572</span> }<a name="line.3572"></a>
-<span class="sourceLineNo">3573</span> } catch (IOException ioe) {<a name="line.3573"></a>
-<span class="sourceLineNo">3574</span> throw new ServiceException(ioe);<a name="line.3574"></a>
-<span class="sourceLineNo">3575</span> }<a name="line.3575"></a>
-<span class="sourceLineNo">3576</span> } finally {<a name="line.3576"></a>
-<span class="sourceLineNo">3577</span> if (!scannerClosed) {<a name="line.3577"></a>
-<span class="sourceLineNo">3578</span> // Adding resets expiration time on lease.<a name="line.3578"></a>
-<span class="sourceLineNo">3579</span> // the closeCallBack will be set in closeScanner so here we only care about shippedCallback<a name="line.3579"></a>
-<span class="sourceLineNo">3580</span> if (context != null) {<a name="line.3580"></a>
-<span class="sourceLineNo">3581</span> context.setCallBack(rsh.shippedCallback);<a name="line.3581"></a>
-<span class="sourceLineNo">3582</span> } else {<a name="line.3582"></a>
-<span class="sourceLineNo">3583</span> // When context != null, adding back the lease will be done in callback set above.<a name="line.3583"></a>
-<span class="sourceLineNo">3584</span> addScannerLeaseBack(lease);<a name="line.3584"></a>
-<span class="sourceLineNo">3585</span> }<a name="line.3585"></a>
-<span class="sourceLineNo">3586</span> }<a name="line.3586"></a>
-<span class="sourceLineNo">3587</span> quota.close();<a name="line.3587"></a>
-<span class="sourceLineNo">3588</span> }<a name="line.3588"></a>
-<span class="sourceLineNo">3589</span> }<a name="line.3589"></a>
-<span class="sourceLineNo">3590</span><a name="line.3590"></a>
-<span class="sourceLineNo">3591</span> private void closeScanner(HRegion region, RegionScanner scanner, String scannerName,<a name="line.3591"></a>
-<span class="sourceLineNo">3592</span> RpcCallContext context) throws IOException {<a name="line.3592"></a>
-<span class="sourceLineNo">3593</span> if (region.getCoprocessorHost() != null) {<a name="line.3593"></a>
-<span class="sourceLineNo">3594</span> if (region.getCoprocessorHost().preScannerClose(scanner)) {<a name="line.3594"></a>
-<span class="sourceLineNo">3595</span> // bypass the actual close.<a name="line.3595"></a>
-<span class="sourceLineNo">3596</span> return;<a name="line.3596"></a>
-<span class="sourceLineNo">3597</span> }<a name="line.3597"></a>
-<span class="sourceLineNo">3598</span> }<a name="line.3598"></a>
-<span class="sourceLineNo">3599</span> RegionScannerHolder rsh = scanners.remove(scannerName);<a name="line.3599"></a>
-<span class="sourceLineNo">3600</span> if (rsh != null) {<a name="line.3600"></a>
-<span class="sourceLineNo">3601</span> if (context != null) {<a name="line.3601"></a>
-<span class="sourceLineNo">3602</span> context.setCallBack(rsh.closeCallBack);<a name="line.3602"></a>
-<span class="sourceLineNo">3603</span> } else {<a name="line.3603"></a>
-<span class="sourceLineNo">3604</span> rsh.s.close();<a name="line.3604"></a>
-<span class="sourceLineNo">3605</span> }<a name="line.3605"></a>
-<span class="sourceLineNo">3606</span> if (region.getCoprocessorHost() != null) {<a name="line.3606"></a>
-<span class="sourceLineNo">3607</span> region.getCoprocessorHost().postScannerClose(scanner);<a name="line.3607"></a>
-<span class="sourceLineNo">3608</span> }<a name="line.3608"></a>
-<span class="sourceLineNo">3609</span> closedScanners.put(scannerName, scannerName);<a name="line.3609"></a>
+<span class="sourceLineNo">3573</span><a name="line.3573"></a>
+<span class="sourceLineNo">3574</span> // We closed the scanner already. Instead of throwing the IOException, and client<a name="line.3574"></a>
+<span class="sourceLineNo">3575</span> // retrying with the same scannerId only to get USE on the next RPC, we directly throw<a name="line.3575"></a>
+<span class="sourceLineNo">3576</span> // a special exception to save an RPC.<a name="line.3576"></a>
+<span class="sourceLineNo">3577</span> if (VersionInfoUtil.hasMinimumVersion(context.getClientVersionInfo(), 1, 4)) {<a name="line.3577"></a>
+<span class="sourceLineNo">3578</span> // 1.4.0+ clients know how to handle<a name="line.3578"></a>
+<span class="sourceLineNo">3579</span> throw new ScannerResetException("Scanner is closed on the server-side", e);<a name="line.3579"></a>
+<span class="sourceLineNo">3580</span> } else {<a name="line.3580"></a>
+<span class="sourceLineNo">3581</span> // older clients do not know about SRE. Just throw USE, which they will handle<a name="line.3581"></a>
+<span class="sourceLineNo">3582</span> throw new UnknownScannerException("Throwing UnknownScannerException to reset the client"<a name="line.3582"></a>
+<span class="sourceLineNo">3583</span> + " scanner state for clients older than 1.3.", e);<a name="line.3583"></a>
+<span class="sourceLineNo">3584</span> }<a name="line.3584"></a>
+<span class="sourceLineNo">3585</span> } catch (IOException ioe) {<a name="line.3585"></a>
+<span class="sourceLineNo">3586</span> throw new ServiceException(ioe);<a name="line.3586"></a>
+<span class="sourceLineNo">3587</span> }<a name="line.3587"></a>
+<span class="sourceLineNo">3588</span> } finally {<a name="line.3588"></a>
+<span class="sourceLineNo">3589</span> if (!scannerClosed) {<a name="line.3589"></a>
+<span class="sourceLineNo">3590</span> // Adding resets expiration time on lease.<a name="line.3590"></a>
+<span class="sourceLineNo">3591</span> // the closeCallBack will be set in closeScanner so here we only care about shippedCallback<a name="line.3591"></a>
+<span class="sourceLineNo">3592</span> if (context != null) {<a name="line.3592"></a>
+<span class="sourceLineNo">3593</span> context.setCallBack(rsh.shippedCallback);<a name="line.3593"></a>
+<span class="sourceLineNo">3594</span> } else {<a name="line.3594"></a>
+<span class="sourceLineNo">3595</span> // When context != null, adding back the lease will be done in callback set above.<a name="line.3595"></a>
+<span class="sourceLineNo">3596</span> addScannerLeaseBack(lease);<a name="line.3596"></a>
+<span class="sourceLineNo">3597</span> }<a name="line.3597"></a>
+<span class="sourceLineNo">3598</span> }<a name="line.3598"></a>
+<span class="sourceLineNo">3599</span> quota.close();<a name="line.3599"></a>
+<span class="sourceLineNo">3600</span> }<a name="line.3600"></a>
+<span class="sourceLineNo">3601</span> }<a name="line.3601"></a>
+<span class="sourceLineNo">3602</span><a name="line.3602"></a>
+<span class="sourceLineNo">3603</span> private void closeScanner(HRegion region, RegionScanner scanner, String scannerName,<a name="line.3603"></a>
+<span class="sourceLineNo">3604</span> RpcCallContext context) throws IOException {<a name="line.3604"></a>
+<span class="sourceLineNo">3605</span> if (region.getCoprocessorHost() != null) {<a name="line.3605"></a>
+<span class="sourceLineNo">3606</span> if (region.getCoprocessorHost().preScannerClose(scanner)) {<a name="line.3606"></a>
+<span class="sourceLineNo">3607</span> // bypass the actual close.<a name="line.3607"></a>
+<span class="sourceLineNo">3608</span> return;<a name="line.3608"></a>
+<span class="sourceLineNo">3609</span> }<a name="line.3609"></a>
<span class="sourceLineNo">3610</span> }<a name="line.3610"></a>
-<span class="sourceLineNo">3611</span> }<a name="line.3611"></a>
-<span class="sourceLineNo">3612</span><a name="line.3612"></a>
-<span class="sourceLineNo">3613</span> @Override<a name="line.3613"></a>
-<span class="sourceLineNo">3614</span> public CoprocessorServiceResponse execRegionServerService(RpcController controller,<a name="line.3614"></a>
-<span class="sourceLineNo">3615</span> CoprocessorServiceRequest request) throws ServiceException {<a name="line.3615"></a>
-<span class="sourceLineNo">3616</span> rpcPreCheck("execRegionServerService");<a name="line.3616"></a>
-<span class="sourceLineNo">3617</span> return regionServer.execRegionServerService(controller, request);<a name="line.3617"></a>
-<span class="sourceLineNo">3618</span> }<a name="line.3618"></a>
-<span class="sourceLineNo">3619</span><a name="line.3619"></a>
-<span class="sourceLineNo">3620</span> @Override<a name="line.3620"></a>
-<span class="sourceLineNo">3621</span> public UpdateConfigurationResponse updateConfiguration(<a name="line.3621"></a>
-<span class="sourceLineNo">3622</span> RpcController controller, UpdateConfigurationRequest request)<a name="line.3622"></a>
-<span class="sourceLineNo">3623</span> throws ServiceException {<a name="line.3623"></a>
-<span class="sourceLineNo">3624</span> try {<a name="line.3624"></a>
-<span class="sourceLineNo">3625</span> this.regionServer.updateConfiguration();<a name="line.3625"></a>
-<span class="sourceLineNo">3626</span> } catch (Exception e) {<a name="line.3626"></a>
-<span class="sourceLineNo">3627</span> throw new ServiceException(e);<a name="line.3627"></a>
-<span class="sourceLineNo">3628</span> }<a name="line.3628"></a>
-<span class="sourceLineNo">3629</span> return UpdateConfigurationResponse.getDefaultInstance();<a name="line.3629"></a>
+<span class="sourceLineNo">3611</span> RegionScannerHolder rsh = scanners.remove(scannerName);<a name="line.3611"></a>
+<span class="sourceLineNo">3612</span> if (rsh != null) {<a name="line.3612"></a>
+<span class="sourceLineNo">3613</span> if (context != null) {<a name="line.3613"></a>
+<span class="sourceLineNo">3614</span> context.setCallBack(rsh.closeCallBack);<a name="line.3614"></a>
+<span class="sourceLineNo">3615</span> } else {<a name="line.3615"></a>
+<span class="sourceLineNo">3616</span> rsh.s.close();<a name="line.3616"></a>
+<span class="sourceLineNo">3617</span> }<a name="line.3617"></a>
+<span class="sourceLineNo">3618</span> if (region.getCoprocessorHost() != null) {<a name="line.3618"></a>
+<span class="sourceLineNo">3619</span> region.getCoprocessorHost().postScannerClose(scanner);<a name="line.3619"></a>
+<span class="sourceLineNo">3620</span> }<a name="line.3620"></a>
+<span class="sourceLineNo">3621</span> closedScanners.put(scannerName, scannerName);<a name="line.3621"></a>
+<span class="sourceLineNo">3622</span> }<a name="line.3622"></a>
+<span class="sourceLineNo">3623</span> }<a name="line.3623"></a>
+<span class="sourceLineNo">3624</span><a name="line.3624"></a>
+<span class="sourceLineNo">3625</span> @Override<a name="line.3625"></a>
+<span class="sourceLineNo">3626</span> public CoprocessorServiceResponse execRegionServerService(RpcController controller,<a name="line.3626"></a>
+<span class="sourceLineNo">3627</span> CoprocessorServiceRequest request) throws ServiceException {<a name="line.3627"></a>
+<span class="sourceLineNo">3628</span> rpcPreCheck("execRegionServerService");<a name="line.3628"></a>
+<span class="sourceLineNo">3629</span> return regionServer.execRegionServerService(controller, request);<a name="line.3629"></a>
<span class="sourceLineNo">3630</span> }<a name="line.3630"></a>
<span class="sourceLineNo">3631</span><a name="line.3631"></a>
<span class="sourceLineNo">3632</span> @Override<a name="line.3632"></a>
-<span class="sourceLineNo">3633</span> public GetSpaceQuotaSnapshotsResponse getSpaceQuotaSnapshots(<a name="line.3633"></a>
-<span class="sourceLineNo">3634</span> RpcController controller, GetSpaceQuotaSnapshotsRequest request) throws ServiceException {<a name="line.3634"></a>
-<span class="sourceLineNo">3635</span> try {<a name="line.3635"></a>
-<span class="sourceLineNo">3636</span> final RegionServerSpaceQuotaManager manager =<a name="line.3636"></a>
-<span class="sourceLineNo">3637</span> regionServer.getRegionServerSpaceQuotaManager();<a name="line.3637"></a>
-<span class="sourceLineNo">3638</span> final GetSpaceQuotaSnapshotsResponse.Builder builder =<a name="line.3638"></a>
-<span class="sourceLineNo">3639</span> GetSpaceQuotaSnapshotsResponse.newBuilder();<a name="line.3639"></a>
-<span class="sourceLineNo">3640</span> if (manager != null) {<a name="line.3640"></a>
-<span class="sourceLineNo">3641</span> final Map<TableName,SpaceQuotaSnapshot> snapshots = manager.copyQuotaSnapshots();<a name="line.3641"></a>
-<span class="sourceLineNo">3642</span> for (Entry<TableName,SpaceQuotaSnapshot> snapshot : snapshots.entrySet()) {<a name="line.3642"></a>
-<span class="sourceLineNo">3643</span> builder.addSnapshots(TableQuotaSnapshot.newBuilder()<a name="line.3643"></a>
-<span class="sourceLineNo">3644</span> .setTableName(ProtobufUtil.toProtoTableName(snapshot.getKey()))<a name="line.3644"></a>
-<span class="sourceLineNo">3645</span> .setSnapshot(SpaceQuotaSnapshot.toProtoSnapshot(snapshot.getValue()))<a name="line.3645"></a>
-<span class="sourceLineNo">3646</span> .build());<a name="line.3646"></a>
-<span class="sourceLineNo">3647</span> }<a name="line.3647"></a>
-<span class="sourceLineNo">3648</span> }<a name="line.3648"></a>
-<span class="sourceLineNo">3649</span> return builder.build();<a name="line.3649"></a>
-<span class="sourceLineNo">3650</span> } catch (Exception e) {<a name="line.3650"></a>
-<span class="sourceLineNo">3651</span> throw new ServiceException(e);<a name="line.3651"></a>
-<span class="sourceLineNo">3652</span> }<a name="line.3652"></a>
-<span class="sourceLineNo">3653</span> }<a name="line.3653"></a>
-<span class="sourceLineNo">3654</span><a name="line.3654"></a>
-<span class="sourceLineNo">3655</span> @Override<a name="line.3655"></a>
-<span class="sourceLineNo">3656</span> public ClearRegionBlockCacheResponse clearRegionBlockCache(RpcController controller,<a name="line.3656"></a>
-<span class="sourceLineNo">3657</span> ClearRegionBlockCacheRequest request) {<a name="line.3657"></a>
-<span class="sourceLineNo">3658</span> ClearRegionBlockCacheResponse.Builder builder =<a name="line.3658"></a>
-<span class="sourceLineNo">3659</span> ClearRegionBlockCacheResponse.newBuilder();<a name="line.3659"></a>
-<span class="sourceLineNo">3660</span> CacheEvictionStatsBuilder stats = CacheEvictionStats.builder();<a name="line.3660"></a>
-<span class="sourceLineNo">3661</span> List<HRegion> regions = getRegions(request.getRegionList(), stats);<a name="line.3661"></a>
-<span class="sourceLineNo">3662</span> for (HRegion region : regions) {<a name="line.3662"></a>
-<span class="sourceLineNo">3663</span> try {<a name="line.3663"></a>
-<span class="sourceLineNo">3664</span> stats = stats.append(this.regionServer.clearRegionBlockCache(region));<a name="line.3664"></a>
-<span class="sourceLineNo">3665</span> } catch (Exception e) {<a name="line.3665"></a>
-<span class="sourceLineNo">3666</span> stats.addException(region.getRegionInfo().getRegionName(), e);<a name="line.3666"></a>
-<span class="sourceLineNo">3667</span> }<a name="line.3667"></a>
-<span class="sourceLineNo">3668</span> }<a name="line.3668"></a>
-<span class="sourceLineNo">3669</span> stats.withMaxCacheSize(regionServer.getCacheConfig().getBlockCache().getMaxSize());<a name="line.3669"></a>
-<span class="sourceLineNo">3670</span> return builder.setStats(ProtobufUtil.toCacheEvictionStats(stats.build())).build();<a name="line.3670"></a>
-<span class="sourceLineNo">3671</span> }<a name="line.3671"></a>
-<span class="sourceLineNo">3672</span><a name="line.3672"></a>
-<span class="sourceLineNo">3673</span> @Override<a name="line.3673"></a>
-<span class="sourceLineNo">3674</span> @QosPriority(priority = HConstants.ADMIN_QOS)<a name="line.3674"></a>
-<span class="sourceLineNo">3675</span> public ExecuteProceduresResponse executeProcedures(RpcController controller,<a name="line.3675"></a>
-<span class="sourceLineNo">3676</span> ExecuteProceduresRequest request) throws ServiceException {<a name="line.3676"></a>
-<span class="sourceLineNo">3677</span> try {<a name="line.3677"></a>
-<span class="sourceLineNo">3678</span> checkOpen();<a name="line.3678"></a>
-<span class="sourceLineNo">3679</span> regionServer.getRegionServerCoprocessorHost().preExecuteProcedures();<a name="line.3679"></a>
-<span class="sourceLineNo">3680</span> if (request.getOpenRegionCount() > 0) {<a name="line.3680"></a>
-<span class="sourceLineNo">3681</span> for (OpenRegionRequest req : request.getOpenRegionList()) {<a name="line.3681"></a>
-<span class="sourceLineNo">3682</span> openRegion(controller, req);<a name="line.3682"></a>
-<span class="sourceLineNo">3683</span> }<a name="line.3683"></a>
-<span class="sourceLineNo">3684</span> }<a name="line.3684"></a>
-<span class="sourceLineNo">3685</span> if (request.getCloseRegionCount() > 0) {<a name="line.3685"></a>
-<span class="sourceLineNo">3686</span> for (CloseRegionRequest req : request.getCloseRegionList()) {<a name="line.3686"></a>
-<span class="sourceLineNo">3687</span> closeRegion(controller, req);<a name="line.3687"></a>
-<span class="sourceLineNo">3688</span> }<a name="line.3688"></a>
-<span class="sourceLineNo">3689</span> }<a name="line.3689"></a>
-<span class="sourceLineNo">3690</span> if (request.getProcCount() > 0) {<a name="line.3690"></a>
-<span class="sourceLineNo">3691</span> for (RemoteProcedureRequest req : request.getProcList()) {<a name="line.3691"></a>
-<span class="sourceLineNo">3692</span> RSProcedureCallable callable;<a name="line.3692"></a>
-<span class="sourceLineNo">3693</span> try {<a name="line.3693"></a>
-<span class="sourceLineNo">3694</span> callable = Class.forName(req.getProcClass()).asSubclass(RSProcedureCallable.class)<a name="line.3694"></a>
-<span class="sourceLineNo">3695</span> .getDeclaredConstructor().newInstance();<a name="line.3695"></a>
-<span class="sourceLineNo">3696</span> } catch (Exception e) {<a name="line.3696"></a>
-<span class="sourceLineNo">3697</span> regionServer.remoteProcedureComplete(req.getProcId(), e);<a name="line.3697"></a>
-<span class="sourceLineNo">3698</span> continue;<a name="line.3698"></a>
-<span class="sourceLineNo">3699</span> }<a name="line.3699"></a>
-<span class="sourceLineNo">3700</span> callable.init(req.getProcData().toByteArray(), regionServer);<a name="line.3700"></a>
-<span class="sourceLineNo">3701</span> regionServer.executeProcedure(req.getProcId(), callable);<a name="line.3701"></a>
-<span class="sourceLineNo">3702</span> }<a name="line.3702"></a>
-<span class="sourceLineNo">3703</span> }<a name="line.3703"></a>
-<span class="sourceLineNo">3704</span> regionServer.getRegionServerCoprocessorHost().postExecuteProcedures();<a name="line.3704"></a>
-<span class="sourceLineNo">3705</span> return ExecuteProceduresResponse.getDefaultInstance();<a name="line.3705"></a>
-<span class="sourceLineNo">3706</span> } catch (IOException e) {<a name="line.3706"></a>
-<span class="sourceLineNo">3707</span> throw new ServiceException(e);<a name="line.3707"></a>
-<span class="sourceLineNo">3708</span> }<a name="line.3708"></a>
-<span class="sourceLineNo">3709</span> }<a name="line.3709"></a>
-<span class="sourceLineNo">3710</span><a name="line.3710"></a>
-<span class="sourceLineNo">3711</span> @VisibleForTesting<a name="line.3711"></a>
-<span class="sourceLineNo">3712</span> public RpcScheduler getRpcScheduler() {<a name="line.3712"></a>
-<span class="sourceLineNo">3713</span> return rpcServer.getScheduler();<a name="line.3713"></a>
-<span class="sourceLineNo">3714</span> }<a name="line.3714"></a>
-<span class="sourceLineNo">3715</span>}<a name="line.3715"></a>
+<span class="sourceLineNo">3633</span> public UpdateConfigurationResponse updateConfiguration(<a name="line.3633"></a>
+<span class="sourceLineNo">3634</span> RpcController controller, UpdateConfigurationRequest request)<a name="line.3634"></a>
+<span class="sourceLineNo">3635</span> throws ServiceException {<a name="line.3635"></a>
+<span class="sourceLineNo">3636</span> try {<a name="line.3636"></a>
+<span class="sourceLineNo">3637</span> this.regionServer.updateConfiguration();<a name="line.3637"></a>
+<span class="sourceLineNo">3638</span> } catch (Exception e) {<a name="line.3638"></a>
+<span class="sourceLineNo">3639</span> throw new ServiceException(e);<a name="line.3639"></a>
+<span class="sourceLineNo">3640</span> }<a name="line.3640"></a>
+<span class="sourceLineNo">3641</span> return UpdateConfigurationResponse.getDefaultInstance();<a name="line.3641"></a>
+<span class="sourceLineNo">3642</span> }<a name="line.3642"></a>
+<span class="sourceLineNo">3643</span><a name="line.3643"></a>
+<span class="sourceLineNo">3644</span> @Override<a name="line.3644"></a>
+<span class="sourceLineNo">3645</span> public GetSpaceQuotaSnapshotsResponse getSpaceQuotaSnapshots(<a name="line.3645"></a>
+<span class="sourceLineNo">3646</span> RpcController controller, GetSpaceQuotaSnapshotsRequest request) throws ServiceException {<a name="line.3646"></a>
+<span class="sourceLineNo">3647</span> try {<a name="line.3647"></a>
+<span class="sourceLineNo">3648</span> final RegionServerSpaceQuotaManager manager =<a name="line.3648"></a>
+<span class="sourceLineNo">3649</span> regionServer.getRegionServerSpaceQuotaManager();<a name="line.3649"></a>
+<span class="sourceLineNo">3650</span> final GetSpaceQuotaSnapshotsResponse.Builder builder =<a name="line.3650"></a>
+<span class="sourceLineNo">3651</span> GetSpaceQuotaSnapshotsResponse.newBuilder();<a name="line.3651"></a>
+<span class="sourceLineNo">3652</span> if (manager != null) {<a name="line.3652"></a>
+<span class="sourceLineNo">3653</span> final Map<TableName,SpaceQuotaSnapshot> snapshots = manager.copyQuotaSnapshots();<a name="line.3653"></a>
+<span class="sourceLineNo">3654</span> for (Entry<TableName,SpaceQuotaSnapshot> snapshot : snapshots.entrySet()) {<a name="line.3654"></a>
+<span class="sourceLineNo">3655</span> builder.addSnapshots(TableQuotaSnapshot.newBuilder()<a name="line.3655"></a>
+<span class="sourceLineNo">3656</span> .setTableName(ProtobufUtil.toProtoTableName(snapshot.getKey()))<a name="line.3656"></a>
+<span class="sourceLineNo">3657</span> .setSnapshot(SpaceQuotaSnapshot.toProtoSnapshot(snapshot.getValue()))<a name="line.3657"></a>
+<span class="sourceLineNo">3658</span> .build());<a name="line.3658"></a>
+<span class="sourceLineNo">3659</span> }<a name="line.3659"></a>
+<span class="sourceLineNo">3660</span> }<a name="line.3660"></a>
+<span class="sourceLineNo">3661</span> return builder.build();<a name="line.3661"></a>
+<span class="sourceLineNo">3662</span> } catch (Exception e) {<a name="line.3662"></a>
+<span class="sourceLineNo">3663</span> throw new ServiceException(e);<a name="line.3663"></a>
+<span class="sourceLineNo">3664</span> }<a name="line.3664"></a>
+<span class="sourceLineNo">3665</span> }<a name="line.3665"></a>
+<span class="sourceLineNo">3666</span><a name="line.3666"></a>
+<span class="sourceLineNo">3667</span> @Override<a name="line.3667"></a>
+<span class="sourceLineNo">3668</span> public ClearRegionBlockCacheResponse clearRegionBlockCache(RpcController controller,<a name="line.3668"></a>
+<span class="sourceLineNo">3669</span> ClearRegionBlockCacheRequest request) {<a name="line.3669"></a>
+<span class="sourceLineNo">3670</span> ClearRegionBlockCacheResponse.Builder builder =<a name="line.3670"></a>
+<span class="sourceLineNo">3671</span> ClearRegionBlockCacheResponse.newBuilder();<a name="line.3671"></a>
+<span class="sourceLineNo">3672</span> CacheEvictionStatsBuilder stats = CacheEvictionStats.builder();<a name="line.3672"></a>
+<span class="sourceLineNo">3673</span> List<HRegion> regions = getRegions(request.getRegionList(), stats);<a name="line.3673"></a>
+<span class="sourceLineNo">3674</span> for (HRegion region : regions) {<a name="line.3674"></a>
+<span class="sourceLineNo">3675</span> try {<a name="line.3675"></a>
+<span class="sourceLineNo">3676</span> stats = stats.append(this.regionServer.clearRegionBlockCache(region));<a name="line.3676"></a>
+<span class="sourceLineNo">3677</span> } catch (Exception e) {<a name="line.3677"></a>
+<span class="sourceLineNo">3678</span> stats.addException(region.getRegionInfo().getRegionName(), e);<a name="line.3678"></a>
+<span class="sourceLineNo">3679</span> }<a name="line.3679"></a>
+<span class="sourceLineNo">3680</span> }<a name="line.3680"></a>
+<span class="sourceLineNo">3681</span> stats.withMaxCacheSize(regionServer.getCacheConfig().getBlockCache().getMaxSize());<a name="line.3681"></a>
+<span class="sourceLineNo">3682</span> return builder.setStats(ProtobufUtil.toCacheEvictionStats(stats.build())).build();<a name="line.3682"></a>
+<span class="sourceLineNo">3683</span> }<a name="line.3683"></a>
+<span class="sourceLineNo">3684</span><a name="line.3684"></a>
+<span class="sourceLineNo">3685</span> @Override<a name="line.3685"></a>
+<span class="sourceLineNo">3686</span> @QosPriority(priority = HConstants.ADMIN_QOS)<a name="line.3686"></a>
+<span class="sourceLineNo">3687</span> public ExecuteProceduresResponse executeProcedures(RpcController controller,<a name="line.3687"></a>
+<span class="sourceLineNo">3688</span> ExecuteProceduresRequest request) throws ServiceException {<a name="line.3688"></a>
+<span class="sourceLineNo">3689</span> try {<a name="line.3689"></a>
+<span class="sourceLineNo">3690</span> checkOpen();<a name="line.3690"></a>
+<span class="sourceLineNo">3691</span>
<TRUNCATED>