@Override
  public void addDataNodeConfigChangeListener(DataNodeConfigChangeListener listener) throws Exception {
    if (recordingListenersRegistered.compareAndSet(false, true)) {
      ConfigChangeRecorder primaryListener = new ConfigChangeRecorder(listener);
      ConfigChangeRecorder secondaryListener = new ConfigChangeRecorder(null);
      primarySource.addDataNodeConfigChangeListener(primaryListener);
      try {
        secondarySource.addDataNodeConfigChangeListener(secondaryListener);
        Utils.newThread("DataNodeConfigConsistencyChecker",
            new ConsistencyChecker(time, metrics, primaryListener, secondaryListener), false).start();
      } catch (Exception e) {
        metrics.addListenerSwallowedErrorCount.inc();
        LOGGER.error("Error from secondarySource.addDataNodeConfigChangeListener({})", listener, e);
      }
    } else {
      // only set up consistency checking for the first listener. Other listeners will just use with the primary src
      primarySource.addDataNodeConfigChangeListener(listener);
    }
  }
@param primarySource the source of truth for users of this class.
@param secondarySource all operations are also attempted against this source, but if the results of the operation
                       differ from the primary, inconsistencies are just recorded with logs and metrics.
@param time a {@link Time} instance used for consistency verification.
@param metrics a {@link DataNodeConfigSourceMetrics} instance to use.
ambry-clustermap/src/main/java/com/github/ambry/clustermap/CompositeDataNodeConfigSource.java