private void handleChangeInVcrNodes(Set<CloudDataNode> newVcrNodes) {
    Set<CloudDataNode> removedNodes = new HashSet<>(vcrNodes.get());
    removedNodes.removeAll(newVcrNodes);
    vcrNodes.set(new ArrayList<>(newVcrNodes));
    logger.info("Handling VCR nodes change. The removed vcr nodes: {}", removedNodes);
    List<PartitionId> partitionsOnRemovedNodes = getPartitionsOnNodes(removedNodes);
    for (PartitionId partitionId : partitionsOnRemovedNodes) {
      try {
        // We first remove replica to stop replication from removed node, and then add replica so that it can pick a
        // new cloud node to start replicating from.
        removeCloudReplica(partitionId.toPathString());
        addCloudReplica(partitionId.toPathString());
      } catch (Exception rex) {
        recoveryMetrics.addCloudPartitionErrorCount.inc();
        logger.error("Exception {} during remove/add replica for partitionId {}", rex, partitionId);
      }
    }
  }
When there is a change in vcr nodes state, update the new list of live vcr nodes.
Also if there are nodes that are removed as part of change, then replication from
those nodes should stop and the partitions should find new nodes to replicate from.
Note that this method is not thread safe in the wake of arriving helix notifications.
@param newVcrNodes Set of new vcr nodes.
ambry-cloud/src/main/java/com/github/ambry/cloud/RecoveryManager.java