[ https://issues.apache.org/jira/browse/HADOOP-2555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12558191#action_12558191 ]
Bryan Duxbury commented on HADOOP-2555: --------------------------------------- Generally, I love this patch. It'll nicely reduce the amount of copy-paste we have. I'd like to maybe take it one step further, though. Instead of the existing callServerWithRetries, how about something like: {code} protected abstract class ServerCallable<T> implements Callable<T> { HRegionLocation location; HRegionInterface server; Text row; protected ServerCallable(Text row){ this.row = row; } void instantiateServer(boolean reload) throws IOException { if (reload) { tableServers = connection.reloadTableServers(tableName); } location = getRegionLocation(row); server = connection.getHRegionConnection(location.getServerAddress()); } } protected <T> T getRegionServerWithRetries(ServerCallable<T> callable) throws IOException, UnexpectedCallableException { for(int tries = 0; tries < numRetries; tries++) { try { callable.instantiateServer(tries == 0); return callable.call(); } catch (IOException e) { if (e instanceof RemoteException) { e = RemoteExceptionHandler.decodeRemoteException((RemoteException) e); } if (tries == numRetries - 1) { throw e; } if (LOG.isDebugEnabled()) { LOG.debug("reloading table servers because: " + e.getMessage()); } } catch (Exception e) { throw new UnexpectedCallableException(e); } try { Thread.sleep(pause); } catch (InterruptedException e) { // continue } } return null; } {code} which takes us from {code} value = this.callServerWithRetries(new Callable<MapWritable>() { public MapWritable call() throws IOException { HRegionLocation r = getRegionLocation(row); HRegionInterface server = connection.getHRegionConnection(r.getServerAddress()); return server.getRow(r.getRegionInfo().getRegionName(), row, ts); } }); {code} to {code} value = this.callServerWithRetries(new ServerCallable<MapWritable>(row) { public MapWritable call() throws IOException { return server.getRow(location.getRegionInfo().getRegionName(), row, ts); } }); {code} This would save a few lines of code inside each internal block, move a little more logic into the helper method, and generally jive better with the way my HADOOP-2443 patch is going to need to work in the near future. Comments? > Refactor the HTable#get and HTable#getRow methods to avoid repetition of > retry-on-failure logic > ----------------------------------------------------------------------------------------------- > > Key: HADOOP-2555 > URL: https://issues.apache.org/jira/browse/HADOOP-2555 > Project: Hadoop > Issue Type: Improvement > Components: contrib/hbase > Reporter: Peter Dolan > Priority: Minor > Attachments: hadoop-2555.patch > > > The following code is repeated in every one of HTable#get and HTable#getRow > methods: > {code:title=HTable.java|borderStyle=solid} > 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 > } > } > {code} > 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: > {code:title=HTable.java|borderStyle=solid} > 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 > } > {code} > 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. -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.