package com.hubspot.singularity.scheduler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hubspot.singularity.data.DeployManager;
import com.hubspot.singularity.data.RackManager;
import com.hubspot.singularity.data.RequestManager;
import com.hubspot.singularity.data.SlaveManager;
import com.hubspot.singularity.data.TaskManager;
import com.hubspot.singularity.data.usage.UsageManager;

@Singleton
public class SingularityLeaderCacheCoordinator {
  private static final Logger LOG = LoggerFactory.getLogger(SingularityLeaderCacheCoordinator.class);

  private final TaskManager taskManager;
  private final DeployManager deployManager;
  private final RequestManager requestManager;
  private final SlaveManager slaveManager;
  private final RackManager rackManager;
  private final UsageManager usageManager;
  private final SingularityLeaderCache leaderCache;

  @Inject
  public SingularityLeaderCacheCoordinator(TaskManager taskManager,
                                           DeployManager deployManager,
                                           RequestManager requestManager,
                                           SlaveManager slaveManager,
                                           RackManager rackManager,
                                           UsageManager usageManager,
                                           SingularityLeaderCache leaderCache) {
    this.taskManager = taskManager;
    this.deployManager = deployManager;
    this.requestManager = requestManager;
    this.slaveManager = slaveManager;
    this.rackManager = rackManager;
    this.usageManager = usageManager;
    this.leaderCache = leaderCache;
  }

  public void activateLeaderCache() {
    long start = System.currentTimeMillis();
    taskManager.activateLeaderCache();
    deployManager.activateLeaderCache();
    requestManager.activateLeaderCache();
    slaveManager.activateLeaderCache();
    rackManager.activateLeaderCache();
    usageManager.activateLeaderCache();
    leaderCache.activate();
    LOG.info("Populated leader cache after {}ms", System.currentTimeMillis() - start);
  }

  public void stopLeaderCache() {
    leaderCache.stop();
  }

  public void clear() {
    leaderCache.clear();
  }
}

@@ -48,126 +48,426 @@
 ort 
-org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport com.google.inject.Inject;%0Aimport com.google.inject.Singleton
+java.util.concurrent.CompletableFuture;%0Aimport java.util.concurrent.ExecutorService;%0Aimport java.util.concurrent.Executors;%0A%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport com.google.common.collect.ImmutableList;%0Aimport com.google.common.util.concurrent.ThreadFactoryBuilder;%0Aimport com.google.inject.Inject;%0Aimport com.google.inject.Singleton;%0Aimport com.hubspot.singularity.async.CompletableFutures
 ;%0Aim
@@ -2119,16 +2119,251 @@
 ();%0A    
+ExecutorService leaderCacheExecutor = Executors.newFixedThreadPool(6, new ThreadFactoryBuilder().setNameFormat(%22leader-cache-%25d%22).build());%0A    CompletableFutures.allOf(%0A        ImmutableList.of(%0A            CompletableFuture.runAsync(
 taskMana
@@ -2357,33 +2357,34 @@
 sync(taskManager
-.
+::
 activateLeaderCa
@@ -2386,24 +2386,79 @@
 derCache
-();%0A    
+, leaderCacheExecutor),%0A            CompletableFuture.runAsync(
 deployMa
@@ -2458,25 +2458,26 @@
 eployManager
-.
+::
 activateLead
@@ -2483,24 +2483,79 @@
 derCache
-();%0A    
+, leaderCacheExecutor),%0A            CompletableFuture.runAsync(
 requestM
@@ -2556,25 +2556,26 @@
 questManager
-.
+::
 activateLead
@@ -2581,24 +2581,79 @@
 derCache
-();%0A    
+, leaderCacheExecutor),%0A            CompletableFuture.runAsync(
 slaveMan
@@ -2648,33 +2648,34 @@
 ync(slaveManager
-.
+::
 activateLeaderCa
@@ -2677,24 +2677,79 @@
 derCache
-();%0A    
+, leaderCacheExecutor),%0A            CompletableFuture.runAsync(
 rackMana
@@ -2747,25 +2747,26 @@
 (rackManager
-.
+::
 activateLead
@@ -2772,24 +2772,79 @@
 derCache
-();%0A    
+, leaderCacheExecutor),%0A            CompletableFuture.runAsync(
 usageMan
@@ -2847,17 +2847,18 @@
 eManager
-.
+::
 activate
@@ -2872,39 +2872,238 @@
 ache
-();%0A    leaderCache.activate();
+, leaderCacheExecutor)%0A        )%0A    ).join();%0A    leaderCache.activate();%0A    try %7B%0A      leaderCacheExecutor.shutdown();%0A    %7D catch (Throwable t) %7B%0A      LOG.error(%22Unable to properly shut down leader cache executor%22, t);%0A    %7D
 %0A   

load the leader cache in parallel