Sends an RPC targeted at a particular region to the right RegionServer. This method is package-private so that the low-level RegionClient can retry RPCs when handling a NotServingRegionException. @param request The RPC to send. This RPC must specify a single specific tabl
(final HBaseRpc request)
| 2416 | * de-serialized back from the network). |
| 2417 | */ |
| 2418 | Deferred<Object> sendRpcToRegion(final HBaseRpc request) { |
| 2419 | if (cannotRetryRequest(request)) { |
| 2420 | return tooManyAttempts(request, null); |
| 2421 | } |
| 2422 | request.attempt++; |
| 2423 | final byte[] table = request.table; |
| 2424 | final byte[] key = request.key; |
| 2425 | final RegionInfo region = getRegion(table, key); |
| 2426 | |
| 2427 | final class RetryRpc implements Callback<Deferred<Object>, Object> { |
| 2428 | public Deferred<Object> call(final Object arg) { |
| 2429 | if (arg instanceof NonRecoverableException) { |
| 2430 | // No point in retrying here, so fail the RPC. |
| 2431 | HBaseException e = (NonRecoverableException) arg; |
| 2432 | if (e instanceof HasFailedRpcException |
| 2433 | && ((HasFailedRpcException) e).getFailedRpc() != request) { |
| 2434 | // If we get here it's because a dependent RPC (such as a META |
| 2435 | // lookup) has failed. Therefore the exception we're getting |
| 2436 | // indicates that the META lookup failed, but we need to return |
| 2437 | // to our caller here that it's their RPC that failed. Here we |
| 2438 | // re-create the exception but with the correct RPC in argument. |
| 2439 | e = e.make(e, request); // e is likely a PleaseThrottleException. |
| 2440 | } |
| 2441 | request.callback(e); |
| 2442 | return Deferred.fromError(e); |
| 2443 | } |
| 2444 | return sendRpcToRegion(request); // Retry the RPC. |
| 2445 | } |
| 2446 | public String toString() { |
| 2447 | return "retry RPC"; |
| 2448 | } |
| 2449 | } |
| 2450 | |
| 2451 | if (region != null) { |
| 2452 | if (knownToBeNSREd(region)) { |
| 2453 | final NotServingRegionException nsre = |
| 2454 | new NotServingRegionException("Region known to be unavailable", |
| 2455 | request); |
| 2456 | final Deferred<Object> d = request.getDeferred(); |
| 2457 | handleNSRE(request, region.name(), nsre); |
| 2458 | return d; |
| 2459 | } |
| 2460 | final RegionClient client = clientFor(region); |
| 2461 | if (client != null && client.isAlive()) { |
| 2462 | request.setRegion(region); |
| 2463 | final Deferred<Object> d = request.getDeferred(); |
| 2464 | client.sendRpc(request); |
| 2465 | return d; |
| 2466 | } |
| 2467 | } |
| 2468 | return locateRegion(request, table, key).addBothDeferring(new RetryRpc()); |
| 2469 | } |
| 2470 | |
| 2471 | /** |
| 2472 | * Returns how many lookups in {@code -ROOT-} were performed. |