private SyncTargetRange getRangeFromPendingRequest() {
    final CompletableFuture<List<BlockHeader>> pendingRequest = this.pendingRequests.get();
    try {
      final List<BlockHeader> newHeaders =
          pendingRequest.get(newHeaderWaitDuration.toMillis(), MILLISECONDS);
      this.pendingRequests = Optional.empty();
      if (newHeaders.isEmpty()) {
        retryCount++;
        if (retryCount >= retriesPermitted) {
          LOG.atDebug()
              .setMessage(
                  "Disconnecting target peer {} for providing useless or empty range headers.")
              .addArgument(peer)
              .log();
          peer.disconnect(DisconnectMessage.DisconnectReason.USELESS_PEER_USELESS_RESPONSES);
        }
      } else {
        retryCount = 0;
        for (final BlockHeader header : newHeaders) {
          retrievedRanges.add(new SyncTargetRange(peer, lastRangeEnd, header));
          lastRangeEnd = header;
        }
      }
      return retrievedRanges.poll();
    } catch (final InterruptedException e) {
      LOG.trace("Interrupted while waiting for new range headers", e);
      return null;
    } catch (final ExecutionException | TimeoutException e) {
      if (e instanceof ExecutionException) {
        this.pendingRequests = Optional.empty();
      }
      retryCount++;
      if (retryCount >= retriesPermitted) {
        LOG.atDebug()
            .setMessage(
                "Disconnecting target peer {} for not providing useful range headers: Exception: {}.")
            .addArgument(peer)
            .addArgument(e)
            .log();
        peer.disconnect(DisconnectMessage.DisconnectReason.USELESS_PEER_USELESS_RESPONSES);
      }
      return null;
    }
  }
Pause after failing to get new range to prevent requesting new range headers in a tight loop.

@return a future that after the pause completes with an empty list.
ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/range/SyncTargetRangeSource.java