docs: private CompletableFuture<Void> sendHeartbeats() {
      checkMetadata();
      Stream<GossipMember> clusterMembers = members.values().stream()
          .filter(member -> !member.id().equals(localMember.id()));
  
      Stream<GossipMember> providerMembers = discoveryService.getNodes().stream()
          .filter(node -> !members.containsKey(MemberId.from(node.id().id())))
          .map(node -> new GossipMember(MemberId.from(node.id().id()), node.address()));
  
      return Futures.allOf(Stream.concat(clusterMembers, providerMembers)
          .map(member -> {
            LOGGER.trace("{} - Sending heartbeat: {}", localMember.id(), member);
            return sendHeartbeat(member).exceptionally(v -> null);
          }).collect(Collectors.toList()))
          .thenApply(v -> null);
    }