/// <summary> /// Checks to see whether any other applications runnable now that the given /// application has been removed from the given queue. /// </summary> /// <remarks> /// Checks to see whether any other applications runnable now that the given /// application has been removed from the given queue. And makes them so. /// 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. /// </remarks> public virtual 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(); } IList <IList <FSAppAttempt> > appsNowMaybeRunnable = new AList <IList <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(); int userNumRunning = usersNumRunnableApps[user]; if (userNumRunning == null) { userNumRunning = 0; } if (userNumRunning == allocConf.GetUserMaxApps(user) - 1) { IList <FSAppAttempt> userWaitingApps = usersNonRunnableApps.Get(user); if (userWaitingApps != null) { appsNowMaybeRunnable.AddItem(userWaitingApps); } } UpdateAppsRunnability(appsNowMaybeRunnable, appsNowMaybeRunnable.Count); }
/// <summary> /// Tracks the given new runnable app for purposes of maintaining max running /// app limits. /// </summary> public virtual void TrackRunnableApp(FSAppAttempt app) { string user = app.GetUser(); FSLeafQueue queue = ((FSLeafQueue)app.GetQueue()); // Increment running counts for all parent queues FSParentQueue parent = queue.GetParent(); while (parent != null) { parent.IncrementRunnableApps(); parent = parent.GetParent(); } int userNumRunnable = usersNumRunnableApps[user]; usersNumRunnableApps[user] = (userNumRunnable == null ? 0 : userNumRunnable) + 1; }
/// <summary> /// Updates the relevant tracking variables after a runnable app with the given /// queue and user has been removed. /// </summary> public virtual void UntrackRunnableApp(FSAppAttempt app) { // Update usersRunnableApps string user = app.GetUser(); int newUserNumRunning = usersNumRunnableApps[user] - 1; if (newUserNumRunning == 0) { Sharpen.Collections.Remove(usersNumRunnableApps, user); } else { usersNumRunnableApps[user] = newUserNumRunning; } // Update runnable app bookkeeping for queues FSLeafQueue queue = ((FSLeafQueue)app.GetQueue()); FSParentQueue parent = queue.GetParent(); while (parent != null) { parent.DecrementRunnableApps(); parent = parent.GetParent(); } }