YARN-11395. RM UI, RMAttemptBlock can not render FINAL_SAVING. Contributed by Bence Kosztolnik

- In the YARN-1345 remove of FINAL_SAVING was missed from RMAttemptBlock
- Same issue was present after YARN-1345 in YARN-4411
- YARN-4411 logic was applied in this commit for FINAL_SAVING
This commit is contained in:
Bence Kosztolnik 2022-12-14 15:58:02 +01:00 committed by Benjamin Teke
parent f9fac84f43
commit 7190fcf713
7 changed files with 84 additions and 18 deletions

View File

@ -27,6 +27,7 @@ public interface StateMachine
<STATE extends Enum<STATE>, <STATE extends Enum<STATE>,
EVENTTYPE extends Enum<EVENTTYPE>, EVENT> { EVENTTYPE extends Enum<EVENTTYPE>, EVENT> {
public STATE getCurrentState(); public STATE getCurrentState();
public STATE getPreviousState();
public STATE doTransition(EVENTTYPE eventType, EVENT event) public STATE doTransition(EVENTTYPE eventType, EVENT event)
throws InvalidStateTransitionException; throws InvalidStateTransitionException;
} }

View File

@ -457,6 +457,7 @@ private class InternalStateMachine
implements StateMachine<STATE, EVENTTYPE, EVENT> { implements StateMachine<STATE, EVENTTYPE, EVENT> {
private final OPERAND operand; private final OPERAND operand;
private STATE currentState; private STATE currentState;
private STATE previousState;
private final StateTransitionListener<OPERAND, EVENT, STATE> listener; private final StateTransitionListener<OPERAND, EVENT, STATE> listener;
InternalStateMachine(OPERAND operand, STATE initialState) { InternalStateMachine(OPERAND operand, STATE initialState) {
@ -479,14 +480,19 @@ public synchronized STATE getCurrentState() {
return currentState; return currentState;
} }
@Override
public synchronized STATE getPreviousState() {
return previousState;
}
@Override @Override
public synchronized STATE doTransition(EVENTTYPE eventType, EVENT event) public synchronized STATE doTransition(EVENTTYPE eventType, EVENT event)
throws InvalidStateTransitionException { throws InvalidStateTransitionException {
listener.preTransition(operand, currentState, event); listener.preTransition(operand, currentState, event);
STATE oldState = currentState; previousState = currentState;
currentState = StateMachineFactory.this.doTransition currentState = StateMachineFactory.this.doTransition
(operand, currentState, eventType, event); (operand, currentState, eventType, event);
listener.postTransition(operand, oldState, currentState, event); listener.postTransition(operand, previousState, currentState, event);
return currentState; return currentState;
} }
} }

View File

@ -453,6 +453,17 @@ public static YarnApplicationState createApplicationState(
} }
} }
public static YarnApplicationAttemptState convertRmAppAttemptStateToYarnApplicationAttemptState(
RMAppAttemptState currentState,
RMAppAttemptState previousState
) {
return createApplicationAttemptState(
currentState == RMAppAttemptState.FINAL_SAVING
? previousState
: currentState
);
}
public static YarnApplicationAttemptState createApplicationAttemptState( public static YarnApplicationAttemptState createApplicationAttemptState(
RMAppAttemptState rmAppAttemptState) { RMAppAttemptState rmAppAttemptState) {
switch (rmAppAttemptState) { switch (rmAppAttemptState) {

View File

@ -206,6 +206,14 @@ public interface RMAppAttempt extends EventHandler<RMAppAttemptEvent> {
*/ */
RMAppAttemptState getState(); RMAppAttemptState getState();
/**
* The previous state of the {@link RMAppAttempt} before the current state.
*
* @return the previous state of the {@link RMAppAttempt} before the current state
* for this application attempt.
*/
RMAppAttemptState getPreviousState();
/** /**
* Create the external user-facing state of the attempt of ApplicationMaster * Create the external user-facing state of the attempt of ApplicationMaster
* from the current state of the {@link RMAppAttempt}. * from the current state of the {@link RMAppAttempt}.

View File

@ -2220,13 +2220,22 @@ public RMAppAttemptState getState() {
} }
@Override @Override
public YarnApplicationAttemptState createApplicationAttemptState() { public RMAppAttemptState getPreviousState() {
RMAppAttemptState state = getState(); this.readLock.lock();
// If AppAttempt is in FINAL_SAVING state, return its previous state.
if (state.equals(RMAppAttemptState.FINAL_SAVING)) { try {
state = stateBeforeFinalSaving; return this.stateMachine.getPreviousState();
} finally {
this.readLock.unlock();
} }
return RMServerUtils.createApplicationAttemptState(state); }
@Override
public YarnApplicationAttemptState createApplicationAttemptState() {
return RMServerUtils.convertRmAppAttemptStateToYarnApplicationAttemptState(
getState(),
stateBeforeFinalSaving
);
} }
private void launchAttempt(){ private void launchAttempt(){

View File

@ -39,6 +39,7 @@
import org.apache.hadoop.yarn.api.records.ResourceRequest; import org.apache.hadoop.yarn.api.records.ResourceRequest;
import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState; import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState;
import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.server.resourcemanager.RMServerUtils;
import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager; import org.apache.hadoop.yarn.server.resourcemanager.ResourceManager;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttempt;
@ -437,20 +438,24 @@ private boolean isApplicationInFinalState(YarnApplicationAttemptState state) {
@Override @Override
protected void createAttemptHeadRoomTable(Block html) { protected void createAttemptHeadRoomTable(Block html) {
RMAppAttempt attempt = getRMAppAttempt(); RMAppAttempt attempt = getRMAppAttempt();
if (attempt != null) { if (attempt != null && !isApplicationInFinalState(createApplicationAttemptState(attempt))) {
if (!isApplicationInFinalState(YarnApplicationAttemptState RMAppAttemptMetrics metrics = attempt.getRMAppAttemptMetrics();
.valueOf(attempt.getAppAttemptState().toString()))) { DIV<Hamlet> pdiv = html.__(InfoBlock.class).div(_INFO_WRAP);
RMAppAttemptMetrics metrics = attempt.getRMAppAttemptMetrics(); info("Application Attempt Overview").clear();
DIV<Hamlet> pdiv = html.__(InfoBlock.class).div(_INFO_WRAP); info("Application Attempt Metrics").__(
info("Application Attempt Overview").clear();
info("Application Attempt Metrics").__(
"Application Attempt Headroom : ", metrics == null ? "N/A" : "Application Attempt Headroom : ", metrics == null ? "N/A" :
metrics.getApplicationAttemptHeadroom()); metrics.getApplicationAttemptHeadroom());
pdiv.__(); pdiv.__();
}
} }
} }
private YarnApplicationAttemptState createApplicationAttemptState(RMAppAttempt attempt) {
return RMServerUtils.convertRmAppAttemptStateToYarnApplicationAttemptState(
attempt.getState(),
attempt.getPreviousState()
);
}
private RMAppAttempt getRMAppAttempt() { private RMAppAttempt getRMAppAttempt() {
ApplicationId appId = this.appAttemptId.getApplicationId(); ApplicationId appId = this.appAttemptId.getApplicationId();
RMAppAttempt attempt = null; RMAppAttempt attempt = null;

View File

@ -43,10 +43,12 @@
import org.apache.hadoop.yarn.api.records.ResourceRequest; import org.apache.hadoop.yarn.api.records.ResourceRequest;
import org.apache.hadoop.yarn.api.records.UpdateContainerError; import org.apache.hadoop.yarn.api.records.UpdateContainerError;
import org.apache.hadoop.yarn.api.records.UpdateContainerRequest; import org.apache.hadoop.yarn.api.records.UpdateContainerRequest;
import org.apache.hadoop.yarn.api.records.YarnApplicationAttemptState;
import org.apache.hadoop.yarn.api.records.impl.pb.UpdateContainerRequestPBImpl; import org.apache.hadoop.yarn.api.records.impl.pb.UpdateContainerRequestPBImpl;
import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.event.Dispatcher; import org.apache.hadoop.yarn.event.Dispatcher;
import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager;
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptState;
import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer;
import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode; import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode;
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ContainerUpdates; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ContainerUpdates;
@ -409,6 +411,30 @@ public void testGetApplicableNodeCountForAMLocalityAndLabels()
Assert.assertEquals(15, Assert.assertEquals(15,
RMServerUtils.getApplicableNodeCountForAM(rmContext, conf, reqs)); RMServerUtils.getApplicableNodeCountForAM(rmContext, conf, reqs));
} }
@Test
public void testConvertRmAppAttemptStateToYarnApplicationAttemptState() {
Assert.assertEquals(
YarnApplicationAttemptState.FAILED,
RMServerUtils.convertRmAppAttemptStateToYarnApplicationAttemptState(
RMAppAttemptState.FINAL_SAVING,
RMAppAttemptState.FAILED
)
);
Assert.assertEquals(
YarnApplicationAttemptState.SCHEDULED,
RMServerUtils.convertRmAppAttemptStateToYarnApplicationAttemptState(
RMAppAttemptState.FINAL_SAVING,
RMAppAttemptState.SCHEDULED
)
);
Assert.assertEquals(
YarnApplicationAttemptState.NEW,
RMServerUtils.convertRmAppAttemptStateToYarnApplicationAttemptState(
RMAppAttemptState.NEW,
null
)
);
}
private ResourceRequest createResourceRequest(String resource, private ResourceRequest createResourceRequest(String resource,
boolean relaxLocality, String nodeLabel) { boolean relaxLocality, String nodeLabel) {