Browse Source

YARN-214. RMContainerImpl does not handle event EXPIRE at state RUNNING (jeagles via bobby)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1410522 13f79535-47bb-0310-9956-ffa450edef68
Robert Joseph Evans 12 years ago
parent
commit
ab5039d4f1

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

@@ -169,6 +169,9 @@ Release 0.23.6 - UNRELEASED
     YARN-188. Coverage fixing for CapacityScheduler (Aleksey Gorshkov via
     bobby)
 
+    YARN-214. RMContainerImpl does not handle event EXPIRE at state RUNNING
+    (jeagles via bobby)
+
 Release 0.23.5 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 8 - 5
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java

@@ -98,10 +98,13 @@ public class RMContainerImpl implements RMContainer {
         RMContainerEventType.KILL, new KillTransition())
     .addTransition(RMContainerState.RUNNING, RMContainerState.RELEASED,
         RMContainerEventType.RELEASED, new KillTransition())
+    .addTransition(RMContainerState.RUNNING, RMContainerState.RUNNING,
+        RMContainerEventType.EXPIRE)
 
     // Transitions from COMPLETED state
     .addTransition(RMContainerState.COMPLETED, RMContainerState.COMPLETED,
-        EnumSet.of(RMContainerEventType.RELEASED, RMContainerEventType.KILL))
+        EnumSet.of(RMContainerEventType.EXPIRE, RMContainerEventType.RELEASED,
+            RMContainerEventType.KILL))
 
     // Transitions from EXPIRED state
     .addTransition(RMContainerState.EXPIRED, RMContainerState.EXPIRED,
@@ -109,13 +112,13 @@ public class RMContainerImpl implements RMContainer {
 
     // Transitions from RELEASED state
     .addTransition(RMContainerState.RELEASED, RMContainerState.RELEASED,
-        EnumSet.of(RMContainerEventType.RELEASED, RMContainerEventType.KILL,
-            RMContainerEventType.FINISHED))
+        EnumSet.of(RMContainerEventType.EXPIRE, RMContainerEventType.RELEASED,
+            RMContainerEventType.KILL, RMContainerEventType.FINISHED))
 
     // Transitions from KILLED state
     .addTransition(RMContainerState.KILLED, RMContainerState.KILLED,
-        EnumSet.of(RMContainerEventType.RELEASED, RMContainerEventType.KILL,
-            RMContainerEventType.FINISHED))
+        EnumSet.of(RMContainerEventType.EXPIRE, RMContainerEventType.RELEASED,
+            RMContainerEventType.KILL, RMContainerEventType.FINISHED))
 
     // create the topology tables
     .installTopology(); 

+ 55 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/TestRMContainerImpl.java

@@ -116,4 +116,59 @@ public class TestRMContainerImpl {
     assertEquals(RMContainerState.RELEASED, rmContainer.getState());
   }
 
+  @Test
+  public void testExpireWhileRunning() {
+
+    DrainDispatcher drainDispatcher = new DrainDispatcher();
+    EventHandler eventHandler = drainDispatcher.getEventHandler();
+    EventHandler<RMAppAttemptEvent> appAttemptEventHandler = mock(EventHandler.class);
+    EventHandler generic = mock(EventHandler.class);
+    drainDispatcher.register(RMAppAttemptEventType.class,
+        appAttemptEventHandler);
+    drainDispatcher.register(RMNodeEventType.class, generic);
+    drainDispatcher.init(new YarnConfiguration());
+    drainDispatcher.start();
+    NodeId nodeId = BuilderUtils.newNodeId("host", 3425);
+    ApplicationId appId = BuilderUtils.newApplicationId(1, 1);
+    ApplicationAttemptId appAttemptId = BuilderUtils.newApplicationAttemptId(
+        appId, 1);
+    ContainerId containerId = BuilderUtils.newContainerId(appAttemptId, 1);
+    ContainerAllocationExpirer expirer = mock(ContainerAllocationExpirer.class);
+
+    Resource resource = BuilderUtils.newResource(512);
+    Priority priority = BuilderUtils.newPriority(5);
+
+    Container container = BuilderUtils.newContainer(containerId, nodeId,
+        "host:3465", resource, priority, null);
+
+    RMContainer rmContainer = new RMContainerImpl(container, appAttemptId,
+        nodeId, eventHandler, expirer);
+
+    assertEquals(RMContainerState.NEW, rmContainer.getState());
+
+    rmContainer.handle(new RMContainerEvent(containerId,
+        RMContainerEventType.START));
+    drainDispatcher.await();
+    assertEquals(RMContainerState.ALLOCATED, rmContainer.getState());
+
+    rmContainer.handle(new RMContainerEvent(containerId,
+        RMContainerEventType.ACQUIRED));
+    drainDispatcher.await();
+    assertEquals(RMContainerState.ACQUIRED, rmContainer.getState());
+
+    rmContainer.handle(new RMContainerEvent(containerId,
+        RMContainerEventType.LAUNCHED));
+    drainDispatcher.await();
+    assertEquals(RMContainerState.RUNNING, rmContainer.getState());
+
+    // In RUNNING state. Verify EXPIRE and associated actions.
+    reset(appAttemptEventHandler);
+    ContainerStatus containerStatus = SchedulerUtils
+        .createAbnormalContainerStatus(containerId,
+            SchedulerUtils.EXPIRED_CONTAINER);
+    rmContainer.handle(new RMContainerFinishedEvent(containerId,
+        containerStatus, RMContainerEventType.EXPIRE));
+    drainDispatcher.await();
+    assertEquals(RMContainerState.RUNNING, rmContainer.getState());
+  }
 }