public void refreshPeerLeadersForLeaderPartitions() {
      // Read-write lock usage: Avoids contention between threads doing the following activities:
      // 1. Adding new leaders (in addPeerLeadersByPartition())
      // 2. Removing old leaders (in removePartition())
      // 3. Refreshing remote leader set for existing leaders (current method).
      // Explanation for point 3: Multiple threads from different cluster change handlers (we have one cluster change handler for each DC)
      // can trigger onRoutingTableUpdate() in parallel which calls this method to refresh leader partitions.
      // We need to make sure that the sequence of gathering remote leaders (from RoutingTableSnapshot of each DC) and updating the map is an atomic operation.

      rwLockForLeaderReplicaUpdates.writeLock().lock();
      try {
        for (Map.Entry<String, Set<ReplicaId>> entry : leaderPartitionToPeerLeaderReplicas.entrySet()) {
          String partitionName = entry.getKey();
          Set<ReplicaId> previousPeerLeaderReplicas = entry.getValue();
          Set<ReplicaId> currentPeerLeaderReplicas = getPeerLeaderReplicaSet(partitionName);
          if (!previousPeerLeaderReplicas.equals(currentPeerLeaderReplicas)) {
            logger.info(
                "Refreshing leader Partition {} and list of peer leader replicas {} on node {} in an in-memory map",
                partitionName, currentPeerLeaderReplicas, dataNodeId);
            leaderPartitionToPeerLeaderReplicas.put(partitionName, currentPeerLeaderReplicas);
          }
        }
      } finally {
        rwLockForLeaderReplicaUpdates.writeLock().unlock();
      }
    }
Refreshes the list of remote leaders for all leader partitions by querying the latest information from
RoutingTableSnapshots of all data centers. This method is thread safe.
ambry-replication/src/main/java/com/github/ambry/replication/ReplicationEngine.java