소스 검색

YARN-2975. FSLeafQueue app lists are accessed without required locks. (kasha)

Karthik Kambatla 10 년 전
부모
커밋
24ee9e3431
8개의 변경된 파일200개의 추가작업 그리고 104개의 파일을 삭제
  1. 2 0
      hadoop-yarn-project/CHANGES.txt
  2. 131 17
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java
  3. 3 7
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java
  4. 4 4
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/MaxRunningAppsEnforcer.java
  5. 1 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java
  6. 2 12
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/FairSchedulerLeafQueueInfo.java
  7. 25 31
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java
  8. 32 32
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestMaxRunningAppsEnforcer.java

+ 2 - 0
hadoop-yarn-project/CHANGES.txt

@@ -256,6 +256,8 @@ Release 2.7.0 - UNRELEASED
     YARN-2952. Fixed incorrect version check in StateStore. (Rohith Sharmaks
     YARN-2952. Fixed incorrect version check in StateStore. (Rohith Sharmaks
     via jianhe)
     via jianhe)
 
 
+    YARN-2975. FSLeafQueue app lists are accessed without required locks. (kasha)
+
 Release 2.6.1 - Unreleased
 Release 2.6.1 - Unreleased
 
 
   INCOMPATIBLE CHANGES
   INCOMPATIBLE CHANGES

+ 131 - 17
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FSLeafQueue.java

