@Override
    public void onNodeAck(DiscoveryNode node, @Nullable Exception e) {
      if (!ackedTaskListener.mustAck(node)) {
        // we always wait for the master ack anyway
        if (!node.equals(nodes.getMasterNode())) {
          return;
        }
      }
      if (e == null) {
        logger.trace(
            "ack received from node [{}], cluster_state update (version: {})",
            node,
            clusterStateVersion);
      } else {
        this.lastFailure = e;
        logger.debug(
            (Supplier<?>)
                () ->
                    new ParameterizedMessage(
                        "ack received from node [{}], cluster_state update (version: {})",
                        node,
                        clusterStateVersion),
            e);
      }

      if (countDown.countDown()) {
        logger.trace(
            "all expected nodes acknowledged cluster_state update (version: {})",
            clusterStateVersion);
        FutureUtils.cancel(ackTimeoutCallback);
        ackedTaskListener.onAllNodesAcked(lastFailure);
      }
    }
 AckCountDownListener(
     AckedClusterStateTaskListener ackedTaskListener,
     long clusterStateVersion,
     DiscoveryNodes nodes,
     ThreadPool threadPool) {
   this.ackedTaskListener = ackedTaskListener;
   this.clusterStateVersion = clusterStateVersion;
   this.nodes = nodes;
   int countDown = 0;
   for (DiscoveryNode node : nodes) {
     if (ackedTaskListener.mustAck(node)) {
       countDown++;
     }
   }
   // we always wait for at least 1 node (the master)
   countDown = Math.max(1, countDown);
   logger.trace(
       "expecting {} acknowledgements for cluster_state update (version: {})",
       countDown,
       clusterStateVersion);
   this.countDown = new CountDown(countDown);
   this.ackTimeoutCallback =
       threadPool.schedule(
           ackedTaskListener.ackTimeout(),
           ThreadPool.Names.GENERIC,
           new Runnable() {
             @Override
             public void run() {
               onTimeout();
             }
           });
 }
 @Override
 public boolean mustAck(DiscoveryNode discoveryNode) {
   return listener.mustAck(discoveryNode);
 }