/** * Checks to see whether any other applications runnable now that the given application has been * removed from the given queue. And makes them so. * * <p>Runs in O(n log(n)) where n is the number of queues that are under the highest queue that * went from having no slack to having slack. */ public void updateRunnabilityOnAppRemoval(FSAppAttempt app, FSLeafQueue queue) { AllocationConfiguration allocConf = scheduler.getAllocationConfiguration(); // childqueueX might have no pending apps itself, but if a queue higher up // in the hierarchy parentqueueY has a maxRunningApps set, an app completion // in childqueueX could allow an app in some other distant child of // parentqueueY to become runnable. // An app removal will only possibly allow another app to become runnable if // the queue was already at its max before the removal. // Thus we find the ancestor queue highest in the tree for which the app // that was at its maxRunningApps before the removal. FSQueue highestQueueWithAppsNowRunnable = (queue.getNumRunnableApps() == allocConf.getQueueMaxApps(queue.getName()) - 1) ? queue : null; FSParentQueue parent = queue.getParent(); while (parent != null) { if (parent.getNumRunnableApps() == allocConf.getQueueMaxApps(parent.getName()) - 1) { highestQueueWithAppsNowRunnable = parent; } parent = parent.getParent(); } List<List<FSAppAttempt>> appsNowMaybeRunnable = new ArrayList<List<FSAppAttempt>>(); // Compile lists of apps which may now be runnable // We gather lists instead of building a set of all non-runnable apps so // that this whole operation can be O(number of queues) instead of // O(number of apps) if (highestQueueWithAppsNowRunnable != null) { gatherPossiblyRunnableAppLists(highestQueueWithAppsNowRunnable, appsNowMaybeRunnable); } String user = app.getUser(); Integer userNumRunning = usersNumRunnableApps.get(user); if (userNumRunning == null) { userNumRunning = 0; } if (userNumRunning == allocConf.getUserMaxApps(user) - 1) { List<FSAppAttempt> userWaitingApps = usersNonRunnableApps.get(user); if (userWaitingApps != null) { appsNowMaybeRunnable.add(userWaitingApps); } } updateAppsRunnability(appsNowMaybeRunnable, appsNowMaybeRunnable.size()); }
/** Checks whether making the application runnable would exceed any maxRunningApps limits. */ public boolean canAppBeRunnable(FSQueue queue, String user) { AllocationConfiguration allocConf = scheduler.getAllocationConfiguration(); Integer userNumRunnable = usersNumRunnableApps.get(user); if (userNumRunnable == null) { userNumRunnable = 0; } if (userNumRunnable >= allocConf.getUserMaxApps(user)) { return false; } // Check queue and all parent queues while (queue != null) { int queueMaxApps = allocConf.getQueueMaxApps(queue.getName()); if (queue.getNumRunnableApps() >= queueMaxApps) { return false; } queue = queue.getParent(); } return true; }