@@ -107,34 +107,94 @@ public class FSLeafQueue extends FSQueue {
    */
    */
   public boolean removeApp(FSAppAttempt app) {
   public boolean removeApp(FSAppAttempt app) {
     boolean runnable = false;
     boolean runnable = false;
+
+    // Remove app from runnable/nonRunnable list while holding the write lock
     writeLock.lock();
     writeLock.lock();
     try {
     try {
-      if (runnableApps.remove(app)) {
-        runnable = true;
-      } else if (nonRunnableApps.remove(app)) {
-        runnable = false; //nop, runnable is initialised to false already
-      } else {
-        throw new IllegalStateException("Given app to remove " + app +
-            " does not exist in queue " + this);
+      runnable = runnableApps.remove(app);
+      if (!runnable) {
+        // removeNonRunnableApp acquires the write lock again, which is fine
+        if (!removeNonRunnableApp(app)) {
+          throw new IllegalStateException("Given app to remove " + app +
+              " does not exist in queue " + this);
+        }
       }
       }
     } finally {
     } finally {
       writeLock.unlock();
       writeLock.unlock();
     }
     }
+
     // Update AM resource usage if needed
     // Update AM resource usage if needed
     if (runnable && app.isAmRunning() && app.getAMResource() != null) {
     if (runnable && app.isAmRunning() && app.getAMResource() != null) {
       Resources.subtractFrom(amResourceUsage, app.getAMResource());
       Resources.subtractFrom(amResourceUsage, app.getAMResource());
     }
     }
+
     return runnable;
     return runnable;
   }
   }
-  
-  public Collection<FSAppAttempt> getRunnableAppSchedulables() {
-    return runnableApps;
+
+  /**
+   * Removes the given app if it is non-runnable and belongs to this queue
+   * @return true if the app is removed, false otherwise
+   */
+  public boolean removeNonRunnableApp(FSAppAttempt app) {
+    writeLock.lock();
+    try {
+      return nonRunnableApps.remove(app);
+    } finally {
+      writeLock.unlock();
+    }
   }
   }
-  
-  public List<FSAppAttempt> getNonRunnableAppSchedulables() {
-    return nonRunnableApps;
+
+  public boolean isRunnableApp(FSAppAttempt attempt) {
+    readLock.lock();
+    try {
+      return runnableApps.contains(attempt);
+    } finally {
+      readLock.unlock();
+    }
   }
   }
-  
+
+  public boolean isNonRunnableApp(FSAppAttempt attempt) {
+    readLock.lock();
+    try {
+      return nonRunnableApps.contains(attempt);
+    } finally {
+      readLock.unlock();
+    }
+  }
+
+  public void resetPreemptedResources() {
+    readLock.lock();
+    try {
+      for (FSAppAttempt attempt : runnableApps) {
+        attempt.resetPreemptedResources();
+      }
+    } finally {
+      readLock.unlock();
+    }
+  }
+
+  public void clearPreemptedResources() {
+    readLock.lock();
+    try {
+      for (FSAppAttempt attempt : runnableApps) {
+        attempt.clearPreemptedResources();
+      }
+    } finally {
+      readLock.unlock();
+    }
+  }
+
+  public List<FSAppAttempt> getCopyOfNonRunnableAppSchedulables() {
+    List<FSAppAttempt> appsToReturn = new ArrayList<FSAppAttempt>();
+    readLock.lock();
+    try {
+      appsToReturn.addAll(nonRunnableApps);
+    } finally {
+      readLock.unlock();
+    }
+    return appsToReturn;
+  }
+
   @Override
   @Override
   public void collectSchedulerApplications(
   public void collectSchedulerApplications(
       Collection<ApplicationAttemptId> apps) {
       Collection<ApplicationAttemptId> apps) {
@@ -162,7 +222,12 @@ public class FSLeafQueue extends FSQueue {
   
   
   @Override
   @Override
   public void recomputeShares() {
   public void recomputeShares() {
-    policy.computeShares(getRunnableAppSchedulables(), getFairShare());
+    readLock.lock();
+    try {
+      policy.computeShares(runnableApps, getFairShare());
+    } finally {
+      readLock.unlock();
+    }
   }
   }
 
 
   @Override
   @Override
@@ -349,9 +414,58 @@ public class FSLeafQueue extends FSQueue {
 
 
   @Override
   @Override
   public int getNumRunnableApps() {
   public int getNumRunnableApps() {
-    return runnableApps.size();
+    readLock.lock();
+    try {
+      return runnableApps.size();
+    } finally {
+      readLock.unlock();
+    }
   }
   }
-  
+
+  public int getNumNonRunnableApps() {
+    readLock.lock();
+    try {
+      return nonRunnableApps.size();
+    } finally {
+      readLock.unlock();
+    }
+  }
+
+  public int getNumPendingApps() {
+    int numPendingApps = 0;
+    readLock.lock();
+    try {
+      for (FSAppAttempt attempt : runnableApps) {
+        if (attempt.isPending()) {
+          numPendingApps++;
+        }
+      }
+      numPendingApps += nonRunnableApps.size();
+    } finally {
+      readLock.unlock();
+    }
+    return numPendingApps;
+  }
+
+  /**
+   * TODO: Based on how frequently this is called, we might want to club
+   * counting pending and active apps in the same method.
+   */
+  public int getNumActiveApps() {
+    int numActiveApps = 0;
+    readLock.lock();
+    try {
+      for (FSAppAttempt attempt : runnableApps) {
+        if (!attempt.isPending()) {
+          numActiveApps++;
+        }
+      }
+    } finally {
+      readLock.unlock();
+    }
+    return numActiveApps;
+  }
+
   @Override
   @Override
   public ActiveUsersManager getActiveUsersManager() {
   public ActiveUsersManager getActiveUsersManager() {
     return activeUsersManager;
     return activeUsersManager;

+ 3 - 7
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/FairScheduler.java

@@ -400,9 +400,7 @@ public class FairScheduler extends
     try {
     try {
       // Reset preemptedResource for each app
       // Reset preemptedResource for each app
       for (FSLeafQueue queue : getQueueManager().getLeafQueues()) {
       for (FSLeafQueue queue : getQueueManager().getLeafQueues()) {
-        for (FSAppAttempt app : queue.getRunnableAppSchedulables()) {
-          app.resetPreemptedResources();
-        }
+        queue.resetPreemptedResources();
       }
       }
 
 
       while (Resources.greaterThan(RESOURCE_CALCULATOR, clusterResource,
       while (Resources.greaterThan(RESOURCE_CALCULATOR, clusterResource,
@@ -421,9 +419,7 @@ public class FairScheduler extends
     } finally {
     } finally {
       // Clear preemptedResources for each app
       // Clear preemptedResources for each app
       for (FSLeafQueue queue : getQueueManager().getLeafQueues()) {
       for (FSLeafQueue queue : getQueueManager().getLeafQueues()) {
-        for (FSAppAttempt app : queue.getRunnableAppSchedulables()) {
-          app.clearPreemptedResources();
-        }
+        queue.clearPreemptedResources();
       }
       }
     }
     }
 
 
@@ -1453,7 +1449,7 @@ public class FairScheduler extends
         return oldQueue.getQueueName();
         return oldQueue.getQueueName();
       }
       }
       
       
-      if (oldQueue.getRunnableAppSchedulables().contains(attempt)) {
+      if (oldQueue.isRunnableApp(attempt)) {
         verifyMoveDoesNotViolateConstraints(attempt, oldQueue, targetQueue);
         verifyMoveDoesNotViolateConstraints(attempt, oldQueue, targetQueue);
       }
       }
       
       

+ 4 - 4
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/MaxRunningAppsEnforcer.java

@@ -170,7 +170,7 @@ public class MaxRunningAppsEnforcer {
       if (canAppBeRunnable(next.getQueue(), next.getUser())) {
       if (canAppBeRunnable(next.getQueue(), next.getUser())) {
         trackRunnableApp(next);
         trackRunnableApp(next);
         FSAppAttempt appSched = next;
         FSAppAttempt appSched = next;
-        next.getQueue().getRunnableAppSchedulables().add(appSched);
+        next.getQueue().addApp(appSched, true);
         noLongerPendingApps.add(appSched);
         noLongerPendingApps.add(appSched);
 
 
         // No more than one app per list will be able to be made runnable, so
         // No more than one app per list will be able to be made runnable, so
@@ -187,8 +187,7 @@ public class MaxRunningAppsEnforcer {
     // pull them out from under the iterator.  If they are not in these lists
     // pull them out from under the iterator.  If they are not in these lists
     // in the first place, there is a bug.
     // in the first place, there is a bug.
     for (FSAppAttempt appSched : noLongerPendingApps) {
     for (FSAppAttempt appSched : noLongerPendingApps) {
-      if (!appSched.getQueue().getNonRunnableAppSchedulables()
-          .remove(appSched)) {
+      if (!appSched.getQueue().removeNonRunnableApp(appSched)) {
         LOG.error("Can't make app runnable that does not already exist in queue"
         LOG.error("Can't make app runnable that does not already exist in queue"
             + " as non-runnable: " + appSched + ". This should never happen.");
             + " as non-runnable: " + appSched + ". This should never happen.");
       }
       }
@@ -239,7 +238,8 @@ public class MaxRunningAppsEnforcer {
     if (queue.getNumRunnableApps() < scheduler.getAllocationConfiguration()
     if (queue.getNumRunnableApps() < scheduler.getAllocationConfiguration()
         .getQueueMaxApps(queue.getName())) {
         .getQueueMaxApps(queue.getName())) {
       if (queue instanceof FSLeafQueue) {
       if (queue instanceof FSLeafQueue) {
-        appLists.add(((FSLeafQueue)queue).getNonRunnableAppSchedulables());
+        appLists.add(
+            ((FSLeafQueue)queue).getCopyOfNonRunnableAppSchedulables());
       } else {
       } else {
         for (FSQueue child : queue.getChildQueues()) {
         for (FSQueue child : queue.getChildQueues()) {
           gatherPossiblyRunnableAppLists(child, appLists);
           gatherPossiblyRunnableAppLists(child, appLists);

+ 1 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/QueueManager.java

@@ -297,7 +297,7 @@ public class QueueManager {
     if (queue instanceof FSLeafQueue) {
     if (queue instanceof FSLeafQueue) {
       FSLeafQueue leafQueue = (FSLeafQueue)queue;
       FSLeafQueue leafQueue = (FSLeafQueue)queue;
       return queue.getNumRunnableApps() == 0 &&
       return queue.getNumRunnableApps() == 0 &&
-          leafQueue.getNonRunnableAppSchedulables().isEmpty();
+          leafQueue.getNumNonRunnableApps() == 0;
     } else {
     } else {
       for (FSQueue child : queue.getChildQueues()) {
       for (FSQueue child : queue.getChildQueues()) {
         if (!isEmpty(child)) {
         if (!isEmpty(child)) {

+ 2 - 12
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/dao/FairSchedulerLeafQueueInfo.java

@@ -18,14 +18,11 @@
 
 
 package org.apache.hadoop.yarn.server.resourcemanager.webapp.dao;
 package org.apache.hadoop.yarn.server.resourcemanager.webapp.dao;
 
 
-import java.util.Collection;
 
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
 
-import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair
-    .FSAppAttempt;
 import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler;
 import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler;
 import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FSLeafQueue;
 import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FSLeafQueue;
 
 
@@ -40,15 +37,8 @@ public class FairSchedulerLeafQueueInfo extends FairSchedulerQueueInfo {
   
   
   public FairSchedulerLeafQueueInfo(FSLeafQueue queue, FairScheduler scheduler) {
   public FairSchedulerLeafQueueInfo(FSLeafQueue queue, FairScheduler scheduler) {
     super(queue, scheduler);
     super(queue, scheduler);
-    Collection<FSAppAttempt> apps = queue.getRunnableAppSchedulables();
-    for (FSAppAttempt app : apps) {
-      if (app.isPending()) {
-        numPendingApps++;
-      } else {
-        numActiveApps++;
-      }
-    }
-    numPendingApps += queue.getNonRunnableAppSchedulables().size();
+    numPendingApps = queue.getNumPendingApps();
+    numActiveApps = queue.getNumActiveApps();
   }
   }
   
   
   public int getNumActiveApplications() {
   public int getNumActiveApplications() {

+ 25 - 31
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestFairScheduler.java

@@ -872,9 +872,9 @@ public class TestFairScheduler extends FairSchedulerTestBase {
     ApplicationAttemptId appAttemptId = createAppAttemptId(1, 1);
     ApplicationAttemptId appAttemptId = createAppAttemptId(1, 1);
     createApplicationWithAMResource(appAttemptId, "default", "user1", null);
     createApplicationWithAMResource(appAttemptId, "default", "user1", null);
     assertEquals(1, scheduler.getQueueManager().getLeafQueue("user1", true)
     assertEquals(1, scheduler.getQueueManager().getLeafQueue("user1", true)
-        .getRunnableAppSchedulables().size());
+        .getNumRunnableApps());
     assertEquals(0, scheduler.getQueueManager().getLeafQueue("default", true)
     assertEquals(0, scheduler.getQueueManager().getLeafQueue("default", true)
-        .getRunnableAppSchedulables().size());
+        .getNumRunnableApps());
     assertEquals("root.user1", resourceManager.getRMContext().getRMApps()
     assertEquals("root.user1", resourceManager.getRMContext().getRMApps()
         .get(appAttemptId.getApplicationId()).getQueue());
         .get(appAttemptId.getApplicationId()).getQueue());
   }
   }
@@ -888,11 +888,11 @@ public class TestFairScheduler extends FairSchedulerTestBase {
     ApplicationAttemptId appAttemptId = createAppAttemptId(1, 1);
     ApplicationAttemptId appAttemptId = createAppAttemptId(1, 1);
     createApplicationWithAMResource(appAttemptId, "default", "user2", null);
     createApplicationWithAMResource(appAttemptId, "default", "user2", null);
     assertEquals(0, scheduler.getQueueManager().getLeafQueue("user1", true)
     assertEquals(0, scheduler.getQueueManager().getLeafQueue("user1", true)
-        .getRunnableAppSchedulables().size());
+        .getNumRunnableApps());
     assertEquals(1, scheduler.getQueueManager().getLeafQueue("default", true)
     assertEquals(1, scheduler.getQueueManager().getLeafQueue("default", true)
-        .getRunnableAppSchedulables().size());
+        .getNumRunnableApps());
     assertEquals(0, scheduler.getQueueManager().getLeafQueue("user2", true)
     assertEquals(0, scheduler.getQueueManager().getLeafQueue("user2", true)
-        .getRunnableAppSchedulables().size());
+        .getNumRunnableApps());
   }
   }
 
 
   @Test
   @Test
@@ -1370,7 +1370,7 @@ public class TestFairScheduler extends FairSchedulerTestBase {
 
 
     // That queue should have one app
     // That queue should have one app
     assertEquals(1, scheduler.getQueueManager().getLeafQueue("user1", true)
     assertEquals(1, scheduler.getQueueManager().getLeafQueue("user1", true)
-        .getRunnableAppSchedulables().size());
+        .getNumRunnableApps());
 
 
     AppAttemptRemovedSchedulerEvent appRemovedEvent1 = new AppAttemptRemovedSchedulerEvent(
     AppAttemptRemovedSchedulerEvent appRemovedEvent1 = new AppAttemptRemovedSchedulerEvent(
         createAppAttemptId(1, 1), RMAppAttemptState.FINISHED, false);
         createAppAttemptId(1, 1), RMAppAttemptState.FINISHED, false);
@@ -1380,7 +1380,7 @@ public class TestFairScheduler extends FairSchedulerTestBase {
 
 
     // Queue should have no apps
     // Queue should have no apps
     assertEquals(0, scheduler.getQueueManager().getLeafQueue("user1", true)
     assertEquals(0, scheduler.getQueueManager().getLeafQueue("user1", true)
-        .getRunnableAppSchedulables().size());
+        .getNumRunnableApps());
   }
   }
 
 
   @Test
   @Test
@@ -2124,7 +2124,7 @@ public class TestFairScheduler extends FairSchedulerTestBase {
     // The user1 queue should inherit the configurations from the root queue
     // The user1 queue should inherit the configurations from the root queue
     FSLeafQueue userQueue =
     FSLeafQueue userQueue =
         scheduler.getQueueManager().getLeafQueue("user1", true);
         scheduler.getQueueManager().getLeafQueue("user1", true);
-    assertEquals(1, userQueue.getRunnableAppSchedulables().size());
+    assertEquals(1, userQueue.getNumRunnableApps());
     assertEquals(10000, userQueue.getMinSharePreemptionTimeout());
     assertEquals(10000, userQueue.getMinSharePreemptionTimeout());
     assertEquals(15000, userQueue.getFairSharePreemptionTimeout());
     assertEquals(15000, userQueue.getFairSharePreemptionTimeout());
     assertEquals(.6f, userQueue.getFairSharePreemptionThreshold(), 0.001);
     assertEquals(.6f, userQueue.getFairSharePreemptionThreshold(), 0.001);
@@ -3023,21 +3023,15 @@ public class TestFairScheduler extends FairSchedulerTestBase {
   private void verifyAppRunnable(ApplicationAttemptId attId, boolean runnable) {
   private void verifyAppRunnable(ApplicationAttemptId attId, boolean runnable) {
     FSAppAttempt app = scheduler.getSchedulerApp(attId);
     FSAppAttempt app = scheduler.getSchedulerApp(attId);
     FSLeafQueue queue = app.getQueue();
     FSLeafQueue queue = app.getQueue();
-    Collection<FSAppAttempt> runnableApps =
-        queue.getRunnableAppSchedulables();
-    Collection<FSAppAttempt> nonRunnableApps =
-        queue.getNonRunnableAppSchedulables();
-    assertEquals(runnable, runnableApps.contains(app));
-    assertEquals(!runnable, nonRunnableApps.contains(app));
+    assertEquals(runnable, queue.isRunnableApp(app));
+    assertEquals(!runnable, queue.isNonRunnableApp(app));
   }
   }
   
   
   private void verifyQueueNumRunnable(String queueName, int numRunnableInQueue,
   private void verifyQueueNumRunnable(String queueName, int numRunnableInQueue,
       int numNonRunnableInQueue) {
       int numNonRunnableInQueue) {
     FSLeafQueue queue = scheduler.getQueueManager().getLeafQueue(queueName, false);
     FSLeafQueue queue = scheduler.getQueueManager().getLeafQueue(queueName, false);
-    assertEquals(numRunnableInQueue,
-        queue.getRunnableAppSchedulables().size());
-    assertEquals(numNonRunnableInQueue,
-        queue.getNonRunnableAppSchedulables().size());
+    assertEquals(numRunnableInQueue, queue.getNumRunnableApps());
+    assertEquals(numNonRunnableInQueue, queue.getNumNonRunnableApps());
   }
   }
   
   
   @Test
   @Test
@@ -3584,23 +3578,23 @@ public class TestFairScheduler extends FairSchedulerTestBase {
     
     
     // Should get put into jerry
     // Should get put into jerry
     createSchedulingRequest(1024, "jerry", "someuser");
     createSchedulingRequest(1024, "jerry", "someuser");
-    assertEquals(1, jerryQueue.getRunnableAppSchedulables().size());
+    assertEquals(1, jerryQueue.getNumRunnableApps());
 
 
     // Should get forced into default
     // Should get forced into default
     createSchedulingRequest(1024, "newqueue", "someuser");
     createSchedulingRequest(1024, "newqueue", "someuser");
-    assertEquals(1, jerryQueue.getRunnableAppSchedulables().size());
-    assertEquals(1, defaultQueue.getRunnableAppSchedulables().size());
+    assertEquals(1, jerryQueue.getNumRunnableApps());
+    assertEquals(1, defaultQueue.getNumRunnableApps());
     
     
     // Would get put into someuser because of user-as-default-queue, but should
     // Would get put into someuser because of user-as-default-queue, but should
     // be forced into default
     // be forced into default
     createSchedulingRequest(1024, "default", "someuser");
     createSchedulingRequest(1024, "default", "someuser");
-    assertEquals(1, jerryQueue.getRunnableAppSchedulables().size());
-    assertEquals(2, defaultQueue.getRunnableAppSchedulables().size());
+    assertEquals(1, jerryQueue.getNumRunnableApps());
+    assertEquals(2, defaultQueue.getNumRunnableApps());
     
     
     // Should get put into jerry because of user-as-default-queue
     // Should get put into jerry because of user-as-default-queue
     createSchedulingRequest(1024, "default", "jerry");
     createSchedulingRequest(1024, "default", "jerry");
-    assertEquals(2, jerryQueue.getRunnableAppSchedulables().size());
-    assertEquals(2, defaultQueue.getRunnableAppSchedulables().size());
+    assertEquals(2, jerryQueue.getNumRunnableApps());
+    assertEquals(2, defaultQueue.getNumRunnableApps());
   }
   }
 
 
   @Test
   @Test
@@ -3843,8 +3837,8 @@ public class TestFairScheduler extends FairSchedulerTestBase {
     scheduler.moveApplication(appId, "queue2");
     scheduler.moveApplication(appId, "queue2");
     FSAppAttempt app = scheduler.getSchedulerApp(appAttId);
     FSAppAttempt app = scheduler.getSchedulerApp(appAttId);
     assertSame(targetQueue, app.getQueue());
     assertSame(targetQueue, app.getQueue());
-    assertFalse(oldQueue.getRunnableAppSchedulables().contains(app));
-    assertTrue(targetQueue.getRunnableAppSchedulables().contains(app));
+    assertFalse(oldQueue.isRunnableApp(app));
+    assertTrue(targetQueue.isRunnableApp(app));
     assertEquals(Resource.newInstance(0, 0), oldQueue.getResourceUsage());
     assertEquals(Resource.newInstance(0, 0), oldQueue.getResourceUsage());
     assertEquals(Resource.newInstance(1024, 1), targetQueue.getResourceUsage());
     assertEquals(Resource.newInstance(1024, 1), targetQueue.getResourceUsage());
     assertEquals(0, oldQueue.getNumRunnableApps());
     assertEquals(0, oldQueue.getNumRunnableApps());
@@ -3893,12 +3887,12 @@ public class TestFairScheduler extends FairSchedulerTestBase {
         createSchedulingRequest(1024, 1, "queue1", "user1", 3);
         createSchedulingRequest(1024, 1, "queue1", "user1", 3);
     
     
     FSAppAttempt app = scheduler.getSchedulerApp(appAttId);
     FSAppAttempt app = scheduler.getSchedulerApp(appAttId);
-    assertTrue(oldQueue.getNonRunnableAppSchedulables().contains(app));
+    assertTrue(oldQueue.isNonRunnableApp(app));
     
     
     scheduler.moveApplication(appAttId.getApplicationId(), "queue2");
     scheduler.moveApplication(appAttId.getApplicationId(), "queue2");
-    assertFalse(oldQueue.getNonRunnableAppSchedulables().contains(app));
-    assertFalse(targetQueue.getNonRunnableAppSchedulables().contains(app));
-    assertTrue(targetQueue.getRunnableAppSchedulables().contains(app));
+    assertFalse(oldQueue.isNonRunnableApp(app));
+    assertFalse(targetQueue.isNonRunnableApp(app));
+    assertTrue(targetQueue.isRunnableApp(app));
     assertEquals(1, targetQueue.getNumRunnableApps());
     assertEquals(1, targetQueue.getNumRunnableApps());
     assertEquals(1, queueMgr.getRootQueue().getNumRunnableApps());
     assertEquals(1, queueMgr.getRootQueue().getNumRunnableApps());
   }
   }

+ 32 - 32
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/fair/TestMaxRunningAppsEnforcer.java

@@ -97,13 +97,13 @@ public class TestMaxRunningAppsEnforcer {
     FSAppAttempt app1 = addApp(leaf1, "user");
     FSAppAttempt app1 = addApp(leaf1, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
-    assertEquals(1, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(1, leaf1.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumNonRunnableApps());
     removeApp(app1);
     removeApp(app1);
-    assertEquals(0, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(0, leaf1.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumNonRunnableApps());
   }
   }
   
   
   @Test
   @Test
@@ -114,13 +114,13 @@ public class TestMaxRunningAppsEnforcer {
     FSAppAttempt app1 = addApp(leaf1, "user");
     FSAppAttempt app1 = addApp(leaf1, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
-    assertEquals(1, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(1, leaf1.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumNonRunnableApps());
     removeApp(app1);
     removeApp(app1);
-    assertEquals(0, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(2, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(0, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(0, leaf1.getNumRunnableApps());
+    assertEquals(2, leaf2.getNumRunnableApps());
+    assertEquals(0, leaf2.getNumNonRunnableApps());
   }
   }
   
   
   @Test
   @Test
@@ -133,14 +133,14 @@ public class TestMaxRunningAppsEnforcer {
     addApp(leaf1, "user2");
     addApp(leaf1, "user2");
     addApp(leaf1, "user3");
     addApp(leaf1, "user3");
     addApp(leaf2, "user1");
     addApp(leaf2, "user1");
-    assertEquals(2, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf1.getNonRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(2, leaf1.getNumRunnableApps());
+    assertEquals(1, leaf1.getNumNonRunnableApps());
+    assertEquals(1, leaf2.getNumNonRunnableApps());
     removeApp(app1);
     removeApp(app1);
-    assertEquals(2, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(0, leaf1.getNonRunnableAppSchedulables().size());
-    assertEquals(0, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(2, leaf1.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumRunnableApps());
+    assertEquals(0, leaf1.getNumNonRunnableApps());
+    assertEquals(0, leaf2.getNumNonRunnableApps());
   }
   }
   
   
   @Test
   @Test
@@ -153,14 +153,14 @@ public class TestMaxRunningAppsEnforcer {
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     clock.tick(20);
     clock.tick(20);
     addApp(leaf1, "user");
     addApp(leaf1, "user");
-    assertEquals(1, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf1.getNonRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(1, leaf1.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumRunnableApps());
+    assertEquals(1, leaf1.getNumNonRunnableApps());
+    assertEquals(1, leaf2.getNumNonRunnableApps());
     removeApp(app1);
     removeApp(app1);
-    assertEquals(0, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(2, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(0, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(0, leaf1.getNumRunnableApps());
+    assertEquals(2, leaf2.getNumRunnableApps());
+    assertEquals(0, leaf2.getNumNonRunnableApps());
   }
   }
   
   
   @Test
   @Test
@@ -172,13 +172,13 @@ public class TestMaxRunningAppsEnforcer {
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
     addApp(leaf2, "user");
-    assertEquals(1, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(2, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(1, leaf1.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumRunnableApps());
+    assertEquals(2, leaf2.getNumNonRunnableApps());
     removeApp(app1);
     removeApp(app1);
-    assertEquals(0, leaf1.getRunnableAppSchedulables().size());
-    assertEquals(2, leaf2.getRunnableAppSchedulables().size());
-    assertEquals(1, leaf2.getNonRunnableAppSchedulables().size());
+    assertEquals(0, leaf1.getNumRunnableApps());
+    assertEquals(2, leaf2.getNumRunnableApps());
+    assertEquals(1, leaf2.getNumNonRunnableApps());
   }
   }
   
   
   @Test
   @Test