diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index 53a04cd28d..5bdc50215a 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/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 diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java index b93b333eb2..de66f583e2 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/RMContainerImpl.java +++ b/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(); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/TestRMContainerImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/TestRMContainerImpl.java index 267e06dc71..f970493bc7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmcontainer/TestRMContainerImpl.java +++ b/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 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()); + } }