diff --git a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusOptionsProcessor.java b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusOptionsProcessor.java index 306391b..d80980a 100644 --- a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusOptionsProcessor.java +++ b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusOptionsProcessor.java @@ -32,12 +32,12 @@ public class LlapStatusOptionsProcessor { - private static final Logger LOG = LoggerFactory.getLogger(LlapStatusOptionsProcessor.class); - private static final String LLAPSTATUS_CONSTANT = "llapstatus"; private static final long FIND_YARN_APP_TIMEOUT_MS = 20 * 1000l; // 20seconds to wait for app to be visible + private static final long DEFAULT_STATUS_REFRESH_INTERVAL_MS = 5 * 1000l; // 5 seconds wait until subsequent status + enum OptionConstants { NAME("name", 'n', "LLAP cluster name", true), @@ -45,6 +45,10 @@ "Amount of time(s) that the tool will sleep to wait for the YARN application to start. negative values=wait forever, 0=Do not wait. default=" + TimeUnit.SECONDS.convert(FIND_YARN_APP_TIMEOUT_MS, TimeUnit.MILLISECONDS) + "s", true), OUTPUT_FILE("outputFile", 'o', "File to which output should be written (Default stdout)", true), + WATCH("watch", 'w', "After listing the initial status, watch for the status changes", false), + STATUS_REFRESH_INTERVAL("refreshInterval", 'i', "Amount of time in seconds to wait until subsequent status checks" + + " in watch mode. Valid only for watch mode. (Default " + + TimeUnit.SECONDS.convert(DEFAULT_STATUS_REFRESH_INTERVAL_MS, TimeUnit.MILLISECONDS) + "s)", true), HIVECONF("hiveconf", null, "Use value for given property. Overridden by explicit parameters", "property=value", 2), HELP("help", 'H', "Print help information", false); @@ -94,17 +98,21 @@ public int getNumArgs() { private final Properties conf; private final long findAppTimeoutMs; private final String outputFile; + private final boolean watch; + private final long refreshIntervalMs; + + public LlapStatusOptions(String name) { + this(name, new Properties(), FIND_YARN_APP_TIMEOUT_MS, null, false, DEFAULT_STATUS_REFRESH_INTERVAL_MS); + } public LlapStatusOptions(String name, Properties hiveProperties, long findAppTimeoutMs, - String outputFile) { + String outputFile, boolean watch, long refreshIntervalMs) { this.name = name; this.conf = hiveProperties; this.findAppTimeoutMs = findAppTimeoutMs; this.outputFile = outputFile; - } - - public LlapStatusOptions(String name) { - this(name, new Properties(), FIND_YARN_APP_TIMEOUT_MS, null); + this.watch = watch; + this.refreshIntervalMs = refreshIntervalMs; } public String getName() { @@ -122,6 +130,14 @@ public long getFindAppTimeoutMs() { public String getOutputFile() { return outputFile; } + + public boolean isWatchMode() { + return watch; + } + + public long getRefreshIntervalMs() { + return refreshIntervalMs; + } } private final Options options = new Options(); @@ -170,7 +186,18 @@ public LlapStatusOptions processOptions(String[] args) throws ParseException { outputFile = commandLine.getOptionValue(OptionConstants.OUTPUT_FILE.getLongOpt()); } - return new LlapStatusOptions(name, hiveConf, findAppTimeoutMs, outputFile); + boolean watch = false; + if (commandLine.hasOption(OptionConstants.WATCH.getLongOpt())) { + watch = true; + } + + long refreshIntervalMs = DEFAULT_STATUS_REFRESH_INTERVAL_MS; + if (commandLine.hasOption(OptionConstants.STATUS_REFRESH_INTERVAL.getLongOpt())) { + refreshIntervalMs = TimeUnit.MILLISECONDS.convert(Long.parseLong( + commandLine.getOptionValue(OptionConstants.STATUS_REFRESH_INTERVAL.getLongOpt())), + TimeUnit.SECONDS); + } + return new LlapStatusOptions(name, hiveConf, findAppTimeoutMs, outputFile, watch, refreshIntervalMs); } diff --git a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusServiceDriver.java b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusServiceDriver.java index 0efe545..8b0c19a 100644 --- a/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusServiceDriver.java +++ b/llap-server/src/java/org/apache/hadoop/hive/llap/cli/LlapStatusServiceDriver.java @@ -30,6 +30,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.StringUtils; @@ -172,8 +173,6 @@ public int run(LlapStatusOptions options) { .getLong(CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS, CONFIG_LLAP_ZK_REGISTRY_TIMEOUT_MS_DEFAULT) + "ms")); - - String appName; appName = options.getName(); if (StringUtils.isEmpty(appName)) { @@ -214,7 +213,7 @@ public int run(LlapStatusOptions options) { } // Process the report to decide whether to go to slider. - ExitCode ret; + ExitCode ret = ExitCode.SUCCESS; try { ret = processAppReport(appReport, appStatusBuilder); } catch (LlapStatusCliException e) { @@ -225,7 +224,7 @@ public int run(LlapStatusOptions options) { if (ret != ExitCode.SUCCESS) { return ret.getInt(); } else if (EnumSet.of(State.APP_NOT_FOUND, State.COMPLETE, State.LAUNCHING) - .contains(appStatusBuilder.getState())) { + .contains(appStatusBuilder.getState())) { return ExitCode.SUCCESS.getInt(); } else { // Get information from slider. @@ -238,7 +237,7 @@ public int run(LlapStatusOptions options) { } } - if (ret !=ExitCode.SUCCESS ) { + if (ret != ExitCode.SUCCESS) { return ret.getInt(); } else { try { @@ -248,8 +247,9 @@ public int run(LlapStatusOptions options) { return e.getExitCode().getInt(); } } + return ret.getInt(); - }finally { + } finally { if (LOG.isDebugEnabled()) { LOG.debug("Final AppState: " + appStatusBuilder.toString()); } @@ -937,17 +937,35 @@ public static void main(String[] args) { System.exit(ret); } - try { - ret = statusServiceDriver.run(options); - if (ret == ExitCode.SUCCESS.getInt()) { - try (OutputStream os = options.getOutputFile() == null ? System.out : - new BufferedOutputStream( - new FileOutputStream(options.getOutputFile())); PrintWriter pw = new PrintWriter( - os)) { - statusServiceDriver.outputJson(pw); + final boolean watchMode = options.isWatchMode(); + final long refreshInterval = options.getRefreshIntervalMs(); + try (OutputStream os = options.getOutputFile() == null ? System.out : + new BufferedOutputStream(new FileOutputStream(options.getOutputFile())); + PrintWriter pw = new PrintWriter(os)) { + + while (true) { + try { + ret = statusServiceDriver.run(options); + if (ret == ExitCode.SUCCESS.getInt()) { + statusServiceDriver.outputJson(pw); + os.flush(); + pw.flush(); + } + } finally { + if (watchMode) { + LOG.warn("Watch mode enabled. Sleeping " + TimeUnit.SECONDS.convert(refreshInterval, TimeUnit.MILLISECONDS) + + "s before refreshing the status.."); + try { + Thread.sleep(refreshInterval); + } catch (InterruptedException e) { + // ignore + } + } else { + // reported once, so break + break; + } } } - } catch (Throwable t) { logError(t); if (t instanceof LlapStatusCliException) {