MCPcopy Index your code
hub / github.com/OpenTSDB/asynchbase / handleNSRE

Method handleNSRE

src/HBaseClient.java:3448–3689  ·  view source on GitHub ↗

Handles the NotServingRegionException for the given RPC. This code will take ownership of the RPC in the sense that it will become responsible for re-scheduling the RPC later once the NSRE situation gets resolved by HBase. NSRE handling logic Whenever we get an NSRE for the fir

(HBaseRpc rpc,
                  final byte[] region_name,
                  final RecoverableException e)

Source from the content-addressed store, hash-verified

3446 * @param e The exception that caused (or may cause) this RPC to fail.
3447 */
3448 void handleNSRE(HBaseRpc rpc,
3449 final byte[] region_name,
3450 final RecoverableException e) {
3451 num_nsre_rpcs.increment();
3452 if (rpc.isProbe()) {
3453 rpc.setSuspendedProbe(true);
3454 }
3455 final boolean can_retry_rpc = !cannotRetryRequest(rpc);
3456 boolean known_nsre = true; // We already aware of an NSRE for this region?
3457 ArrayList<HBaseRpc> nsred_rpcs = got_nsre.get(region_name);
3458 HBaseRpc exists_rpc = null; // Our "probe" RPC.
3459 if (nsred_rpcs == null) { // Looks like this could be a new NSRE...
3460 final ArrayList<HBaseRpc> newlist = new ArrayList<HBaseRpc>(64);
3461 // In HBase 0.95 and up, the exists RPC can't use the empty row key,
3462 // which could happen if we were trying to scan from the beginning of
3463 // the table. So instead use "\0" as the key.
3464 exists_rpc = GetRequest.exists(rpc.table, probeKey(rpc.key));
3465 newlist.add(exists_rpc);
3466 if (can_retry_rpc) {
3467 newlist.add(rpc);
3468 }
3469 nsred_rpcs = got_nsre.putIfAbsent(region_name, newlist);
3470 if (nsred_rpcs == null) { // We've just put `newlist'.
3471 nsred_rpcs = newlist; // => We're the first thread to get
3472 known_nsre = false; // the NSRE for this region.
3473 }
3474 }
3475
3476 if (known_nsre) { // Some RPCs seem to already be pending due to this NSRE
3477 boolean reject = true; // Should we reject this RPC (too many pending)?
3478 int size; // How many RPCs are already pending?
3479
3480 synchronized (nsred_rpcs) {
3481 size = nsred_rpcs.size();
3482 // If nsred_rpcs is empty, there was a race with another thread which
3483 // is executing RetryNSREd.call and that just cleared this array and
3484 // removed nsred_rpcs from got_nsre right after we got the reference,
3485 // so we need to add it back there, unless another thread already
3486 // did it (in which case we're really unlucky and lost 2 races).
3487 if (size == 0) {
3488 final ArrayList<HBaseRpc> added =
3489 got_nsre.putIfAbsent(region_name, nsred_rpcs);
3490 if (added == null) { // We've just put `nsred_rpcs'.
3491 exists_rpc = GetRequest.exists(rpc.table, probeKey(rpc.key));
3492 nsred_rpcs.add(exists_rpc); // We hold the lock on nsred_rpcs
3493 if (can_retry_rpc) {
3494 nsred_rpcs.add(rpc); // so we can safely add those 2.
3495 }
3496 known_nsre = false; // We mistakenly believed it was known.
3497 } else { // We lost the second race.
3498 // Here we synchronize on two different references without any
3499 // apparent ordering guarantee, which can typically lead to
3500 // deadlocks. In this case though we're fine, as any other thread
3501 // that still has a reference to `nsred_rpcs' is gonna go through
3502 // this very same code path and will lock `nsred_rpcs' first
3503 // before finding that it too lost 2 races, so it'll lock `added'
3504 // second. So there's actually a very implicit ordering.
3505 if (can_retry_rpc) {

Callers 15

sendRpcToRegionMethod · 0.95
answerMethod · 0.80
recoverOnTriggerMethod · 0.80
recoverOnProbeMethod · 0.80
tooManyAttemptsMethod · 0.80
handleNSRENullRPCMethod · 0.80
handleNSRENullRegionMethod · 0.80
handleNSRE1stTimeMethod · 0.80
handleNSRE2ndTimeMethod · 0.80

Calls 15

setSuspendedProbeMethod · 0.95
cannotRetryRequestMethod · 0.95
existsMethod · 0.95
probeKeyMethod · 0.95
prettyMethod · 0.95
isSuspendedProbeMethod · 0.95
getDeferredMethod · 0.95
invalidateRegionCacheMethod · 0.95
tooManyAttemptsMethod · 0.95
newTimeoutMethod · 0.95
getRetryDelayMethod · 0.95
incrementMethod · 0.80

Tested by 15

answerMethod · 0.64
recoverOnTriggerMethod · 0.64
recoverOnProbeMethod · 0.64
tooManyAttemptsMethod · 0.64
handleNSRENullRPCMethod · 0.64
handleNSRENullRegionMethod · 0.64
handleNSRE1stTimeMethod · 0.64
handleNSRE2ndTimeMethod · 0.64
handleNSREReProbeMethod · 0.64