diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index ac142b2b9cb..127f75bb6df 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -565,6 +565,9 @@ Release 2.4.0 - UNRELEASED YARN-1705. Reset cluster-metrics on transition to standby. (Rohith via kasha) + YARN-1852. Fixed RMAppAttempt to not resend AttemptFailed/AttemptKilled + events to already recovered Failed/Killed RMApps. (Rohith via jianhe) + Release 2.3.1 - 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/rmapp/RMAppImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java index 30af77de1d0..31e3767bba3 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java @@ -1136,8 +1136,12 @@ public class RMAppImpl implements RMApp, Recoverable { } public static boolean isAppInFinalState(RMApp rmApp) { - RMAppState appState = rmApp.getState(); + RMAppState appState = ((RMAppImpl) rmApp).getRecoveredFinalState(); return appState == RMAppState.FAILED || appState == RMAppState.FINISHED || appState == RMAppState.KILLED; } + + private RMAppState getRecoveredFinalState() { + return this.recoveredFinalState; + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/TestRMAppTransitions.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/TestRMAppTransitions.java index 5f89b198d00..e89b71b4105 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/TestRMAppTransitions.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/TestRMAppTransitions.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify; import java.io.IOException; import java.util.Arrays; import java.util.Collection; +import java.util.Map; import org.junit.Assert; @@ -53,6 +54,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.RMContextImpl; import org.apache.hadoop.yarn.server.resourcemanager.ahs.RMApplicationHistoryWriter; import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore; import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore.ApplicationState; +import org.apache.hadoop.yarn.server.resourcemanager.recovery.RMStateStore.RMState; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.AMLivelinessMonitor; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptEvent; @@ -862,7 +864,57 @@ public class TestRMAppTransitions { assertTimesAtFinish(application); assertAppState(RMAppState.KILLED, application); } + + @Test(timeout = 30000) + public void testAppsRecoveringStates() throws Exception { + RMState state = new RMState(); + Map applicationState = + state.getApplicationState(); + createRMStateForApplications(applicationState, RMAppState.FINISHED); + createRMStateForApplications(applicationState, RMAppState.KILLED); + createRMStateForApplications(applicationState, RMAppState.FAILED); + for (ApplicationState appState : applicationState.values()) { + testRecoverApplication(appState, state); + } + } + + public void testRecoverApplication(ApplicationState appState, RMState rmState) + throws Exception { + ApplicationSubmissionContext submissionContext = + appState.getApplicationSubmissionContext(); + RMAppImpl application = + new RMAppImpl(appState.getAppId(), rmContext, conf, + submissionContext.getApplicationName(), null, + submissionContext.getQueue(), submissionContext, null, null, + appState.getSubmitTime(), submissionContext.getApplicationType(), + submissionContext.getApplicationTags()); + Assert.assertEquals(RMAppState.NEW, application.getState()); + application.recover(rmState); + // Application final status looked from recoveredFinalStatus + Assert.assertTrue("Application is not in recoveredFinalStatus.", + RMAppImpl.isAppInFinalState(application)); + + // Trigger RECOVER event. + application.handle(new RMAppEvent(appState.getAppId(), + RMAppEventType.RECOVER)); + rmDispatcher.await(); + RMAppState finalState = appState.getState(); + Assert.assertEquals("Application is not in finalState.", finalState, + application.getState()); + } + + public void createRMStateForApplications( + Map applicationState, + RMAppState rmAppState) { + RMApp app = createNewTestApp(null); + ApplicationState appState = + new ApplicationState(app.getSubmitTime(), app.getStartTime(), + app.getApplicationSubmissionContext(), app.getUser(), rmAppState, + null, app.getFinishTime()); + applicationState.put(app.getApplicationId(), appState); + } + @Test public void testGetAppReport() { RMApp app = createNewTestApp(null);