code: @VisibleForTesting
    void handleLeadershipChange(NotificationContext changeContext) {
      this.metrics.clusterLeadershipChange.update(1);
      if (this.managerClusterHelixManager.isLeader()) {
        // can get multiple notifications on a leadership change,
        // so only start the application launcher the first time
        // the notification is received
        log.info("Leader notification for {} isLeader {} HM.isLeader {}",
            managerClusterHelixManager.getInstanceName(),
            isLeader,
            managerClusterHelixManager.isLeader());
  
        if (!isLeader) {
          log.info("New Helix Controller leader {}", this.managerClusterHelixManager.getInstanceName());
  
          cleanUpJobs(this.jobClusterHelixManager);
  
          if (this.taskDriverHelixManager.isPresent()) {
            cleanUpJobs(this.taskDriverHelixManager.get());
          }
  
          for (LeadershipChangeAwareComponent c: this.leadershipChangeAwareComponents) {
            c.becomeActive();
          }
  
          isLeader = true;
        }
      } else {
        // stop and reinitialize services since they are not restartable
        // this prepares them to start when this cluster manager becomes a leader
        if (isLeader) {
          isLeader = false;
          for (LeadershipChangeAwareComponent c: this.leadershipChangeAwareComponents) {
            c.becomeStandby();
          }
        }
      }
    }
docs: Handle leadership change.
  The applicationLauncher is only started on the leader.
  The leader cleans up existing jobs before starting the applicationLauncher.
  @param changeContext notification context