in hbase-server/src/main/java/org/apache/hadoop/hbase/util/JVMClusterUtil.java [235:342]
public static void shutdown(final List<MasterThread> masters,
final List<RegionServerThread> regionservers) {
LOG.debug("Shutting down HBase Cluster");
if (masters != null) {
// Do backups first.
JVMClusterUtil.MasterThread activeMaster = null;
for (JVMClusterUtil.MasterThread t : masters) {
// Master was killed but could be still considered as active. Check first if it is stopped.
if (!t.master.isStopped()) {
if (!t.master.isActiveMaster()) {
try {
t.master.stopMaster();
} catch (IOException e) {
LOG.error("Exception occurred while stopping master", e);
}
LOG.info("Stopped backup Master {} is stopped: {}", t.master.hashCode(),
t.master.isStopped());
} else {
if (activeMaster != null) {
LOG.warn("Found more than 1 active master, hash {}", activeMaster.master.hashCode());
}
activeMaster = t;
LOG.debug("Found active master hash={}, stopped={}", t.master.hashCode(),
t.master.isStopped());
}
}
}
// Do active after.
if (activeMaster != null) {
try {
activeMaster.master.shutdown();
} catch (IOException e) {
LOG.error("Exception occurred in HMaster.shutdown()", e);
}
}
}
boolean wasInterrupted = false;
final long maxTime = EnvironmentEdgeManager.currentTime() + 30 * 1000;
if (regionservers != null) {
// first try nicely.
for (RegionServerThread t : regionservers) {
t.getRegionServer().stop("Shutdown requested");
}
for (RegionServerThread t : regionservers) {
long now = EnvironmentEdgeManager.currentTime();
if (t.isAlive() && !wasInterrupted && now < maxTime) {
try {
t.join(maxTime - now);
} catch (InterruptedException e) {
LOG.info("Got InterruptedException on shutdown - "
+ "not waiting anymore on region server ends", e);
wasInterrupted = true; // someone wants us to speed up.
}
}
}
// Let's try to interrupt the remaining threads if any.
for (int i = 0; i < 100; ++i) {
boolean atLeastOneLiveServer = false;
for (RegionServerThread t : regionservers) {
if (t.isAlive()) {
atLeastOneLiveServer = true;
try {
LOG.warn("RegionServerThreads remaining, give one more chance before interrupting");
t.join(1000);
} catch (InterruptedException e) {
wasInterrupted = true;
}
}
}
if (!atLeastOneLiveServer) break;
for (RegionServerThread t : regionservers) {
if (t.isAlive()) {
LOG.warn("RegionServerThreads taking too long to stop, interrupting; thread dump "
+ "if > 3 attempts: i=" + i);
if (i > 3) {
Threads.printThreadInfo(System.out, "Thread dump " + t.getName());
}
t.interrupt();
}
}
}
}
if (masters != null) {
for (JVMClusterUtil.MasterThread t : masters) {
while (t.master.isAlive() && !wasInterrupted) {
try {
// The below has been replaced to debug sometime hangs on end of
// tests.
// this.master.join():
Threads.threadDumpingIsAlive(t.master);
} catch (InterruptedException e) {
LOG.info(
"Got InterruptedException on shutdown - " + "not waiting anymore on master ends", e);
wasInterrupted = true;
}
}
}
}
LOG.info("Shutdown of " + ((masters != null) ? masters.size() : "0") + " master(s) and "
+ ((regionservers != null) ? regionservers.size() : "0") + " regionserver(s) "
+ (wasInterrupted ? "interrupted" : "complete"));
if (wasInterrupted) {
Thread.currentThread().interrupt();
}
}