package com.hubspot.singularity.scheduler; import java.util.Collection; import java.util.List; import java.util.Map; import com.google.common.base.Optional; import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.google.inject.Inject; import com.hubspot.singularity.MachineState; import com.hubspot.singularity.SingularityKilledTaskIdRecord; import com.hubspot.singularity.SingularityPendingTask; import com.hubspot.singularity.SingularityRack; import com.hubspot.singularity.SingularitySlave; import com.hubspot.singularity.SingularityTaskId; import com.hubspot.singularity.data.RackManager; import com.hubspot.singularity.data.SlaveManager; import com.hubspot.singularity.data.TaskManager; public class SingularitySchedulerStateCache { private final TaskManager taskManager; private final SlaveManager slaveManager; private final RackManager rackManager; private final Map<String, Optional<SingularitySlave>> slaveCache; private final Map<String, Optional<SingularityRack>> rackCache; private Optional<Collection<SingularityTaskId>> activeTaskIds; private Optional<Collection<SingularityPendingTask>> scheduledTasks; private Optional<Collection<SingularityTaskId>> cleaningTasks; private Optional<Collection<SingularityTaskId>> killedTasks; private Optional<Integer> numActiveRacks; private Optional<Integer> numActiveSlaves; private Optional<Multimap<String, SingularityTaskId>> requestToActiveTaskIds; @Inject public SingularitySchedulerStateCache(TaskManager taskManager, SlaveManager slaveManager, RackManager rackManager) { this.taskManager = taskManager; this.slaveManager = slaveManager; this.rackManager = rackManager; activeTaskIds = Optional.absent(); scheduledTasks = Optional.absent(); cleaningTasks = Optional.absent(); killedTasks = Optional.absent(); numActiveRacks = Optional.absent(); numActiveSlaves = Optional.absent(); slaveCache = Maps.newHashMap(); rackCache = Maps.newHashMap(); requestToActiveTaskIds = Optional.absent(); } public Collection<SingularityTaskId> getActiveTaskIdsForRequest(String requestId) { if (!requestToActiveTaskIds.isPresent()) { Multimap<String, SingularityTaskId> requestToActiveTaskIdsLocal = HashMultimap.create(); for (SingularityTaskId taskId : getActiveTaskIds()) { requestToActiveTaskIdsLocal.put(taskId.getRequestId(), taskId); } requestToActiveTaskIds = Optional.of(requestToActiveTaskIdsLocal); } return requestToActiveTaskIds.get().get(requestId); } public Collection<SingularityTaskId> getActiveTaskIds() { if (!activeTaskIds.isPresent()) { activeTaskIds = getMutableCollection(taskManager.getActiveTaskIds()); } return activeTaskIds.get(); } public Collection<SingularityPendingTask> getScheduledTasks() { if (!scheduledTasks.isPresent()) { scheduledTasks = getMutableCollection(taskManager.getPendingTasks()); } return scheduledTasks.get(); } private <T> Optional<Collection<T>> getMutableCollection(List<T> immutableList) { Collection<T> mutableSet = Sets.newHashSet(immutableList); return Optional.of(mutableSet); } public Collection<SingularityTaskId> getCleaningTasks() { if (!cleaningTasks.isPresent()) { cleaningTasks = getMutableCollection(taskManager.getCleanupTaskIds()); } return cleaningTasks.get(); } public Collection<SingularityTaskId> getKilledTasks() { if (!killedTasks.isPresent()) { List<SingularityKilledTaskIdRecord> killedTaskRecords = taskManager.getKilledTaskIdRecords(); Collection<SingularityTaskId> taskIds = Sets.newHashSet(); for (SingularityKilledTaskIdRecord record : killedTaskRecords) { taskIds.add(record.getTaskId()); } killedTasks = Optional.of(taskIds); } return killedTasks.get(); } public int getNumActiveRacks() { if (numActiveRacks.isPresent()) { return numActiveRacks.get(); } numActiveRacks = Optional.of(rackManager.getNumObjectsAtState(MachineState.ACTIVE)); return numActiveRacks.get(); } public int getNumActiveSlaves() { if (numActiveSlaves.isPresent()) { return numActiveSlaves.get(); } numActiveSlaves = Optional.of(slaveManager.getNumObjectsAtState(MachineState.ACTIVE)); return numActiveSlaves.get(); } public Optional<SingularitySlave> getSlave(String slaveId) { if (!slaveCache.containsKey(slaveId)) { slaveCache.put(slaveId, slaveManager.getObject(slaveId)); } return slaveCache.get(slaveId); } public Optional<SingularityRack> getRack(String rackId) { if (!rackCache.containsKey(rackId)) { rackCache.put(rackId, rackManager.getObject(rackId)); } return rackCache.get(rackId); } }