@Override
  protected void persist(String mountPath, List<ReplicaTokenInfo> tokenInfoList) throws IOException {
    File temp = new File(mountPath, replicaTokenFileName + ".tmp");
    File actual = new File(mountPath, replicaTokenFileName);
    try (FileOutputStream fileStream = new FileOutputStream(temp)) {
      replicaTokenSerde.serializeTokens(tokenInfoList, fileStream);

      // swap temp file with the original file
      temp.renameTo(actual);
      logger.debug("Completed writing replica tokens to file {}", actual.getAbsolutePath());
    } catch (IOException e) {
      logger.error("IO error while persisting tokens to disk {}", temp.getAbsoluteFile());
      Iterator<PartitionInfo> partitioninfoIterator = partitionGroupedByMountPath.get(mountPath).iterator();
      if (!partitioninfoIterator.hasNext()) {
        // If no partition exists but we had experienced an IO exception, this mount path should still be skipped
        mountPathsToSkip.add(mountPath);
        logger.error("No partition information found for mount path {}", mountPath);
      } else {
        PartitionInfo partitionInfo = partitioninfoIterator.next();
        if (storeManager.checkLocalPartitionStatus(partitionInfo.getPartitionId(), partitionInfo.getLocalReplicaId())
            == ServerErrorCode.DiskUnavailable) {
          // check disk state in storeManager. If checkLocalPartitionStatus returns Disk_Unavailable, it means all stores on
          // this disk are unreachable due to hardware issues. In this case, persistor should skip the bad disk next time.
          mountPathsToSkip.add(mountPath);
        }
      }
      throw e;
    }
  }
Constructor for {@link DiskTokenPersistor}.
@param replicaTokenFileName the token's file name.
@param partitionGroupedByMountPath A map between mount path and list of partitions under this mount path.
@param replicationMetrics metrics including token persist time.
@param clusterMap the {@link ClusterMap} to deserialize tokens.
@param tokenHelper the {@link FindTokenHelper} to deserialize tokens.
@param storeManager the {@link StoreManager} that manages disks and stores.
ambry-replication/src/main/java/com/github/ambry/replication/DiskTokenPersistor.java