code: private <T> T execute(Operation<T> operation, ThriftClientProvider provider) throws Exception {
      RetryStrategy retryStrategy = retryStrategyProvider.newRetryStrategy();
      while (true) {
        // did we get a custom client provider or do we use the default?
        if (provider == null) {
          provider = this.clientProvider;
        }
        // this will throw a TException if it cannot get a client
        try (CloseableThriftClient closeable = provider.getCloseableClient()) {
          // note that this can throw exceptions other than TException
          return operation.execute(closeable.getThriftClient());
  
        } catch (TException te) {
          // determine whether we should retry
          boolean retry = retryStrategy.failOnce();
          if (!retry) {
            // retry strategy is exceeded, throw an operation exception
            String message =
                "Thrift error for " + operation + ": " + te.getMessage();
            LOG.error(message);
            LOG.debug(message, te);
            throw new Exception(message, te);
          } else {
            // call retry strategy before retrying
            retryStrategy.beforeRetry();
            String msg = "Retrying " + operation.getName() + " after Thrift error: " + te.getMessage();
            LOG.info(msg);
            LOG.debug(msg, te);
          }
  
        }
      }
    }
docs: This is a generic method implementing the somewhat complex execution
  and retry logic for operations, to avoid repetitive code.
  
  Attempts to execute one operation, by obtaining an tx client from
  the client provider and passing the operation to the client. If the
  call fails with a Thrift exception, apply the retry strategy. If no
  more retries are to be made according to the strategy, call the
  operation's error method to obtain a value to return. Note that error()
  may also throw an exception. Note also that the retry logic is only
  applied for thrift exceptions.
  
  @param operation The operation to be executed
  @param provider An tx client provider. If null, then a client will be
  obtained using the client provider
  @param <T> The return type of the operation
  @return the result of the operation, or a value returned by error()