blob: bf6cb9174568cf13e73390ab4296143742e6ef7c [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hive.ql;
import com.google.common.collect.ImmutableMap;
import org.apache.hadoop.hive.ql.exec.Task;
import org.apache.hadoop.hive.ql.exec.TaskResult;
import org.apache.hadoop.hive.ql.plan.api.StageType;
import java.io.Serializable;
import java.util.*;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonWriteNullProperties;
import org.codehaus.jackson.annotate.JsonIgnore;
/**
* Some limited query information to save for WebUI.
*
* The class is synchronized, as WebUI may access information about a running query.
*/
public class QueryDisplay {
// Member variables
private String queryStr;
private String explainPlan;
private String errorMessage;
private String queryId;
private final Map<Phase, Map<String, Long>> hmsTimingMap = new HashMap<Phase, Map<String, Long>>();
private final Map<Phase, Map<String, Long>> perfLogStartMap = new HashMap<Phase, Map<String, Long>>();
private final Map<Phase, Map<String, Long>> perfLogEndMap = new HashMap<Phase, Map<String, Long>>();
private final LinkedHashMap<String, TaskDisplay> tasks = new LinkedHashMap<String, TaskDisplay>();
public synchronized <T extends Serializable> void updateTaskStatus(Task<T> tTask) {
if (!tasks.containsKey(tTask.getId())) {
tasks.put(tTask.getId(), new TaskDisplay(tTask));
}
tasks.get(tTask.getId()).updateStatus(tTask);
}
//Inner classes
public enum Phase {
COMPILATION,
EXECUTION,
}
@JsonWriteNullProperties(false)
@JsonIgnoreProperties(ignoreUnknown = true)
public static class TaskDisplay {
private Integer returnValue; //if set, determines that task is complete.
private String errorMsg;
private Long beginTime;
private Long endTime;
private String taskId;
private String externalHandle;
public Task.TaskState taskState;
private StageType taskType;
private String name;
private boolean requireLock;
private boolean retryIfFail;
private String statusMessage;
// required for jackson
public TaskDisplay() {
}
public TaskDisplay(Task task) {
taskId = task.getId();
externalHandle = task.getExternalHandle();
taskType = task.getType();
name = task.getName();
requireLock = task.requireLock();
retryIfFail = task.ifRetryCmdWhenFail();
}
@JsonIgnore
public synchronized String getStatus() {
if (returnValue == null) {
return "Running";
} else if (returnValue == 0) {
return "Success, ReturnVal 0";
} else {
return "Failure, ReturnVal " + String.valueOf(returnValue);
}
}
public synchronized Long getElapsedTime() {
if (endTime == null) {
if (beginTime == null) {
return null;
}
return System.currentTimeMillis() - beginTime;
} else {
return endTime - beginTime;
}
}
public synchronized Integer getReturnValue() {
return returnValue;
}
public synchronized String getErrorMsg() {
return errorMsg;
}
public synchronized Long getBeginTime() {
return beginTime;
}
public synchronized Long getEndTime() {
return endTime;
}
public synchronized String getTaskId() {
return taskId;
}
public synchronized StageType getTaskType() {
return taskType;
}
public synchronized String getName() {
return name;
}
@JsonIgnore
public synchronized boolean isRequireLock() {
return requireLock;
}
@JsonIgnore
public synchronized boolean isRetryIfFail() {
return retryIfFail;
}
public synchronized String getExternalHandle() {
return externalHandle;
}
public synchronized <T extends Serializable> void updateStatus(Task<T> tTask) {
this.taskState = tTask.getTaskState();
if (externalHandle == null && tTask.getExternalHandle() != null) {
this.externalHandle = tTask.getExternalHandle();
}
setStatusMessage(tTask.getStatusMessage());
switch (taskState) {
case RUNNING:
if (beginTime == null) {
beginTime = System.currentTimeMillis();
}
break;
case FINISHED:
if (endTime == null) {
endTime = System.currentTimeMillis();
}
break;
}
}
public synchronized String getStatusMessage() {
return statusMessage;
}
public synchronized void setStatusMessage(String statusMessage) {
this.statusMessage = statusMessage;
}
}
public synchronized void setTaskResult(String taskId, TaskResult result) {
TaskDisplay taskDisplay = tasks.get(taskId);
if (taskDisplay != null) {
taskDisplay.returnValue = result.getExitVal();
if (result.getTaskError() != null) {
taskDisplay.errorMsg = result.getTaskError().toString();
}
}
}
public synchronized List<TaskDisplay> getTaskDisplays() {
List<TaskDisplay> taskDisplays = new ArrayList<TaskDisplay>();
taskDisplays.addAll(tasks.values());
return taskDisplays;
}
public synchronized void setQueryStr(String queryStr) {
this.queryStr = queryStr;
}
public synchronized String getQueryString() {
return returnStringOrUnknown(queryStr);
}
public synchronized String getExplainPlan() {
return returnStringOrUnknown(explainPlan);
}
public synchronized void setExplainPlan(String explainPlan) {
this.explainPlan = explainPlan;
}
/**
* @param phase phase of query
* @return map of HMS Client method-calls and duration in miliseconds, during given phase.
*/
public synchronized Map<String, Long> getHmsTimings(Phase phase) {
return hmsTimingMap.get(phase);
}
/**
* @param phase phase of query
* @param hmsTimings map of HMS Client method-calls and duration in miliseconds, during given phase.
*/
public synchronized void setHmsTimings(Phase phase, ImmutableMap<String, Long> hmsTimings) {
hmsTimingMap.put(phase, hmsTimings);
}
/**
* @param phase phase of query
* @return map of PerfLogger call-trace name and start time in miliseconds, during given phase.
*/
public synchronized Map<String, Long> getPerfLogStarts(Phase phase) {
return perfLogStartMap.get(phase);
}
/**
* @param phase phase of query
* @param perfLogStarts map of PerfLogger call-trace name and start time in miliseconds, during given phase.
*/
public synchronized void setPerfLogStarts(Phase phase, ImmutableMap<String, Long> perfLogStarts) {
perfLogStartMap.put(phase, perfLogStarts);
}
/**
* @param phase phase of query
* @return map of PerfLogger call-trace name and end time in miliseconds, during given phase.
*/
public synchronized Map<String, Long> getPerfLogEnds(Phase phase) {
return perfLogEndMap.get(phase);
}
/**
* @param phase phase of query
* @param perfLogEnds map of PerfLogger call-trace name and end time in miliseconds, during given phase.
*/
public synchronized void setPerfLogEnds(Phase phase, ImmutableMap<String, Long> perfLogEnds) {
perfLogEndMap.put(phase, perfLogEnds);
}
/**
* @param phase phase of query
* @return map of PerfLogger call-trace name and duration in miliseconds, during given phase.
*/
public synchronized Map<String, Long> getPerfLogTimes(Phase phase) {
Map<String, Long> times = new HashMap<>();
Map<String, Long> startTimes = perfLogStartMap.get(phase);
Map<String, Long> endTimes = perfLogEndMap.get(phase);
if (endTimes != null && startTimes != null) {
for (String timeKey : endTimes.keySet()) {
Long endTime = endTimes.get(timeKey);
Long startTime = startTimes.get(timeKey);
if (startTime != null) {
times.put(timeKey, endTime - startTime);
}
}
}
return times;
}
public synchronized String getErrorMessage() {
return errorMessage;
}
public synchronized void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public synchronized String getQueryId() {
return returnStringOrUnknown(queryId);
}
public synchronized void setQueryId(String queryId) {
this.queryId = queryId;
}
private String returnStringOrUnknown(String s) {
return s == null ? "UNKNOWN" : s;
}
}