Details
-
Improvement
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
None
-
None
-
None
Description
The following code is repeated in every one of HTable#get and HTable#getRow methods:
MapWritable value = null; for (int tries = 0; tries < numRetries; tries++) { HRegionLocation r = getRegionLocation(row); HRegionInterface server = connection.getHRegionConnection(r.getServerAddress()); try { value = server.getRow(r.getRegionInfo().getRegionName(), row, ts); // This is the only line of code that changes significantly between methods break; } catch (IOException e) { if (e instanceof RemoteException) { e = RemoteExceptionHandler.decodeRemoteException((RemoteException) e); } if (tries == numRetries - 1) { // No more tries throw e; } if (LOG.isDebugEnabled()) { LOG.debug("reloading table servers because: " + e.getMessage()); } tableServers = connection.reloadTableServers(tableName); } try { Thread.sleep(this.pause); } catch (InterruptedException x) { // continue } }
This should be factored out into a protected method that handles retry-on-failure logic to facilitate more robust testing and the development of new API methods.
Proposed modification:
// Execute the provided Callable against the server
protected <T> callServerWithRetries(Callable<T> callable) throws RemoteException;
The above code could then be reduced to:
MapWritable value = null; final connection; try { value = callServerWithRetries(new Callable<MapWritable>() { HRegionLocation r = getRegionLocation(row); HRegionInterface server = connection.getHRegionConnection(r.getServerAddress()); server.getRow(r.getRegionInfo().getRegionName(), row, ts); }); } catch (RemoteException e) { // handle unrecoverable remote exceptions }
This would greatly ease the development of new API methods by reducing the amount of code needed to implement a new method and reducing the amount of logic that needs to be tested per method.