diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMAppManager.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMAppManager.java index bdc68acf3a8..39998dc9e0a 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMAppManager.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMAppManager.java @@ -717,6 +717,7 @@ public void handle(RMAppManagerEvent event) { app.getStartTime(), app.getApplicationSubmissionContext(), app.getUser(), app.getCallerContext()); appState.setApplicationTimeouts(currentExpireTimeouts); + appState.setLaunchTime(app.getLaunchTime()); // update to state store. Though it synchronous call, update via future to // know any exception has been set. It is required because in non-HA mode, @@ -842,6 +843,7 @@ private void updateAppDataToStateStore(String queue, RMApp app, app.getApplicationSubmissionContext(), app.getUser(), app.getCallerContext()); appState.setApplicationTimeouts(app.getApplicationTimeouts()); + appState.setLaunchTime(app.getLaunchTime()); rmContext.getStateStore().updateApplicationStateSynchronously(appState, false, future); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java 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 3f9f9c8103d..abb925cf54f 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/RMAppImpl.java @@ -1068,6 +1068,11 @@ public void transition(RMAppImpl app, RMAppEvent event) { app.getApplicationId()+", attemptId: "+ app.getCurrentAppAttempt().getAppAttemptId()+ "launchTime: "+event.getTimestamp()); + ApplicationStateData appState = ApplicationStateData + .newInstance(app.submitTime, app.startTime, app.user, app.submissionContext, + app.recoveredFinalState, app.diagnostics.toString(), event.getTimestamp(), app.storedFinishTime, + app.callerContext, app.applicationTimeouts); + app.rmContext.getStateStore().updateApplicationStateSynchronously(appState, false, null); app.launchTime = event.getTimestamp(); app.rmContext.getSystemMetricsPublisher().appLaunched( app, app.launchTime); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java index d6f20d7fa29..21cdbf9113f 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/CapacityScheduler.java @@ -2675,6 +2675,7 @@ public Priority updateApplicationPriority(Priority newPriority, rmApp.getApplicationSubmissionContext(), rmApp.getUser(), rmApp.getCallerContext()); appState.setApplicationTimeouts(rmApp.getApplicationTimeouts()); + appState.setLaunchTime(rmApp.getLaunchTime()); rmContext.getStateStore().updateApplicationStateSynchronously(appState, false, future); diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/TestRMAppTransitions.java 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 2e176cc9763..6c5f1a7d798 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/TestRMAppTransitions.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/rmapp/TestRMAppTransitions.java @@ -483,6 +483,13 @@ private void assertAppFinalStateNotSaved(RMApp application){ any(ApplicationStateData.class)); } + private void assertAppStateLaunchTimeSaved(long expectedLaunchTime) { + ArgumentCaptor state = ArgumentCaptor.forClass(ApplicationStateData.class); + verify(store, times(1)).updateApplicationStateSynchronously( + state.capture(), eq(false), eq(null)); + assertEquals(expectedLaunchTime, state.getValue().getLaunchTime()); + } + private void assertKilled(RMApp application) { assertTimesAtFinish(application); assertAppState(RMAppState.KILLED, application); @@ -932,6 +939,21 @@ public void testAppAcceptedKill() throws IOException, InterruptedException { verifyRMAppFieldsForFinalTransitions(application); } + @Test + public void testAppAcceptedAccepted() throws IOException { + LOG.info("--- START: testAppAcceptedAccepted ---"); + + RMApp application = testCreateAppAccepted(null); + // ACCEPTED => ACCEPTED event RMAppEventType.ATTEMPT_LAUNCHED + RMAppEvent appAttemptLaunched = + new RMAppEvent(application.getApplicationId(), + RMAppEventType.ATTEMPT_LAUNCHED, 1234L); + application.handle(appAttemptLaunched); + rmDispatcher.await(); + assertAppState(RMAppState.ACCEPTED, application); + assertAppStateLaunchTimeSaved(1234L); + } + @Test public void testAppAcceptedAttemptKilled() throws IOException, InterruptedException {