Skip to content

Commit 76490d4

Browse files
authored
TEZ-4561: Improve reported exception when DAGAppMaster is shutting down. (#365). (Ayush Saxena, reviewed by Laszlo Bodor)
1 parent 174d4e3 commit 76490d4

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

tez-dag/src/main/java/org/apache/tez/dag/app/DAGAppMaster.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.Arrays;
3737
import java.util.Calendar;
3838
import java.util.Collections;
39+
import java.util.Date;
3940
import java.util.EnumSet;
4041
import java.util.HashMap;
4142
import java.util.HashSet;
@@ -936,6 +937,15 @@ public void handle(DAGAppMasterEvent event) {
936937
protected class DAGAppMasterShutdownHandler {
937938
private AtomicBoolean shutdownHandled = new AtomicBoolean(false);
938939
private long sleepTimeBeforeExit = TezConstants.TEZ_DAG_SLEEP_TIME_BEFORE_EXIT;
940+
private long shutdownTime;
941+
942+
public Date getShutdownTime() {
943+
return new Date(shutdownTime);
944+
}
945+
946+
public void setShutdownTime(long shutdownTime) {
947+
this.shutdownTime = shutdownTime;
948+
}
939949

940950
void setSleepTimeBeforeExit(long sleepTimeBeforeExit) {
941951
this.sleepTimeBeforeExit = sleepTimeBeforeExit;
@@ -954,6 +964,7 @@ public void shutdown(boolean now) {
954964

955965
synchronized (shutdownHandlerRunning) {
956966
shutdownHandlerRunning.set(true);
967+
setShutdownTime(System.currentTimeMillis());
957968
}
958969
LOG.info("Handling DAGAppMaster shutdown");
959970

@@ -1680,9 +1691,11 @@ public HadoopShim getHadoopShim() {
16801691

16811692
@Override
16821693
public Map<ApplicationAccessType, String> getApplicationACLs() {
1683-
if (getServiceState() != STATE.STARTED) {
1694+
STATE serviceState = getServiceState();
1695+
if (serviceState != STATE.STARTED) {
16841696
throw new TezUncheckedException(
1685-
"Cannot get ApplicationACLs before all services have started");
1697+
"Cannot get ApplicationACLs before all services have started, The current service state is " + serviceState
1698+
+ "." + getShutdownTimeString());
16861699
}
16871700
return taskSchedulerManager.getApplicationAcls();
16881701
}
@@ -1743,6 +1756,13 @@ public void setQueueName(String queueName) {
17431756
}
17441757
}
17451758

1759+
private String getShutdownTimeString() {
1760+
if (shutdownHandler != null && shutdownHandler.getShutdownTime() != null) {
1761+
return " The shutdown hook started at " + shutdownHandler.getShutdownTime();
1762+
}
1763+
return "";
1764+
}
1765+
17461766
private static class ServiceWithDependency implements ServiceStateChangeListener {
17471767
ServiceWithDependency(Service service) {
17481768
this.service = service;

tez-dag/src/test/java/org/apache/tez/dag/app/TestDAGAppMaster.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
import org.apache.hadoop.security.token.SecretManager;
3333
import org.apache.hadoop.security.token.Token;
3434
import org.apache.hadoop.security.token.TokenIdentifier;
35-
import org.apache.hadoop.util.Progressable;
35+
import org.apache.hadoop.test.LambdaTestUtils;
36+
import org.apache.hadoop.util.Time;
3637
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
3738
import org.apache.hadoop.yarn.api.records.ApplicationId;
3839
import org.apache.hadoop.yarn.api.records.ContainerId;
@@ -49,6 +50,7 @@
4950
import org.apache.tez.dag.api.NamedEntityDescriptor;
5051
import org.apache.tez.dag.api.TezConfiguration;
5152
import org.apache.tez.dag.api.TezConstants;
53+
import org.apache.tez.dag.api.TezUncheckedException;
5254
import org.apache.tez.dag.api.UserPayload;
5355
import org.apache.tez.dag.api.records.DAGProtos;
5456
import org.apache.tez.dag.api.records.DAGProtos.AMPluginDescriptorProto;
@@ -67,18 +69,19 @@
6769
import org.junit.Before;
6870
import org.junit.Test;
6971
import org.mockito.ArgumentCaptor;
72+
import org.mockito.Mockito;
7073

7174
import java.io.ByteArrayInputStream;
7275
import java.io.DataInput;
7376
import java.io.DataInputStream;
7477
import java.io.DataOutput;
7578
import java.io.File;
76-
import java.io.FileNotFoundException;
7779
import java.io.FileOutputStream;
7880
import java.io.IOException;
7981
import java.lang.reflect.Field;
80-
import java.net.URI;
8182
import java.nio.ByteBuffer;
83+
import java.time.Instant;
84+
import java.util.Date;
8285
import java.util.HashMap;
8386
import java.util.LinkedList;
8487
import java.util.List;
@@ -493,6 +496,26 @@ public void testDagCredentialsWithMerge() throws Exception {
493496
testDagCredentials(true);
494497
}
495498

499+
@Test
500+
public void testGetACLFailure() throws Exception {
501+
ApplicationId appId = ApplicationId.newInstance(1, 1);
502+
ApplicationAttemptId attemptId = ApplicationAttemptId.newInstance(appId, 2);
503+
DAGAppMasterForTest dam = new DAGAppMasterForTest(attemptId, true);
504+
TezConfiguration conf = new TezConfiguration(false);
505+
conf.setBoolean(TezConfiguration.DAG_RECOVERY_ENABLED, false);
506+
dam.init(conf);
507+
LambdaTestUtils.intercept(TezUncheckedException.class,
508+
"Cannot get ApplicationACLs before all services have started, The current service state is INITED",
509+
() -> dam.getContext().getApplicationACLs());
510+
dam.start();
511+
dam.stop();
512+
Mockito.when(dam.mockShutdown.getShutdownTime()).thenReturn(Date.from(Instant.ofEpochMilli(Time.now())));
513+
LambdaTestUtils.intercept(TezUncheckedException.class,
514+
" Cannot get ApplicationACLs before all services have started, "
515+
+ "The current service state is STOPPED. The shutdown hook started at "
516+
+ dam.mockShutdown.getShutdownTime(), () -> dam.getContext().getApplicationACLs());
517+
}
518+
496519
@Test
497520
public void testBadProgress() throws Exception {
498521
TezConfiguration conf = new TezConfiguration();

0 commit comments

Comments
 (0)