public boolean shouldKickNewTaskOnHost(long timeOnQueue, HostState host) { synchronized (hostAvailSlots) { if (hostAvailSlots.containsKey(host.getHostUuid()) && hostAvailSlots.get(host.getHostUuid()) <= 1) { if (host.getMaxTaskSlots() == 1) { // If a host has only one slot to begin with, allow tasks to kick there. return true; } // Otherwise, don't let new tasks take the last slot for a set period return timeOnQueue > SPAWN_QUEUE_NEW_TASK_LAST_SLOT_DELAY; } return true; } }
/** * Out of a list of possible hosts to run a task, find the best one. * * @param inputHosts The legal hosts for a task * @param requireAvailableSlot Whether to require at least one available slot * @return One of the hosts, if one with free slots is found; null otherwise */ public HostState findBestHostToRunTask(List<HostState> inputHosts, boolean requireAvailableSlot) { if (inputHosts == null || inputHosts.isEmpty()) { return null; } synchronized (hostAvailSlots) { HostState bestHost = Collections.min(inputHosts, hostStateComparator); if (bestHost != null) { if (!requireAvailableSlot || hostAvailSlots.containsKey(bestHost.getHostUuid()) && hostAvailSlots.get(bestHost.getHostUuid()) > 0) { return bestHost; } } return null; } }
/** * Update the available slots for each host if it has been sufficiently long since the last * update. * * @param hosts The hosts to input */ public void updateAllHostAvailSlots(List<HostState> hosts) { synchronized (hostAvailSlots) { if (JitterClock.globalTime() - lastAvailSlotsUpdate < SPAWN_QUEUE_AVAIL_REFRESH) { return; } hostAvailSlots.clear(); for (HostState host : hosts) { String hostID = host.getHostUuid(); if (hostID != null) { hostAvailSlots.put(hostID, host.getAvailableTaskSlots()); } } } lastAvailSlotsUpdate = JitterClock.globalTime(); if (log.isTraceEnabled()) { log.trace("[SpawnQueuesByPriority] Host Avail Slots: " + hostAvailSlots); } }
@Override public int compare(HostState o1, HostState o2) { int hostAvailSlots1 = hostAvailSlots.containsKey(o1.getHostUuid()) ? hostAvailSlots.get(o1.getHostUuid()) : 0; int hostAvailSlots2 = hostAvailSlots.containsKey(o2.getHostUuid()) ? hostAvailSlots.get(o2.getHostUuid()) : 0; if (hostAvailSlots1 != hostAvailSlots2) { return Integer.compare( -hostAvailSlots1, -hostAvailSlots2); // Return hosts with large number of slots first } else { return Double.compare( o1.getMeanActiveTasks(), o2.getMeanActiveTasks()); // Return hosts with small meanActiveTask value first } }