private <T extends Message> CompletableFuture<T> call(ClientMetaService.Interface stub,
    Callable<T> callable) {
    HBaseRpcController controller = rpcControllerFactory.newController();
    CompletableFuture<T> future = new CompletableFuture<>();
    callable.call(controller, stub, resp -> {
      if (controller.failed()) {
        IOException failureReason = controller.getFailed();
        future.completeExceptionally(failureReason);
        if (ClientExceptionsUtil.isConnectionException(failureReason)) {
          // RPC has failed, trigger a refresh of end points. We can have some spurious
          // refreshes, but that is okay since the RPC is not expensive and not in a hot path.
          registryEndpointRefresher.refreshNow();
        }
      } else {
        future.complete(resp);
      }
    });
    return future;
  }
For describing the actual asynchronous rpc call.
<p/>
Typically, you can use lambda expression to implement this interface as

<pre>
(c, s, d) -&gt; s.xxx(c, your request here, d)
</pre>
hbase-client/src/main/java/org/apache/hadoop/hbase/client/AbstractRpcBasedConnectionRegistry.java