public void start()
  {
    synchronized (lifecycleLock) {
      if (!lifecycleLock.canStart()) {
        throw new ISE("LookupCoordinatorManager can't start.");
      }

      try {
        LOG.debug("Starting.");

        if (lookupNodeDiscovery == null) {
          lookupNodeDiscovery = new LookupNodeDiscovery(druidNodeDiscoveryProvider);
        }

        //first ensure that previous executorService from last cycle of start/stop has finished completely.
        //so that we don't have multiple live executorService instances lying around doing lookup management.
        if (executorService != null &&
            !executorService.awaitTermination(
                lookupCoordinatorManagerConfig.getHostTimeout().getMillis() * 10,
                TimeUnit.MILLISECONDS
            )) {
          throw new ISE("WTF! LookupCoordinatorManager executor from last start() hasn't finished. Failed to Start.");
        }

        executorService = MoreExecutors.listeningDecorator(
            Executors.newScheduledThreadPool(
                lookupCoordinatorManagerConfig.getThreadPoolSize(),
                Execs.makeThreadFactory("LookupCoordinatorManager--%s")
            )
        );

        initializeLookupsConfigWatcher();

        this.backgroundManagerExitedLatch = new CountDownLatch(1);
        this.backgroundManagerFuture = executorService.scheduleWithFixedDelay(
            this::lookupManagementLoop,
            lookupCoordinatorManagerConfig.getInitialDelay(),
            lookupCoordinatorManagerConfig.getPeriod(),
            TimeUnit.MILLISECONDS
        );
        Futures.addCallback(
            backgroundManagerFuture,
            new FutureCallback<Object>()
            {
              @Override
              public void onSuccess(@Nullable Object result)
              {
                backgroundManagerExitedLatch.countDown();
                LOG.debug("Exited background lookup manager");
              }

              @Override
              public void onFailure(Throwable t)
              {
                backgroundManagerExitedLatch.countDown();
                if (backgroundManagerFuture.isCancelled()) {
                  LOG.debug("Exited background lookup manager due to cancellation.");
                } else {
                  LOG.makeAlert(t, "Background lookup manager exited with error!").emit();
                }
              }
            }
        );

        LOG.debug("Started");
      }
      catch (Exception ex) {
        LOG.makeAlert(ex, "Got Exception while start()").emit();
      }
      finally {
        //so that subsequent stop() would happen, even if start() failed with exception
        lifecycleLock.started();
        lifecycleLock.exitStart();
      }
    }
  }
public void start ( ) { synchronized ( lifecycleLock ) { if ( ! lifecycleLock . canStart ( ) ) { throw new ISE ( "LookupCoordinatorManager can't start." ) ; } try { LOG . debug ( "Starting." ) ; if ( lookupNodeDiscovery == null ) { lookupNodeDiscovery = new LookupNodeDiscovery ( druidNodeDiscoveryProvider ) ; } if ( executorService != null && ! executorService . awaitTermination ( lookupCoordinatorManagerConfig . getHostTimeout ( ) . getMillis ( ) * 10 , TimeUnit . MILLISECONDS ) ) { throw new ISE ( "WTF! LookupCoordinatorManager executor from last start() hasn't finished. Failed to Start." ) ; } executorService = MoreExecutors . listeningDecorator ( Executors . newScheduledThreadPool ( lookupCoordinatorManagerConfig . getThreadPoolSize ( ) , Execs . makeThreadFactory ( "LookupCoordinatorManager--%s" ) ) ) ; initializeLookupsConfigWatcher ( ) ; this . backgroundManagerExitedLatch = new CountDownLatch ( 1 ) ; this . backgroundManagerFuture = executorService . scheduleWithFixedDelay ( this :: lookupManagementLoop , lookupCoordinatorManagerConfig . getInitialDelay ( ) , lookupCoordinatorManagerConfig . getPeriod ( ) , TimeUnit . MILLISECONDS ) ; Futures . addCallback ( backgroundManagerFuture , new FutureCallback < Object > ( ) { @ Override public void onSuccess ( @ Nullable Object result ) { backgroundManagerExitedLatch . countDown ( ) ; LOG . debug ( "Exited background lookup manager" ) ; } @ Override public void onFailure ( Throwable t ) { backgroundManagerExitedLatch . countDown ( ) ; if ( backgroundManagerFuture . isCancelled ( ) ) { LOG . debug ( "Exited background lookup manager due to cancellation." ) ; } else { LOG . makeAlert ( t , "Background lookup manager exited with error!" ) . emit ( ) ; } } } ) ; LOG . debug ( "Started" ) ; } catch ( Exception ex ) { LOG . makeAlert ( ex , "Got Exception while start()" ) . emit ( ) ; } finally { lifecycleLock . started ( ) ; lifecycleLock . exitStart ( ) ; } } }
coordinator becomes leader and drops leadership in quick succession.