diff --git a/core/trino-main/src/main/java/io/trino/dispatcher/FailedDispatchQuery.java b/core/trino-main/src/main/java/io/trino/dispatcher/FailedDispatchQuery.java index 66e3dcbfa957..06cc9bc99292 100644 --- a/core/trino-main/src/main/java/io/trino/dispatcher/FailedDispatchQuery.java +++ b/core/trino-main/src/main/java/io/trino/dispatcher/FailedDispatchQuery.java @@ -270,6 +270,8 @@ private static QueryStats immediateFailureQueryStats() 0, 0, 0, + 0, + 0, DataSize.ofBytes(0), DataSize.ofBytes(0), DataSize.ofBytes(0), @@ -283,19 +285,33 @@ private static QueryStats immediateFailureQueryStats() new Duration(0, MILLISECONDS), new Duration(0, MILLISECONDS), new Duration(0, MILLISECONDS), + new Duration(0, MILLISECONDS), + new Duration(0, MILLISECONDS), false, ImmutableSet.of(), DataSize.ofBytes(0), + DataSize.ofBytes(0), + 0, 0, new Duration(0, MILLISECONDS), + new Duration(0, MILLISECONDS), + DataSize.ofBytes(0), DataSize.ofBytes(0), 0, + 0, + DataSize.ofBytes(0), DataSize.ofBytes(0), 0, + 0, + DataSize.ofBytes(0), DataSize.ofBytes(0), 0, + 0, + DataSize.ofBytes(0), DataSize.ofBytes(0), 0, + 0, + DataSize.ofBytes(0), DataSize.ofBytes(0), ImmutableList.of(), DynamicFiltersStats.EMPTY, diff --git a/core/trino-main/src/main/java/io/trino/event/QueryMonitor.java b/core/trino-main/src/main/java/io/trino/event/QueryMonitor.java index b176026e224f..bcc05fe1b209 100644 --- a/core/trino-main/src/main/java/io/trino/event/QueryMonitor.java +++ b/core/trino-main/src/main/java/io/trino/event/QueryMonitor.java @@ -166,6 +166,7 @@ public void queryImmediateFailureEvent(BasicQueryInfo queryInfo, ExecutionFailur Optional.empty(), Optional.empty()), new QueryStatistics( + ofMillis(0), ofMillis(0), ofMillis(0), ofMillis(queryInfo.getQueryStats().getQueuedTime().toMillis()), @@ -174,6 +175,8 @@ public void queryImmediateFailureEvent(BasicQueryInfo queryInfo, ExecutionFailur Optional.empty(), Optional.empty(), Optional.empty(), + Optional.empty(), + 0, 0, 0, 0, @@ -252,9 +255,11 @@ private QueryStatistics createQueryStatistics(QueryInfo queryInfo) QueryStats queryStats = queryInfo.getQueryStats(); return new QueryStatistics( ofMillis(queryStats.getTotalCpuTime().toMillis()), + ofMillis(queryStats.getFailedCpuTime().toMillis()), ofMillis(queryStats.getElapsedTime().toMillis()), ofMillis(queryStats.getQueuedTime().toMillis()), Optional.of(ofMillis(queryStats.getTotalScheduledTime().toMillis())), + Optional.of(ofMillis(queryStats.getFailedScheduledTime().toMillis())), Optional.of(ofMillis(queryStats.getResourceWaitingTime().toMillis())), Optional.of(ofMillis(queryStats.getAnalysisTime().toMillis())), Optional.of(ofMillis(queryStats.getPlanningTime().toMillis())), @@ -273,6 +278,7 @@ private QueryStatistics createQueryStatistics(QueryInfo queryInfo) queryStats.getLogicalWrittenDataSize().toBytes(), queryStats.getWrittenPositions(), queryStats.getCumulativeUserMemory(), + queryStats.getFailedCumulativeUserMemory(), queryStats.getStageGcStatistics(), queryStats.getCompletedDrivers(), queryInfo.isCompleteInfo(), diff --git a/core/trino-main/src/main/java/io/trino/execution/BasicStageStats.java b/core/trino-main/src/main/java/io/trino/execution/BasicStageStats.java index 5b1ffc92de28..d7569758ac9d 100644 --- a/core/trino-main/src/main/java/io/trino/execution/BasicStageStats.java +++ b/core/trino-main/src/main/java/io/trino/execution/BasicStageStats.java @@ -47,10 +47,13 @@ public class BasicStageStats DataSize.ofBytes(0), 0, + 0, 0, DataSize.ofBytes(0), DataSize.ofBytes(0), + new Duration(0, MILLISECONDS), + new Duration(0, MILLISECONDS), new Duration(0, MILLISECONDS), new Duration(0, MILLISECONDS), @@ -72,10 +75,13 @@ public class BasicStageStats private final DataSize rawInputDataSize; private final long rawInputPositions; private final long cumulativeUserMemory; + private final long failedCumulativeUserMemory; private final DataSize userMemoryReservation; private final DataSize totalMemoryReservation; private final Duration totalCpuTime; + private final Duration failedCpuTime; private final Duration totalScheduledTime; + private final Duration failedScheduledTime; private final boolean fullyBlocked; private final Set blockedReasons; private final OptionalDouble progressPercentage; @@ -99,11 +105,14 @@ public BasicStageStats( long rawInputPositions, long cumulativeUserMemory, + long failedCumulativeUserMemory, DataSize userMemoryReservation, DataSize totalMemoryReservation, Duration totalCpuTime, + Duration failedCpuTime, Duration totalScheduledTime, + Duration failedScheduledTime, boolean fullyBlocked, Set blockedReasons, @@ -123,10 +132,13 @@ public BasicStageStats( this.rawInputDataSize = requireNonNull(rawInputDataSize, "rawInputDataSize is null"); this.rawInputPositions = rawInputPositions; this.cumulativeUserMemory = cumulativeUserMemory; + this.failedCumulativeUserMemory = failedCumulativeUserMemory; this.userMemoryReservation = requireNonNull(userMemoryReservation, "userMemoryReservation is null"); this.totalMemoryReservation = requireNonNull(totalMemoryReservation, "totalMemoryReservation is null"); this.totalCpuTime = requireNonNull(totalCpuTime, "totalCpuTime is null"); + this.failedCpuTime = requireNonNull(failedCpuTime, "failedCpuTime is null"); this.totalScheduledTime = requireNonNull(totalScheduledTime, "totalScheduledTime is null"); + this.failedScheduledTime = requireNonNull(failedScheduledTime, "failedScheduledTime is null"); this.fullyBlocked = fullyBlocked; this.blockedReasons = ImmutableSet.copyOf(requireNonNull(blockedReasons, "blockedReasons is null")); this.progressPercentage = requireNonNull(progressPercentage, "progressPercentage is null"); @@ -197,6 +209,11 @@ public long getCumulativeUserMemory() return cumulativeUserMemory; } + public long getFailedCumulativeUserMemory() + { + return failedCumulativeUserMemory; + } + public DataSize getUserMemoryReservation() { return userMemoryReservation; @@ -212,11 +229,21 @@ public Duration getTotalCpuTime() return totalCpuTime; } + public Duration getFailedCpuTime() + { + return failedCpuTime; + } + public Duration getTotalScheduledTime() { return totalScheduledTime; } + public Duration getFailedScheduledTime() + { + return failedScheduledTime; + } + public boolean isFullyBlocked() { return fullyBlocked; @@ -240,11 +267,14 @@ public static BasicStageStats aggregateBasicStageStats(Iterable int completedDrivers = 0; long cumulativeUserMemory = 0; + long failedCumulativeUserMemory = 0; long userMemoryReservation = 0; long totalMemoryReservation = 0; long totalScheduledTimeMillis = 0; + long failedScheduledTimeMillis = 0; long totalCpuTime = 0; + long failedCpuTime = 0; long physicalInputDataSize = 0; long physicalInputPositions = 0; @@ -268,11 +298,14 @@ public static BasicStageStats aggregateBasicStageStats(Iterable completedDrivers += stageStats.getCompletedDrivers(); cumulativeUserMemory += stageStats.getCumulativeUserMemory(); + failedCumulativeUserMemory += stageStats.getFailedCumulativeUserMemory(); userMemoryReservation += stageStats.getUserMemoryReservation().toBytes(); totalMemoryReservation += stageStats.getTotalMemoryReservation().toBytes(); totalScheduledTimeMillis += stageStats.getTotalScheduledTime().roundTo(MILLISECONDS); + failedScheduledTimeMillis += stageStats.getFailedScheduledTime().roundTo(MILLISECONDS); totalCpuTime += stageStats.getTotalCpuTime().roundTo(MILLISECONDS); + failedCpuTime += stageStats.getFailedCpuTime().roundTo(MILLISECONDS); isScheduled &= stageStats.isScheduled(); @@ -314,11 +347,14 @@ public static BasicStageStats aggregateBasicStageStats(Iterable rawInputPositions, cumulativeUserMemory, + failedCumulativeUserMemory, succinctBytes(userMemoryReservation), succinctBytes(totalMemoryReservation), new Duration(totalCpuTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), + new Duration(failedCpuTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), new Duration(totalScheduledTimeMillis, MILLISECONDS).convertToMostSuccinctTimeUnit(), + new Duration(failedScheduledTimeMillis, MILLISECONDS).convertToMostSuccinctTimeUnit(), fullyBlocked, blockedReasons, diff --git a/core/trino-main/src/main/java/io/trino/execution/QueryStateMachine.java b/core/trino-main/src/main/java/io/trino/execution/QueryStateMachine.java index 12edc2096b2c..099855aee0a1 100644 --- a/core/trino-main/src/main/java/io/trino/execution/QueryStateMachine.java +++ b/core/trino-main/src/main/java/io/trino/execution/QueryStateMachine.java @@ -382,13 +382,16 @@ public BasicQueryInfo getBasicQueryInfo(Optional rootStage) stageStats.getPhysicalInputDataSize(), stageStats.getCumulativeUserMemory(), + stageStats.getFailedCumulativeUserMemory(), stageStats.getUserMemoryReservation(), stageStats.getTotalMemoryReservation(), succinctBytes(getPeakUserMemoryInBytes()), succinctBytes(getPeakTotalMemoryInBytes()), stageStats.getTotalCpuTime(), + stageStats.getFailedCpuTime(), stageStats.getTotalScheduledTime(), + stageStats.getFailedScheduledTime(), stageStats.isFullyBlocked(), stageStats.getBlockedReasons(), @@ -470,6 +473,7 @@ private QueryStats getQueryStats(Optional rootStage) int totalTasks = 0; int runningTasks = 0; int completedTasks = 0; + int failedTasks = 0; int totalDrivers = 0; int queuedDrivers = 0; @@ -478,31 +482,46 @@ private QueryStats getQueryStats(Optional rootStage) int completedDrivers = 0; long cumulativeUserMemory = 0; + long failedCumulativeUserMemory = 0; long userMemoryReservation = 0; long revocableMemoryReservation = 0; long totalMemoryReservation = 0; long totalScheduledTime = 0; + long failedScheduledTime = 0; long totalCpuTime = 0; + long failedCpuTime = 0; long totalBlockedTime = 0; long physicalInputDataSize = 0; + long failedPhysicalInputDataSize = 0; long physicalInputPositions = 0; + long failedPhysicalInputPositions = 0; long physicalInputReadTime = 0; + long failedPhysicalInputReadTime = 0; long internalNetworkInputDataSize = 0; + long failedInternalNetworkInputDataSize = 0; long internalNetworkInputPositions = 0; + long failedInternalNetworkInputPositions = 0; long rawInputDataSize = 0; + long failedRawInputDataSize = 0; long rawInputPositions = 0; + long failedRawInputPositions = 0; long processedInputDataSize = 0; + long failedProcessedInputDataSize = 0; long processedInputPositions = 0; + long failedProcessedInputPositions = 0; long outputDataSize = 0; + long failedOutputDataSize = 0; long outputPositions = 0; + long failedOutputPositions = 0; long physicalWrittenDataSize = 0; + long failedPhysicalWrittenDataSize = 0; ImmutableList.Builder stageGcStatistics = ImmutableList.builder(); @@ -516,6 +535,7 @@ private QueryStats getQueryStats(Optional rootStage) totalTasks += stageStats.getTotalTasks(); runningTasks += stageStats.getRunningTasks(); completedTasks += stageStats.getCompletedTasks(); + failedTasks += stageStats.getFailedTasks(); totalDrivers += stageStats.getTotalDrivers(); queuedDrivers += stageStats.getQueuedDrivers(); @@ -524,11 +544,14 @@ private QueryStats getQueryStats(Optional rootStage) completedDrivers += stageStats.getCompletedDrivers(); cumulativeUserMemory += stageStats.getCumulativeUserMemory(); + failedCumulativeUserMemory += stageStats.getFailedCumulativeUserMemory(); userMemoryReservation += stageStats.getUserMemoryReservation().toBytes(); revocableMemoryReservation += stageStats.getRevocableMemoryReservation().toBytes(); totalMemoryReservation += stageStats.getTotalMemoryReservation().toBytes(); totalScheduledTime += stageStats.getTotalScheduledTime().roundTo(MILLISECONDS); + failedScheduledTime += stageStats.getFailedScheduledTime().roundTo(MILLISECONDS); totalCpuTime += stageStats.getTotalCpuTime().roundTo(MILLISECONDS); + failedCpuTime += stageStats.getFailedCpuTime().roundTo(MILLISECONDS); totalBlockedTime += stageStats.getTotalBlockedTime().roundTo(MILLISECONDS); if (!stageInfo.getState().isDone()) { fullyBlocked &= stageStats.isFullyBlocked(); @@ -536,22 +559,32 @@ private QueryStats getQueryStats(Optional rootStage) } physicalInputDataSize += stageStats.getPhysicalInputDataSize().toBytes(); + failedPhysicalInputDataSize += stageStats.getFailedPhysicalInputDataSize().toBytes(); physicalInputPositions += stageStats.getPhysicalInputPositions(); + failedPhysicalInputPositions += stageStats.getFailedPhysicalInputPositions(); physicalInputReadTime += stageStats.getPhysicalInputReadTime().roundTo(MILLISECONDS); + failedPhysicalInputReadTime += stageStats.getFailedPhysicalInputReadTime().roundTo(MILLISECONDS); internalNetworkInputDataSize += stageStats.getInternalNetworkInputDataSize().toBytes(); + failedInternalNetworkInputDataSize += stageStats.getFailedInternalNetworkInputDataSize().toBytes(); internalNetworkInputPositions += stageStats.getInternalNetworkInputPositions(); + failedInternalNetworkInputPositions += stageStats.getFailedInternalNetworkInputPositions(); PlanFragment plan = stageInfo.getPlan(); if (plan != null && plan.getPartitionedSourceNodes().stream().anyMatch(TableScanNode.class::isInstance)) { rawInputDataSize += stageStats.getRawInputDataSize().toBytes(); + failedRawInputDataSize += stageStats.getFailedRawInputDataSize().toBytes(); rawInputPositions += stageStats.getRawInputPositions(); + failedRawInputPositions += stageStats.getFailedRawInputPositions(); processedInputDataSize += stageStats.getProcessedInputDataSize().toBytes(); + failedProcessedInputDataSize += stageStats.getFailedProcessedInputDataSize().toBytes(); processedInputPositions += stageStats.getProcessedInputPositions(); + failedProcessedInputPositions += stageStats.getFailedProcessedInputPositions(); } physicalWrittenDataSize += stageStats.getPhysicalWrittenDataSize().toBytes(); + failedPhysicalWrittenDataSize += stageStats.getFailedPhysicalWrittenDataSize().toBytes(); stageGcStatistics.add(stageStats.getGcInfo()); @@ -562,7 +595,9 @@ private QueryStats getQueryStats(Optional rootStage) if (rootStage.isPresent()) { StageStats outputStageStats = rootStage.get().getStageStats(); outputDataSize += outputStageStats.getOutputDataSize().toBytes(); + failedOutputDataSize += outputStageStats.getFailedOutputDataSize().toBytes(); outputPositions += outputStageStats.getOutputPositions(); + failedOutputPositions += outputStageStats.getFailedOutputPositions(); } boolean isScheduled = isScheduled(rootStage); @@ -585,6 +620,7 @@ private QueryStats getQueryStats(Optional rootStage) totalTasks, runningTasks, completedTasks, + failedTasks, totalDrivers, queuedDrivers, @@ -593,6 +629,7 @@ private QueryStats getQueryStats(Optional rootStage) completedDrivers, cumulativeUserMemory, + failedCumulativeUserMemory, succinctBytes(userMemoryReservation), succinctBytes(revocableMemoryReservation), succinctBytes(totalMemoryReservation), @@ -606,24 +643,38 @@ private QueryStats getQueryStats(Optional rootStage) isScheduled, new Duration(totalScheduledTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), + new Duration(failedScheduledTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), new Duration(totalCpuTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), + new Duration(failedCpuTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), new Duration(totalBlockedTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), fullyBlocked, blockedReasons, succinctBytes(physicalInputDataSize), + succinctBytes(failedPhysicalInputDataSize), physicalInputPositions, + failedPhysicalInputPositions, new Duration(physicalInputReadTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), + new Duration(failedPhysicalInputReadTime, MILLISECONDS).convertToMostSuccinctTimeUnit(), succinctBytes(internalNetworkInputDataSize), + succinctBytes(failedInternalNetworkInputDataSize), internalNetworkInputPositions, + failedInternalNetworkInputPositions, succinctBytes(rawInputDataSize), + succinctBytes(failedRawInputDataSize), rawInputPositions, + failedRawInputPositions, succinctBytes(processedInputDataSize), + succinctBytes(failedProcessedInputDataSize), processedInputPositions, + failedProcessedInputPositions, succinctBytes(outputDataSize), + succinctBytes(failedOutputDataSize), outputPositions, + failedOutputPositions, succinctBytes(physicalWrittenDataSize), + succinctBytes(failedPhysicalWrittenDataSize), stageGcStatistics.build(), @@ -1136,6 +1187,7 @@ private static QueryStats pruneQueryStats(QueryStats queryStats) queryStats.getPlanningTime(), queryStats.getFinishingTime(), queryStats.getTotalTasks(), + queryStats.getFailedTasks(), queryStats.getRunningTasks(), queryStats.getCompletedTasks(), queryStats.getTotalDrivers(), @@ -1144,6 +1196,7 @@ private static QueryStats pruneQueryStats(QueryStats queryStats) queryStats.getBlockedDrivers(), queryStats.getCompletedDrivers(), queryStats.getCumulativeUserMemory(), + queryStats.getFailedCumulativeUserMemory(), queryStats.getUserMemoryReservation(), queryStats.getRevocableMemoryReservation(), queryStats.getTotalMemoryReservation(), @@ -1155,22 +1208,36 @@ private static QueryStats pruneQueryStats(QueryStats queryStats) queryStats.getPeakTaskTotalMemory(), queryStats.isScheduled(), queryStats.getTotalScheduledTime(), + queryStats.getFailedScheduledTime(), queryStats.getTotalCpuTime(), + queryStats.getFailedCpuTime(), queryStats.getTotalBlockedTime(), queryStats.isFullyBlocked(), queryStats.getBlockedReasons(), queryStats.getPhysicalInputDataSize(), + queryStats.getFailedPhysicalInputDataSize(), queryStats.getPhysicalInputPositions(), + queryStats.getFailedPhysicalInputPositions(), queryStats.getPhysicalInputReadTime(), + queryStats.getFailedPhysicalInputReadTime(), queryStats.getInternalNetworkInputDataSize(), + queryStats.getFailedInternalNetworkInputDataSize(), queryStats.getInternalNetworkInputPositions(), + queryStats.getFailedInternalNetworkInputPositions(), queryStats.getRawInputDataSize(), + queryStats.getFailedRawInputDataSize(), queryStats.getRawInputPositions(), + queryStats.getFailedRawInputPositions(), queryStats.getProcessedInputDataSize(), + queryStats.getFailedProcessedInputDataSize(), queryStats.getProcessedInputPositions(), + queryStats.getFailedProcessedInputPositions(), queryStats.getOutputDataSize(), + queryStats.getFailedOutputDataSize(), queryStats.getOutputPositions(), + queryStats.getFailedOutputPositions(), queryStats.getPhysicalWrittenDataSize(), + queryStats.getFailedPhysicalWrittenDataSize(), queryStats.getStageGcStatistics(), queryStats.getDynamicFiltersStats(), ImmutableList.of()); // Remove the operator summaries as OperatorInfo (especially DirectExchangeClientStatus) can hold onto a large amount of memory diff --git a/core/trino-main/src/main/java/io/trino/execution/QueryStats.java b/core/trino-main/src/main/java/io/trino/execution/QueryStats.java index 3631fab377aa..40decaa2a3af 100644 --- a/core/trino-main/src/main/java/io/trino/execution/QueryStats.java +++ b/core/trino-main/src/main/java/io/trino/execution/QueryStats.java @@ -57,6 +57,7 @@ public class QueryStats private final int totalTasks; private final int runningTasks; private final int completedTasks; + private final int failedTasks; private final int totalDrivers; private final int queuedDrivers; @@ -65,6 +66,7 @@ public class QueryStats private final int completedDrivers; private final double cumulativeUserMemory; + private final double failedCumulativeUserMemory; private final DataSize userMemoryReservation; private final DataSize revocableMemoryReservation; private final DataSize totalMemoryReservation; @@ -77,28 +79,42 @@ public class QueryStats private final boolean scheduled; private final Duration totalScheduledTime; + private final Duration failedScheduledTime; private final Duration totalCpuTime; + private final Duration failedCpuTime; private final Duration totalBlockedTime; private final boolean fullyBlocked; private final Set blockedReasons; private final DataSize physicalInputDataSize; + private final DataSize failedPhysicalInputDataSize; private final long physicalInputPositions; + private final long failedPhysicalInputPositions; private final Duration physicalInputReadTime; + private final Duration failedPhysicalInputReadTime; private final DataSize internalNetworkInputDataSize; + private final DataSize failedInternalNetworkInputDataSize; private final long internalNetworkInputPositions; + private final long failedInternalNetworkInputPositions; private final DataSize rawInputDataSize; + private final DataSize failedRawInputDataSize; private final long rawInputPositions; + private final long failedRawInputPositions; private final DataSize processedInputDataSize; + private final DataSize failedProcessedInputDataSize; private final long processedInputPositions; + private final long failedProcessedInputPositions; private final DataSize outputDataSize; + private final DataSize failedOutputDataSize; private final long outputPositions; + private final long failedOutputPositions; private final DataSize physicalWrittenDataSize; + private final DataSize failedPhysicalWrittenDataSize; private final List stageGcStatistics; @@ -125,6 +141,7 @@ public QueryStats( @JsonProperty("totalTasks") int totalTasks, @JsonProperty("runningTasks") int runningTasks, @JsonProperty("completedTasks") int completedTasks, + @JsonProperty("failedTasks") int failedTasks, @JsonProperty("totalDrivers") int totalDrivers, @JsonProperty("queuedDrivers") int queuedDrivers, @@ -133,6 +150,7 @@ public QueryStats( @JsonProperty("completedDrivers") int completedDrivers, @JsonProperty("cumulativeUserMemory") double cumulativeUserMemory, + @JsonProperty("failedCumulativeUserMemory") double failedCumulativeUserMemory, @JsonProperty("userMemoryReservation") DataSize userMemoryReservation, @JsonProperty("revocableMemoryReservation") DataSize revocableMemoryReservation, @JsonProperty("totalMemoryReservation") DataSize totalMemoryReservation, @@ -145,28 +163,42 @@ public QueryStats( @JsonProperty("scheduled") boolean scheduled, @JsonProperty("totalScheduledTime") Duration totalScheduledTime, + @JsonProperty("failedScheduledTime") Duration failedScheduledTime, @JsonProperty("totalCpuTime") Duration totalCpuTime, + @JsonProperty("failedCpuTime") Duration failedCpuTime, @JsonProperty("totalBlockedTime") Duration totalBlockedTime, @JsonProperty("fullyBlocked") boolean fullyBlocked, @JsonProperty("blockedReasons") Set blockedReasons, @JsonProperty("physicalInputDataSize") DataSize physicalInputDataSize, + @JsonProperty("failedPhysicalInputDataSize") DataSize failedPhysicalInputDataSize, @JsonProperty("physicalInputPositions") long physicalInputPositions, + @JsonProperty("failedPhysicalInputPositions") long failedPhysicalInputPositions, @JsonProperty("physicalInputReadTime") Duration physicalInputReadTime, + @JsonProperty("failedPhysicalInputReadTime") Duration failedPhysicalInputReadTime, @JsonProperty("internalNetworkInputDataSize") DataSize internalNetworkInputDataSize, + @JsonProperty("failedInternalNetworkInputDataSize") DataSize failedInternalNetworkInputDataSize, @JsonProperty("internalNetworkInputPositions") long internalNetworkInputPositions, + @JsonProperty("failedInternalNetworkInputPositions") long failedInternalNetworkInputPositions, @JsonProperty("rawInputDataSize") DataSize rawInputDataSize, + @JsonProperty("failedRawInputDataSize") DataSize failedRawInputDataSize, @JsonProperty("rawInputPositions") long rawInputPositions, + @JsonProperty("failedRawInputPositions") long failedRawInputPositions, @JsonProperty("processedInputDataSize") DataSize processedInputDataSize, + @JsonProperty("failedProcessedInputDataSize") DataSize failedProcessedInputDataSize, @JsonProperty("processedInputPositions") long processedInputPositions, + @JsonProperty("failedProcessedInputPositions") long failedProcessedInputPositions, @JsonProperty("outputDataSize") DataSize outputDataSize, + @JsonProperty("failedOutputDataSize") DataSize failedOutputDataSize, @JsonProperty("outputPositions") long outputPositions, + @JsonProperty("failedOutputPositions") long failedOutputPositions, @JsonProperty("physicalWrittenDataSize") DataSize physicalWrittenDataSize, + @JsonProperty("failedPhysicalWrittenDataSize") DataSize failedPhysicalWrittenDataSize, @JsonProperty("stageGcStatistics") List stageGcStatistics, @@ -194,6 +226,8 @@ public QueryStats( this.runningTasks = runningTasks; checkArgument(completedTasks >= 0, "completedTasks is negative"); this.completedTasks = completedTasks; + checkArgument(failedTasks >= 0, "failedTasks is negative"); + this.failedTasks = failedTasks; checkArgument(totalDrivers >= 0, "totalDrivers is negative"); this.totalDrivers = totalDrivers; @@ -207,6 +241,7 @@ public QueryStats( this.completedDrivers = completedDrivers; checkArgument(cumulativeUserMemory >= 0, "cumulativeUserMemory is negative"); this.cumulativeUserMemory = cumulativeUserMemory; + this.failedCumulativeUserMemory = failedCumulativeUserMemory; this.userMemoryReservation = requireNonNull(userMemoryReservation, "userMemoryReservation is null"); this.revocableMemoryReservation = requireNonNull(revocableMemoryReservation, "revocableMemoryReservation is null"); this.totalMemoryReservation = requireNonNull(totalMemoryReservation, "totalMemoryReservation is null"); @@ -218,33 +253,52 @@ public QueryStats( this.peakTaskTotalMemory = requireNonNull(peakTaskTotalMemory, "peakTaskTotalMemory is null"); this.scheduled = scheduled; this.totalScheduledTime = requireNonNull(totalScheduledTime, "totalScheduledTime is null"); + this.failedScheduledTime = requireNonNull(failedScheduledTime, "failedScheduledTime is null"); this.totalCpuTime = requireNonNull(totalCpuTime, "totalCpuTime is null"); + this.failedCpuTime = requireNonNull(failedCpuTime, "failedCpuTime is null"); this.totalBlockedTime = requireNonNull(totalBlockedTime, "totalBlockedTime is null"); this.fullyBlocked = fullyBlocked; this.blockedReasons = ImmutableSet.copyOf(requireNonNull(blockedReasons, "blockedReasons is null")); this.physicalInputDataSize = requireNonNull(physicalInputDataSize, "physicalInputDataSize is null"); + this.failedPhysicalInputDataSize = requireNonNull(failedPhysicalInputDataSize, "failedPhysicalInputDataSize is null"); checkArgument(physicalInputPositions >= 0, "physicalInputPositions is negative"); this.physicalInputPositions = physicalInputPositions; + checkArgument(failedPhysicalInputPositions >= 0, "failedPhysicalInputPositions is negative"); + this.failedPhysicalInputPositions = failedPhysicalInputPositions; this.physicalInputReadTime = requireNonNull(physicalInputReadTime, "physicalInputReadTime is null"); + this.failedPhysicalInputReadTime = requireNonNull(failedPhysicalInputReadTime, "failedPhysicalInputReadTime is null"); this.internalNetworkInputDataSize = requireNonNull(internalNetworkInputDataSize, "internalNetworkInputDataSize is null"); + this.failedInternalNetworkInputDataSize = requireNonNull(failedInternalNetworkInputDataSize, "failedInternalNetworkInputDataSize is null"); checkArgument(internalNetworkInputPositions >= 0, "internalNetworkInputPositions is negative"); this.internalNetworkInputPositions = internalNetworkInputPositions; + checkArgument(failedInternalNetworkInputPositions >= 0, "failedInternalNetworkInputPositions is negative"); + this.failedInternalNetworkInputPositions = failedInternalNetworkInputPositions; this.rawInputDataSize = requireNonNull(rawInputDataSize, "rawInputDataSize is null"); + this.failedRawInputDataSize = requireNonNull(failedRawInputDataSize, "failedRawInputDataSize is null"); checkArgument(rawInputPositions >= 0, "rawInputPositions is negative"); this.rawInputPositions = rawInputPositions; + checkArgument(failedRawInputPositions >= 0, "failedRawInputPositions is negative"); + this.failedRawInputPositions = failedRawInputPositions; this.processedInputDataSize = requireNonNull(processedInputDataSize, "processedInputDataSize is null"); + this.failedProcessedInputDataSize = requireNonNull(failedProcessedInputDataSize, "failedProcessedInputDataSize is null"); checkArgument(processedInputPositions >= 0, "processedInputPositions is negative"); this.processedInputPositions = processedInputPositions; + checkArgument(failedProcessedInputPositions >= 0, "failedProcessedInputPositions is negative"); + this.failedProcessedInputPositions = failedProcessedInputPositions; this.outputDataSize = requireNonNull(outputDataSize, "outputDataSize is null"); + this.failedOutputDataSize = requireNonNull(failedOutputDataSize, "failedOutputDataSize is null"); checkArgument(outputPositions >= 0, "outputPositions is negative"); this.outputPositions = outputPositions; + checkArgument(failedOutputPositions >= 0, "failedOutputPositions is negative"); + this.failedOutputPositions = failedOutputPositions; this.physicalWrittenDataSize = requireNonNull(physicalWrittenDataSize, "physicalWrittenDataSize is null"); + this.failedPhysicalWrittenDataSize = requireNonNull(failedPhysicalWrittenDataSize, "failedPhysicalWrittenDataSize is null"); this.stageGcStatistics = ImmutableList.copyOf(requireNonNull(stageGcStatistics, "stageGcStatistics is null")); @@ -332,6 +386,12 @@ public int getTotalTasks() return totalTasks; } + @JsonProperty + public int getFailedTasks() + { + return failedTasks; + } + @JsonProperty public int getRunningTasks() { @@ -380,6 +440,12 @@ public double getCumulativeUserMemory() return cumulativeUserMemory; } + @JsonProperty + public double getFailedCumulativeUserMemory() + { + return failedCumulativeUserMemory; + } + @JsonProperty public DataSize getUserMemoryReservation() { @@ -446,12 +512,24 @@ public Duration getTotalScheduledTime() return totalScheduledTime; } + @JsonProperty + public Duration getFailedScheduledTime() + { + return failedScheduledTime; + } + @JsonProperty public Duration getTotalCpuTime() { return totalCpuTime; } + @JsonProperty + public Duration getFailedCpuTime() + { + return failedCpuTime; + } + @JsonProperty public Duration getTotalBlockedTime() { @@ -476,72 +554,144 @@ public DataSize getPhysicalInputDataSize() return physicalInputDataSize; } + @JsonProperty + public DataSize getFailedPhysicalInputDataSize() + { + return failedPhysicalInputDataSize; + } + @JsonProperty public long getPhysicalInputPositions() { return physicalInputPositions; } + @JsonProperty + public long getFailedPhysicalInputPositions() + { + return failedPhysicalInputPositions; + } + @JsonProperty public Duration getPhysicalInputReadTime() { return physicalInputReadTime; } + @JsonProperty + public Duration getFailedPhysicalInputReadTime() + { + return failedPhysicalInputReadTime; + } + @JsonProperty public DataSize getInternalNetworkInputDataSize() { return internalNetworkInputDataSize; } + @JsonProperty + public DataSize getFailedInternalNetworkInputDataSize() + { + return failedInternalNetworkInputDataSize; + } + @JsonProperty public long getInternalNetworkInputPositions() { return internalNetworkInputPositions; } + @JsonProperty + public long getFailedInternalNetworkInputPositions() + { + return failedInternalNetworkInputPositions; + } + @JsonProperty public DataSize getRawInputDataSize() { return rawInputDataSize; } + @JsonProperty + public DataSize getFailedRawInputDataSize() + { + return failedRawInputDataSize; + } + @JsonProperty public long getRawInputPositions() { return rawInputPositions; } + @JsonProperty + public long getFailedRawInputPositions() + { + return failedRawInputPositions; + } + @JsonProperty public DataSize getProcessedInputDataSize() { return processedInputDataSize; } + @JsonProperty + public DataSize getFailedProcessedInputDataSize() + { + return failedProcessedInputDataSize; + } + @JsonProperty public long getProcessedInputPositions() { return processedInputPositions; } + @JsonProperty + public long getFailedProcessedInputPositions() + { + return failedProcessedInputPositions; + } + @JsonProperty public DataSize getOutputDataSize() { return outputDataSize; } + @JsonProperty + public DataSize getFailedOutputDataSize() + { + return failedOutputDataSize; + } + @JsonProperty public long getOutputPositions() { return outputPositions; } + @JsonProperty + public long getFailedOutputPositions() + { + return failedOutputPositions; + } + @JsonProperty public DataSize getPhysicalWrittenDataSize() { return physicalWrittenDataSize; } + @JsonProperty + public DataSize getFailedPhysicalWrittenDataSize() + { + return failedPhysicalWrittenDataSize; + } + @JsonProperty public long getWrittenPositions() { diff --git a/core/trino-main/src/main/java/io/trino/execution/StageStateMachine.java b/core/trino-main/src/main/java/io/trino/execution/StageStateMachine.java index 950b0fd8708d..60cfc09a79eb 100644 --- a/core/trino-main/src/main/java/io/trino/execution/StageStateMachine.java +++ b/core/trino-main/src/main/java/io/trino/execution/StageStateMachine.java @@ -242,11 +242,14 @@ public BasicStageStats getBasicStageStats(Supplier> taskInfos int completedDrivers = 0; long cumulativeUserMemory = 0; + long failedCumulativeUserMemory = 0; long userMemoryReservation = 0; long totalMemoryReservation = 0; long totalScheduledTime = 0; + long failedScheduledTime = 0; long totalCpuTime = 0; + long failedCpuTime = 0; long physicalInputDataSize = 0; long physicalInputPositions = 0; @@ -271,6 +274,9 @@ public BasicStageStats getBasicStageStats(Supplier> taskInfos completedDrivers += taskStats.getCompletedDrivers(); cumulativeUserMemory += taskStats.getCumulativeUserMemory(); + if (taskState == TaskState.FAILED) { + failedCumulativeUserMemory += taskStats.getCumulativeUserMemory(); + } long taskUserMemory = taskStats.getUserMemoryReservation().toBytes(); long taskRevocableMemory = taskStats.getRevocableMemoryReservation().toBytes(); @@ -279,6 +285,10 @@ public BasicStageStats getBasicStageStats(Supplier> taskInfos totalScheduledTime += taskStats.getTotalScheduledTime().roundTo(NANOSECONDS); totalCpuTime += taskStats.getTotalCpuTime().roundTo(NANOSECONDS); + if (taskState == TaskState.FAILED) { + failedScheduledTime += taskStats.getTotalScheduledTime().roundTo(NANOSECONDS); + failedCpuTime += taskStats.getTotalCpuTime().roundTo(NANOSECONDS); + } if (!taskState.isDone()) { fullyBlocked &= taskStats.isFullyBlocked(); blockedReasons.addAll(taskStats.getBlockedReasons()); @@ -321,11 +331,14 @@ public BasicStageStats getBasicStageStats(Supplier> taskInfos rawInputPositions, cumulativeUserMemory, + failedCumulativeUserMemory, succinctBytes(userMemoryReservation), succinctBytes(totalMemoryReservation), new Duration(totalCpuTime, NANOSECONDS).convertToMostSuccinctTimeUnit(), + new Duration(failedCpuTime, NANOSECONDS).convertToMostSuccinctTimeUnit(), new Duration(totalScheduledTime, NANOSECONDS).convertToMostSuccinctTimeUnit(), + new Duration(failedScheduledTime, NANOSECONDS).convertToMostSuccinctTimeUnit(), fullyBlocked, blockedReasons, @@ -360,6 +373,7 @@ public StageInfo getStageInfo(Supplier> taskInfosSupplier) int completedDrivers = 0; long cumulativeUserMemory = 0; + long failedCumulativeUserMemory = 0; long userMemoryReservation = 0; long revocableMemoryReservation = 0; long totalMemoryReservation = 0; @@ -367,27 +381,41 @@ public StageInfo getStageInfo(Supplier> taskInfosSupplier) long peakRevocableMemoryReservation = peakRevocableMemory.get(); long totalScheduledTime = 0; + long failedScheduledTime = 0; long totalCpuTime = 0; + long failedCpuTime = 0; long totalBlockedTime = 0; long physicalInputDataSize = 0; + long failedPhysicalInputDataSize = 0; long physicalInputPositions = 0; + long failedPhysicalInputPositions = 0; long physicalInputReadTime = 0; + long failedPhysicalInputReadTime = 0; long internalNetworkInputDataSize = 0; + long failedInternalNetworkInputDataSize = 0; long internalNetworkInputPositions = 0; + long failedInternalNetworkInputPositions = 0; long rawInputDataSize = 0; + long failedRawInputDataSize = 0; long rawInputPositions = 0; + long failedRawInputPositions = 0; long processedInputDataSize = 0; + long failedProcessedInputDataSize = 0; long processedInputPositions = 0; + long failedProcessedInputPositions = 0; long bufferedDataSize = 0; long outputDataSize = 0; + long failedOutputDataSize = 0; long outputPositions = 0; + long failedOutputPositions = 0; long physicalWrittenDataSize = 0; + long failedPhysicalWrittenDataSize = 0; int fullGcCount = 0; int fullGcTaskCount = 0; @@ -421,6 +449,9 @@ public StageInfo getStageInfo(Supplier> taskInfosSupplier) completedDrivers += taskStats.getCompletedDrivers(); cumulativeUserMemory += taskStats.getCumulativeUserMemory(); + if (taskState == TaskState.FAILED) { + failedCumulativeUserMemory += taskStats.getCumulativeUserMemory(); + } long taskUserMemory = taskStats.getUserMemoryReservation().toBytes(); long taskRevocableMemory = taskStats.getRevocableMemoryReservation().toBytes(); @@ -431,6 +462,10 @@ public StageInfo getStageInfo(Supplier> taskInfosSupplier) totalScheduledTime += taskStats.getTotalScheduledTime().roundTo(NANOSECONDS); totalCpuTime += taskStats.getTotalCpuTime().roundTo(NANOSECONDS); totalBlockedTime += taskStats.getTotalBlockedTime().roundTo(NANOSECONDS); + if (taskState == TaskState.FAILED) { + failedScheduledTime += taskStats.getTotalScheduledTime().roundTo(NANOSECONDS); + failedCpuTime += taskStats.getTotalCpuTime().roundTo(NANOSECONDS); + } if (!taskState.isDone()) { fullyBlocked &= taskStats.isFullyBlocked(); blockedReasons.addAll(taskStats.getBlockedReasons()); @@ -455,6 +490,26 @@ public StageInfo getStageInfo(Supplier> taskInfosSupplier) physicalWrittenDataSize += taskStats.getPhysicalWrittenDataSize().toBytes(); + if (taskState == TaskState.FAILED) { + failedPhysicalInputDataSize += taskStats.getPhysicalInputDataSize().toBytes(); + failedPhysicalInputPositions += taskStats.getPhysicalInputPositions(); + failedPhysicalInputReadTime += taskStats.getPhysicalInputReadTime().roundTo(NANOSECONDS); + + failedInternalNetworkInputDataSize += taskStats.getInternalNetworkInputDataSize().toBytes(); + failedInternalNetworkInputPositions += taskStats.getInternalNetworkInputPositions(); + + failedRawInputDataSize += taskStats.getRawInputDataSize().toBytes(); + failedRawInputPositions += taskStats.getRawInputPositions(); + + failedProcessedInputDataSize += taskStats.getProcessedInputDataSize().toBytes(); + failedProcessedInputPositions += taskStats.getProcessedInputPositions(); + + failedOutputDataSize += taskStats.getOutputDataSize().toBytes(); + failedOutputPositions += taskStats.getOutputPositions(); + + failedPhysicalWrittenDataSize += taskStats.getPhysicalWrittenDataSize().toBytes(); + } + fullGcCount += taskStats.getFullGcCount(); fullGcTaskCount += taskStats.getFullGcCount() > 0 ? 1 : 0; @@ -487,33 +542,48 @@ public StageInfo getStageInfo(Supplier> taskInfosSupplier) completedDrivers, cumulativeUserMemory, + failedCumulativeUserMemory, succinctBytes(userMemoryReservation), succinctBytes(revocableMemoryReservation), succinctBytes(totalMemoryReservation), succinctBytes(peakUserMemoryReservation), succinctBytes(peakRevocableMemoryReservation), succinctDuration(totalScheduledTime, NANOSECONDS), + succinctDuration(failedScheduledTime, NANOSECONDS), succinctDuration(totalCpuTime, NANOSECONDS), + succinctDuration(failedCpuTime, NANOSECONDS), succinctDuration(totalBlockedTime, NANOSECONDS), fullyBlocked && runningTasks > 0, blockedReasons, succinctBytes(physicalInputDataSize), + succinctBytes(failedPhysicalInputDataSize), physicalInputPositions, + failedPhysicalInputPositions, succinctDuration(physicalInputReadTime, NANOSECONDS), + succinctDuration(failedPhysicalInputReadTime, NANOSECONDS), succinctBytes(internalNetworkInputDataSize), + succinctBytes(failedInternalNetworkInputDataSize), internalNetworkInputPositions, + failedInternalNetworkInputPositions, succinctBytes(rawInputDataSize), + succinctBytes(failedRawInputDataSize), rawInputPositions, + failedRawInputPositions, succinctBytes(processedInputDataSize), + succinctBytes(failedProcessedInputDataSize), processedInputPositions, + failedProcessedInputPositions, succinctBytes(bufferedDataSize), succinctBytes(outputDataSize), + succinctBytes(failedOutputDataSize), outputPositions, + failedOutputPositions, succinctBytes(physicalWrittenDataSize), + succinctBytes(failedPhysicalWrittenDataSize), new StageGcStatistics( stageId.getId(), diff --git a/core/trino-main/src/main/java/io/trino/execution/StageStats.java b/core/trino-main/src/main/java/io/trino/execution/StageStats.java index efb457f701df..8f97194ed45b 100644 --- a/core/trino-main/src/main/java/io/trino/execution/StageStats.java +++ b/core/trino-main/src/main/java/io/trino/execution/StageStats.java @@ -55,6 +55,7 @@ public class StageStats private final int completedDrivers; private final double cumulativeUserMemory; + private final double failedCumulativeUserMemory; private final DataSize userMemoryReservation; private final DataSize revocableMemoryReservation; private final DataSize totalMemoryReservation; @@ -62,29 +63,43 @@ public class StageStats private final DataSize peakRevocableMemoryReservation; private final Duration totalScheduledTime; + private final Duration failedScheduledTime; private final Duration totalCpuTime; + private final Duration failedCpuTime; private final Duration totalBlockedTime; private final boolean fullyBlocked; private final Set blockedReasons; private final DataSize physicalInputDataSize; + private final DataSize failedPhysicalInputDataSize; private final long physicalInputPositions; + private final long failedPhysicalInputPositions; private final Duration physicalInputReadTime; + private final Duration failedPhysicalInputReadTime; private final DataSize internalNetworkInputDataSize; + private final DataSize failedInternalNetworkInputDataSize; private final long internalNetworkInputPositions; + private final long failedInternalNetworkInputPositions; private final DataSize rawInputDataSize; + private final DataSize failedRawInputDataSize; private final long rawInputPositions; + private final long failedRawInputPositions; private final DataSize processedInputDataSize; + private final DataSize failedProcessedInputDataSize; private final long processedInputPositions; + private final long failedProcessedInputPositions; private final DataSize bufferedDataSize; private final DataSize outputDataSize; + private final DataSize failedOutputDataSize; private final long outputPositions; + private final long failedOutputPositions; private final DataSize physicalWrittenDataSize; + private final DataSize failedPhysicalWrittenDataSize; private final StageGcStatistics gcInfo; @@ -108,6 +123,7 @@ public StageStats( @JsonProperty("completedDrivers") int completedDrivers, @JsonProperty("cumulativeUserMemory") double cumulativeUserMemory, + @JsonProperty("failedCumulativeUserMemory") double failedCumulativeUserMemory, @JsonProperty("userMemoryReservation") DataSize userMemoryReservation, @JsonProperty("revocableMemoryReservation") DataSize revocableMemoryReservation, @JsonProperty("totalMemoryReservation") DataSize totalMemoryReservation, @@ -115,29 +131,43 @@ public StageStats( @JsonProperty("peakRevocableMemoryReservation") DataSize peakRevocableMemoryReservation, @JsonProperty("totalScheduledTime") Duration totalScheduledTime, + @JsonProperty("failedScheduledTime") Duration failedScheduledTime, @JsonProperty("totalCpuTime") Duration totalCpuTime, + @JsonProperty("failedCpuTime") Duration failedCpuTime, @JsonProperty("totalBlockedTime") Duration totalBlockedTime, @JsonProperty("fullyBlocked") boolean fullyBlocked, @JsonProperty("blockedReasons") Set blockedReasons, @JsonProperty("physicalInputDataSize") DataSize physicalInputDataSize, + @JsonProperty("failedPhysicalInputDataSize") DataSize failedPhysicalInputDataSize, @JsonProperty("physicalInputPositions") long physicalInputPositions, + @JsonProperty("failedPhysicalInputPositions") long failedPhysicalInputPositions, @JsonProperty("physicalInputReadTime") Duration physicalInputReadTime, + @JsonProperty("failedPhysicalInputReadTime") Duration failedPhysicalInputReadTime, @JsonProperty("internalNetworkInputDataSize") DataSize internalNetworkInputDataSize, + @JsonProperty("failedInternalNetworkInputDataSize") DataSize failedInternalNetworkInputDataSize, @JsonProperty("internalNetworkInputPositions") long internalNetworkInputPositions, + @JsonProperty("failedInternalNetworkInputPositions") long failedInternalNetworkInputPositions, @JsonProperty("rawInputDataSize") DataSize rawInputDataSize, + @JsonProperty("failedRawInputDataSize") DataSize failedRawInputDataSize, @JsonProperty("rawInputPositions") long rawInputPositions, + @JsonProperty("failedRawInputPositions") long failedRawInputPositions, @JsonProperty("processedInputDataSize") DataSize processedInputDataSize, + @JsonProperty("failedProcessedInputDataSize") DataSize failedProcessedInputDataSize, @JsonProperty("processedInputPositions") long processedInputPositions, + @JsonProperty("failedProcessedInputPositions") long failedProcessedInputPositions, @JsonProperty("bufferedDataSize") DataSize bufferedDataSize, @JsonProperty("outputDataSize") DataSize outputDataSize, + @JsonProperty("failedOutputDataSize") DataSize failedOutputDataSize, @JsonProperty("outputPositions") long outputPositions, + @JsonProperty("failedOutputPositions") long failedOutputPositions, @JsonProperty("physicalWrittenDataSize") DataSize physicalWrittenDataSize, + @JsonProperty("failedPhysicalWrittenDataSize") DataSize failedPhysicalWrittenDataSize, @JsonProperty("gcInfo") StageGcStatistics gcInfo, @@ -167,6 +197,7 @@ public StageStats( this.completedDrivers = completedDrivers; checkArgument(cumulativeUserMemory >= 0, "cumulativeUserMemory is negative"); this.cumulativeUserMemory = cumulativeUserMemory; + this.failedCumulativeUserMemory = failedCumulativeUserMemory; this.userMemoryReservation = requireNonNull(userMemoryReservation, "userMemoryReservation is null"); this.revocableMemoryReservation = requireNonNull(revocableMemoryReservation, "revocableMemoryReservation is null"); this.totalMemoryReservation = requireNonNull(totalMemoryReservation, "totalMemoryReservation is null"); @@ -174,34 +205,53 @@ public StageStats( this.peakRevocableMemoryReservation = requireNonNull(peakRevocableMemoryReservation, "peakRevocableMemoryReservation is null"); this.totalScheduledTime = requireNonNull(totalScheduledTime, "totalScheduledTime is null"); + this.failedScheduledTime = requireNonNull(failedScheduledTime, "failedScheduledTime is null"); this.totalCpuTime = requireNonNull(totalCpuTime, "totalCpuTime is null"); + this.failedCpuTime = requireNonNull(failedCpuTime, "failedCpuTime is null"); this.totalBlockedTime = requireNonNull(totalBlockedTime, "totalBlockedTime is null"); this.fullyBlocked = fullyBlocked; this.blockedReasons = ImmutableSet.copyOf(requireNonNull(blockedReasons, "blockedReasons is null")); this.physicalInputDataSize = requireNonNull(physicalInputDataSize, "physicalInputDataSize is null"); + this.failedPhysicalInputDataSize = requireNonNull(failedPhysicalInputDataSize, "failedPhysicalInputDataSize is null"); checkArgument(physicalInputPositions >= 0, "physicalInputPositions is negative"); this.physicalInputPositions = physicalInputPositions; + checkArgument(failedPhysicalInputPositions >= 0, "failedPhysicalInputPositions is negative"); + this.failedPhysicalInputPositions = failedPhysicalInputPositions; this.physicalInputReadTime = requireNonNull(physicalInputReadTime, "physicalInputReadTime is null"); + this.failedPhysicalInputReadTime = requireNonNull(failedPhysicalInputReadTime, "failedPhysicalInputReadTime is null"); this.internalNetworkInputDataSize = requireNonNull(internalNetworkInputDataSize, "internalNetworkInputDataSize is null"); + this.failedInternalNetworkInputDataSize = requireNonNull(failedInternalNetworkInputDataSize, "failedInternalNetworkInputDataSize is null"); checkArgument(internalNetworkInputPositions >= 0, "internalNetworkInputPositions is negative"); this.internalNetworkInputPositions = internalNetworkInputPositions; + checkArgument(failedInternalNetworkInputPositions >= 0, "failedInternalNetworkInputPositions is negative"); + this.failedInternalNetworkInputPositions = failedInternalNetworkInputPositions; this.rawInputDataSize = requireNonNull(rawInputDataSize, "rawInputDataSize is null"); + this.failedRawInputDataSize = requireNonNull(failedRawInputDataSize, "failedRawInputDataSize is null"); checkArgument(rawInputPositions >= 0, "rawInputPositions is negative"); this.rawInputPositions = rawInputPositions; + checkArgument(failedRawInputPositions >= 0, "failedRawInputPositions is negative"); + this.failedRawInputPositions = failedRawInputPositions; this.processedInputDataSize = requireNonNull(processedInputDataSize, "processedInputDataSize is null"); + this.failedProcessedInputDataSize = requireNonNull(failedProcessedInputDataSize, "failedProcessedInputDataSize is null"); checkArgument(processedInputPositions >= 0, "processedInputPositions is negative"); this.processedInputPositions = processedInputPositions; + checkArgument(failedProcessedInputPositions >= 0, "failedProcessedInputPositions is negative"); + this.failedProcessedInputPositions = failedProcessedInputPositions; this.bufferedDataSize = requireNonNull(bufferedDataSize, "bufferedDataSize is null"); this.outputDataSize = requireNonNull(outputDataSize, "outputDataSize is null"); + this.failedOutputDataSize = requireNonNull(failedOutputDataSize, "failedOutputDataSize is null"); checkArgument(outputPositions >= 0, "outputPositions is negative"); this.outputPositions = outputPositions; + checkArgument(failedOutputPositions >= 0, "failedOutputPositions is negative"); + this.failedOutputPositions = failedOutputPositions; this.physicalWrittenDataSize = requireNonNull(physicalWrittenDataSize, "physicalWrittenDataSize is null"); + this.failedPhysicalWrittenDataSize = requireNonNull(failedPhysicalWrittenDataSize, "failedPhysicalWrittenDataSize is null"); this.gcInfo = requireNonNull(gcInfo, "gcInfo is null"); @@ -280,6 +330,12 @@ public double getCumulativeUserMemory() return cumulativeUserMemory; } + @JsonProperty + public double getFailedCumulativeUserMemory() + { + return failedCumulativeUserMemory; + } + @JsonProperty public DataSize getUserMemoryReservation() { @@ -316,12 +372,24 @@ public Duration getTotalScheduledTime() return totalScheduledTime; } + @JsonProperty + public Duration getFailedScheduledTime() + { + return failedScheduledTime; + } + @JsonProperty public Duration getTotalCpuTime() { return totalCpuTime; } + @JsonProperty + public Duration getFailedCpuTime() + { + return failedCpuTime; + } + @JsonProperty public Duration getTotalBlockedTime() { @@ -346,54 +414,108 @@ public DataSize getPhysicalInputDataSize() return physicalInputDataSize; } + @JsonProperty + public DataSize getFailedPhysicalInputDataSize() + { + return failedPhysicalInputDataSize; + } + @JsonProperty public long getPhysicalInputPositions() { return physicalInputPositions; } + @JsonProperty + public long getFailedPhysicalInputPositions() + { + return failedPhysicalInputPositions; + } + @JsonProperty public Duration getPhysicalInputReadTime() { return physicalInputReadTime; } + @JsonProperty + public Duration getFailedPhysicalInputReadTime() + { + return failedPhysicalInputReadTime; + } + @JsonProperty public DataSize getInternalNetworkInputDataSize() { return internalNetworkInputDataSize; } + @JsonProperty + public DataSize getFailedInternalNetworkInputDataSize() + { + return failedInternalNetworkInputDataSize; + } + @JsonProperty public long getInternalNetworkInputPositions() { return internalNetworkInputPositions; } + @JsonProperty + public long getFailedInternalNetworkInputPositions() + { + return failedInternalNetworkInputPositions; + } + @JsonProperty public DataSize getRawInputDataSize() { return rawInputDataSize; } + @JsonProperty + public DataSize getFailedRawInputDataSize() + { + return failedRawInputDataSize; + } + @JsonProperty public long getRawInputPositions() { return rawInputPositions; } + @JsonProperty + public long getFailedRawInputPositions() + { + return failedRawInputPositions; + } + @JsonProperty public DataSize getProcessedInputDataSize() { return processedInputDataSize; } + @JsonProperty + public DataSize getFailedProcessedInputDataSize() + { + return failedProcessedInputDataSize; + } + @JsonProperty public long getProcessedInputPositions() { return processedInputPositions; } + @JsonProperty + public long getFailedProcessedInputPositions() + { + return failedProcessedInputPositions; + } + @JsonProperty public DataSize getBufferedDataSize() { @@ -406,18 +528,36 @@ public DataSize getOutputDataSize() return outputDataSize; } + @JsonProperty + public DataSize getFailedOutputDataSize() + { + return failedOutputDataSize; + } + @JsonProperty public long getOutputPositions() { return outputPositions; } + @JsonProperty + public long getFailedOutputPositions() + { + return failedOutputPositions; + } + @JsonProperty public DataSize getPhysicalWrittenDataSize() { return physicalWrittenDataSize; } + @JsonProperty + public DataSize getFailedPhysicalWrittenDataSize() + { + return failedPhysicalWrittenDataSize; + } + @JsonProperty public StageGcStatistics getGcInfo() { @@ -453,10 +593,13 @@ public BasicStageStats toBasicStageStats(StageState stageState) rawInputDataSize, rawInputPositions, (long) cumulativeUserMemory, + (long) failedCumulativeUserMemory, userMemoryReservation, totalMemoryReservation, totalCpuTime, + failedCpuTime, totalScheduledTime, + failedScheduledTime, fullyBlocked, blockedReasons, progressPercentage); diff --git a/core/trino-main/src/main/java/io/trino/server/BasicQueryStats.java b/core/trino-main/src/main/java/io/trino/server/BasicQueryStats.java index 744ba652afe2..f234cf08b309 100644 --- a/core/trino-main/src/main/java/io/trino/server/BasicQueryStats.java +++ b/core/trino-main/src/main/java/io/trino/server/BasicQueryStats.java @@ -55,12 +55,15 @@ public class BasicQueryStats private final DataSize physicalInputDataSize; private final double cumulativeUserMemory; + private final double failedCumulativeUserMemory; private final DataSize userMemoryReservation; private final DataSize totalMemoryReservation; private final DataSize peakUserMemoryReservation; private final DataSize peakTotalMemoryReservation; private final Duration totalCpuTime; + private final Duration failedCpuTime; private final Duration totalScheduledTime; + private final Duration failedScheduledTime; private final boolean fullyBlocked; private final Set blockedReasons; @@ -82,12 +85,15 @@ public BasicQueryStats( @JsonProperty("rawInputPositions") long rawInputPositions, @JsonProperty("physicalInputDataSize") DataSize physicalInputDataSize, @JsonProperty("cumulativeUserMemory") double cumulativeUserMemory, + @JsonProperty("failedCumulativeUserMemory") double failedCumulativeUserMemory, @JsonProperty("userMemoryReservation") DataSize userMemoryReservation, @JsonProperty("totalMemoryReservation") DataSize totalMemoryReservation, @JsonProperty("peakUserMemoryReservation") DataSize peakUserMemoryReservation, @JsonProperty("peakTotalMemoryReservation") DataSize peakTotalMemoryReservation, @JsonProperty("totalCpuTime") Duration totalCpuTime, + @JsonProperty("failedCpuTime") Duration failedCpuTime, @JsonProperty("totalScheduledTime") Duration totalScheduledTime, + @JsonProperty("failedScheduledTime") Duration failedScheduledTime, @JsonProperty("fullyBlocked") boolean fullyBlocked, @JsonProperty("blockedReasons") Set blockedReasons, @JsonProperty("progressPercentage") OptionalDouble progressPercentage) @@ -113,12 +119,15 @@ public BasicQueryStats( this.physicalInputDataSize = physicalInputDataSize; this.cumulativeUserMemory = cumulativeUserMemory; + this.failedCumulativeUserMemory = failedCumulativeUserMemory; this.userMemoryReservation = userMemoryReservation; this.totalMemoryReservation = totalMemoryReservation; this.peakUserMemoryReservation = peakUserMemoryReservation; this.peakTotalMemoryReservation = peakTotalMemoryReservation; this.totalCpuTime = totalCpuTime; + this.failedCpuTime = failedCpuTime; this.totalScheduledTime = totalScheduledTime; + this.failedScheduledTime = failedScheduledTime; this.fullyBlocked = fullyBlocked; this.blockedReasons = ImmutableSet.copyOf(requireNonNull(blockedReasons, "blockedReasons is null")); @@ -141,12 +150,15 @@ public BasicQueryStats(QueryStats queryStats) queryStats.getRawInputPositions(), queryStats.getPhysicalInputDataSize(), queryStats.getCumulativeUserMemory(), + queryStats.getFailedCumulativeUserMemory(), queryStats.getUserMemoryReservation(), queryStats.getTotalMemoryReservation(), queryStats.getPeakUserMemoryReservation(), queryStats.getPeakTotalMemoryReservation(), queryStats.getTotalCpuTime(), + queryStats.getFailedCpuTime(), queryStats.getTotalScheduledTime(), + queryStats.getFailedScheduledTime(), queryStats.isFullyBlocked(), queryStats.getBlockedReasons(), queryStats.getProgressPercentage()); @@ -169,12 +181,15 @@ public static BasicQueryStats immediateFailureQueryStats() 0, DataSize.ofBytes(0), 0, + 0, DataSize.ofBytes(0), DataSize.ofBytes(0), DataSize.ofBytes(0), DataSize.ofBytes(0), new Duration(0, MILLISECONDS), new Duration(0, MILLISECONDS), + new Duration(0, MILLISECONDS), + new Duration(0, MILLISECONDS), false, ImmutableSet.of(), OptionalDouble.empty()); @@ -258,6 +273,12 @@ public double getCumulativeUserMemory() return cumulativeUserMemory; } + @JsonProperty + public double getFailedCumulativeUserMemory() + { + return failedCumulativeUserMemory; + } + @JsonProperty public DataSize getUserMemoryReservation() { @@ -288,12 +309,24 @@ public Duration getTotalCpuTime() return totalCpuTime; } + @JsonProperty + public Duration getFailedCpuTime() + { + return failedCpuTime; + } + @JsonProperty public Duration getTotalScheduledTime() { return totalScheduledTime; } + @JsonProperty + public Duration getFailedScheduledTime() + { + return failedScheduledTime; + } + @JsonProperty public boolean isFullyBlocked() { diff --git a/core/trino-main/src/main/resources/webapp/dist/query.js b/core/trino-main/src/main/resources/webapp/dist/query.js index 046421e4f171..d4985f921072 100644 --- a/core/trino-main/src/main/resources/webapp/dist/query.js +++ b/core/trino-main/src/main/resources/webapp/dist/query.js @@ -106,7 +106,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n}); /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.QueryDetail = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _react = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactable = __webpack_require__(/*! reactable */ \"./node_modules/reactable/lib/reactable.js\");\n\nvar _reactable2 = _interopRequireDefault(_reactable);\n\nvar _utils = __webpack_require__(/*! ../utils */ \"./utils.js\");\n\nvar _QueryHeader = __webpack_require__(/*! ./QueryHeader */ \"./components/QueryHeader.jsx\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar Table = _reactable2.default.Table,\n Thead = _reactable2.default.Thead,\n Th = _reactable2.default.Th,\n Tr = _reactable2.default.Tr,\n Td = _reactable2.default.Td;\n\nvar TaskList = function (_React$Component) {\n _inherits(TaskList, _React$Component);\n\n function TaskList() {\n _classCallCheck(this, TaskList);\n\n return _possibleConstructorReturn(this, (TaskList.__proto__ || Object.getPrototypeOf(TaskList)).apply(this, arguments));\n }\n\n _createClass(TaskList, [{\n key: \"render\",\n value: function render() {\n var tasks = this.props.tasks;\n\n if (tasks === undefined || tasks.length === 0) {\n return _react2.default.createElement(\n \"div\",\n { className: \"row error-message\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h4\",\n null,\n \"No threads in the selected group\"\n )\n )\n );\n }\n\n var showPortNumbers = TaskList.showPortNumbers(tasks);\n\n var renderedTasks = tasks.map(function (task) {\n var elapsedTime = (0, _utils.parseDuration)(task.stats.elapsedTime);\n if (elapsedTime === 0) {\n elapsedTime = Date.now() - Date.parse(task.stats.createTime);\n }\n\n return _react2.default.createElement(\n Tr,\n { key: task.taskStatus.taskId },\n _react2.default.createElement(\n Td,\n { column: \"id\", value: task.taskStatus.taskId },\n _react2.default.createElement(\n \"a\",\n { href: \"/ui/api/worker/\" + task.taskStatus.nodeId + \"/task/\" + task.taskStatus.taskId + \"?pretty\" },\n (0, _utils.getTaskIdSuffix)(task.taskStatus.taskId)\n )\n ),\n _react2.default.createElement(\n Td,\n { column: \"host\", value: (0, _utils.getHostname)(task.taskStatus.self) },\n _react2.default.createElement(\n \"a\",\n { href: \"worker.html?\" + task.taskStatus.nodeId, className: \"font-light\", target: \"_blank\" },\n showPortNumbers ? (0, _utils.getHostAndPort)(task.taskStatus.self) : (0, _utils.getHostname)(task.taskStatus.self)\n )\n ),\n _react2.default.createElement(\n Td,\n { column: \"state\", value: TaskList.formatState(task.taskStatus.state, task.stats.fullyBlocked) },\n TaskList.formatState(task.taskStatus.state, task.stats.fullyBlocked)\n ),\n _react2.default.createElement(\n Td,\n { column: \"rows\", value: task.stats.rawInputPositions },\n (0, _utils.formatCount)(task.stats.rawInputPositions)\n ),\n _react2.default.createElement(\n Td,\n { column: \"rowsSec\", value: (0, _utils.computeRate)(task.stats.rawInputPositions, elapsedTime) },\n (0, _utils.formatCount)((0, _utils.computeRate)(task.stats.rawInputPositions, elapsedTime))\n ),\n _react2.default.createElement(\n Td,\n { column: \"bytes\", value: (0, _utils.parseDataSize)(task.stats.rawInputDataSize) },\n (0, _utils.formatDataSizeBytes)((0, _utils.parseDataSize)(task.stats.rawInputDataSize))\n ),\n _react2.default.createElement(\n Td,\n { column: \"bytesSec\", value: (0, _utils.computeRate)((0, _utils.parseDataSize)(task.stats.rawInputDataSize), elapsedTime) },\n (0, _utils.formatDataSizeBytes)((0, _utils.computeRate)((0, _utils.parseDataSize)(task.stats.rawInputDataSize), elapsedTime))\n ),\n _react2.default.createElement(\n Td,\n { column: \"splitsPending\", value: task.stats.queuedDrivers },\n task.stats.queuedDrivers\n ),\n _react2.default.createElement(\n Td,\n { column: \"splitsRunning\", value: task.stats.runningDrivers },\n task.stats.runningDrivers\n ),\n _react2.default.createElement(\n Td,\n { column: \"splitsBlocked\", value: task.stats.blockedDrivers },\n task.stats.blockedDrivers\n ),\n _react2.default.createElement(\n Td,\n { column: \"splitsDone\", value: task.stats.completedDrivers },\n task.stats.completedDrivers\n ),\n _react2.default.createElement(\n Td,\n { column: \"elapsedTime\", value: (0, _utils.parseDuration)(task.stats.elapsedTime) },\n task.stats.elapsedTime\n ),\n _react2.default.createElement(\n Td,\n { column: \"cpuTime\", value: (0, _utils.parseDuration)(task.stats.totalCpuTime) },\n task.stats.totalCpuTime\n ),\n _react2.default.createElement(\n Td,\n { column: \"bufferedBytes\", value: task.outputBuffers.totalBufferedBytes },\n (0, _utils.formatDataSizeBytes)(task.outputBuffers.totalBufferedBytes)\n )\n );\n });\n\n return _react2.default.createElement(\n Table,\n { id: \"tasks\", className: \"table table-striped sortable\", sortable: [{\n column: 'id',\n sortFunction: TaskList.compareTaskId\n }, 'host', 'state', 'splitsPending', 'splitsRunning', 'splitsBlocked', 'splitsDone', 'rows', 'rowsSec', 'bytes', 'bytesSec', 'elapsedTime', 'cpuTime', 'bufferedBytes'],\n defaultSort: { column: 'id', direction: 'asc' } },\n _react2.default.createElement(\n Thead,\n null,\n _react2.default.createElement(\n Th,\n { column: \"id\" },\n \"ID\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"host\" },\n \"Host\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"state\" },\n \"State\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"splitsPending\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-pause\", style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\",\n title: \"Pending splits\" })\n ),\n _react2.default.createElement(\n Th,\n { column: \"splitsRunning\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-play\", style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\",\n title: \"Running splits\" })\n ),\n _react2.default.createElement(\n Th,\n { column: \"splitsBlocked\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-bookmark\", style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\",\n title: \"Blocked splits\" })\n ),\n _react2.default.createElement(\n Th,\n { column: \"splitsDone\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-ok\", style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\",\n title: \"Completed splits\" })\n ),\n _react2.default.createElement(\n Th,\n { column: \"rows\" },\n \"Rows\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"rowsSec\" },\n \"Rows/s\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"bytes\" },\n \"Bytes\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"bytesSec\" },\n \"Bytes/s\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"elapsedTime\" },\n \"Elapsed\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"cpuTime\" },\n \"CPU Time\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"bufferedBytes\" },\n \"Buffered\"\n )\n ),\n renderedTasks\n );\n }\n }], [{\n key: \"removeQueryId\",\n value: function removeQueryId(id) {\n var pos = id.indexOf('.');\n if (pos !== -1) {\n return id.substring(pos + 1);\n }\n return id;\n }\n }, {\n key: \"compareTaskId\",\n value: function compareTaskId(taskA, taskB) {\n var taskIdArrA = TaskList.removeQueryId(taskA).split(\".\");\n var taskIdArrB = TaskList.removeQueryId(taskB).split(\".\");\n\n if (taskIdArrA.length > taskIdArrB.length) {\n return 1;\n }\n for (var i = 0; i < taskIdArrA.length; i++) {\n var anum = Number.parseInt(taskIdArrA[i]);\n var bnum = Number.parseInt(taskIdArrB[i]);\n if (anum !== bnum) {\n return anum > bnum ? 1 : -1;\n }\n }\n\n return 0;\n }\n }, {\n key: \"showPortNumbers\",\n value: function showPortNumbers(tasks) {\n // check if any host has multiple port numbers\n var hostToPortNumber = {};\n for (var i = 0; i < tasks.length; i++) {\n var taskUri = tasks[i].taskStatus.self;\n var hostname = (0, _utils.getHostname)(taskUri);\n var port = (0, _utils.getPort)(taskUri);\n if (hostname in hostToPortNumber && hostToPortNumber[hostname] !== port) {\n return true;\n }\n hostToPortNumber[hostname] = port;\n }\n\n return false;\n }\n }, {\n key: \"formatState\",\n value: function formatState(state, fullyBlocked) {\n if (fullyBlocked && state === \"RUNNING\") {\n return \"BLOCKED\";\n } else {\n return state;\n }\n }\n }]);\n\n return TaskList;\n}(_react2.default.Component);\n\nvar BAR_CHART_WIDTH = 800;\n\nvar BAR_CHART_PROPERTIES = {\n type: 'bar',\n barSpacing: '0',\n height: '80px',\n barColor: '#747F96',\n zeroColor: '#8997B3',\n chartRangeMin: 0,\n tooltipClassname: 'sparkline-tooltip',\n tooltipFormat: 'Task {{offset:offset}} - {{value}}',\n disableHiddenCheck: true\n};\n\nvar HISTOGRAM_WIDTH = 175;\n\nvar HISTOGRAM_PROPERTIES = {\n type: 'bar',\n barSpacing: '0',\n height: '80px',\n barColor: '#747F96',\n zeroColor: '#747F96',\n zeroAxis: true,\n chartRangeMin: 0,\n tooltipClassname: 'sparkline-tooltip',\n tooltipFormat: '{{offset:offset}} -- {{value}} tasks',\n disableHiddenCheck: true\n};\n\nvar StageSummary = function (_React$Component2) {\n _inherits(StageSummary, _React$Component2);\n\n function StageSummary(props) {\n _classCallCheck(this, StageSummary);\n\n var _this2 = _possibleConstructorReturn(this, (StageSummary.__proto__ || Object.getPrototypeOf(StageSummary)).call(this, props));\n\n _this2.state = {\n expanded: false,\n lastRender: null\n };\n return _this2;\n }\n\n _createClass(StageSummary, [{\n key: \"getExpandedIcon\",\n value: function getExpandedIcon() {\n return this.state.expanded ? \"glyphicon-chevron-up\" : \"glyphicon-chevron-down\";\n }\n }, {\n key: \"getExpandedStyle\",\n value: function getExpandedStyle() {\n return this.state.expanded ? {} : { display: \"none\" };\n }\n }, {\n key: \"toggleExpanded\",\n value: function toggleExpanded() {\n this.setState({\n expanded: !this.state.expanded\n });\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n var stage = this.props.stage;\n var numTasks = stage.tasks.length;\n\n // sort the x-axis\n stage.tasks.sort(function (taskA, taskB) {\n return (0, _utils.getTaskNumber)(taskA.taskStatus.taskId) - (0, _utils.getTaskNumber)(taskB.taskStatus.taskId);\n });\n\n var scheduledTimes = stage.tasks.map(function (task) {\n return (0, _utils.parseDuration)(task.stats.totalScheduledTime);\n });\n var cpuTimes = stage.tasks.map(function (task) {\n return (0, _utils.parseDuration)(task.stats.totalCpuTime);\n });\n\n // prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts\n if (this.state.lastRender === null || Date.now() - this.state.lastRender >= 1000) {\n var renderTimestamp = Date.now();\n var stageId = (0, _utils.getStageNumber)(stage.stageId);\n\n StageSummary.renderHistogram('#scheduled-time-histogram-' + stageId, scheduledTimes, _utils.formatDuration);\n StageSummary.renderHistogram('#cpu-time-histogram-' + stageId, cpuTimes, _utils.formatDuration);\n\n if (this.state.expanded) {\n // this needs to be a string otherwise it will also be passed to numberFormatter\n var tooltipValueLookups = { 'offset': {} };\n for (var i = 0; i < numTasks; i++) {\n tooltipValueLookups['offset'][i] = (0, _utils.getStageNumber)(stage.stageId) + \".\" + i;\n }\n\n var stageBarChartProperties = $.extend({}, BAR_CHART_PROPERTIES, { barWidth: BAR_CHART_WIDTH / numTasks, tooltipValueLookups: tooltipValueLookups });\n\n $('#scheduled-time-bar-chart-' + stageId).sparkline(scheduledTimes, $.extend({}, stageBarChartProperties, { numberFormatter: _utils.formatDuration }));\n $('#cpu-time-bar-chart-' + stageId).sparkline(cpuTimes, $.extend({}, stageBarChartProperties, { numberFormatter: _utils.formatDuration }));\n }\n\n this.setState({\n lastRender: renderTimestamp\n });\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var stage = this.props.stage;\n if (stage === undefined || !stage.hasOwnProperty('plan')) {\n return _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n \"Information about this stage is unavailable.\"\n )\n );\n }\n\n var totalBufferedBytes = stage.tasks.map(function (task) {\n return task.outputBuffers.totalBufferedBytes;\n }).reduce(function (a, b) {\n return a + b;\n }, 0);\n\n var stageId = (0, _utils.getStageNumber)(stage.stageId);\n\n return _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-id\" },\n _react2.default.createElement(\n \"div\",\n { className: \"stage-state-color\", style: { borderLeftColor: (0, _utils.getStageStateColor)(stage) } },\n stageId\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"table single-stage-table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table stage-table-time\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-stat-header\" },\n \"Time\"\n ),\n _react2.default.createElement(\"th\", null)\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Scheduled\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.stageStats.totalScheduledTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Blocked\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.stageStats.totalBlockedTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"CPU\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.stageStats.totalCpuTime\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table stage-table-memory\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-stat-header\" },\n \"Memory\"\n ),\n _react2.default.createElement(\"th\", null)\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Cumulative\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n (0, _utils.formatDataSizeBytes)(stage.stageStats.cumulativeUserMemory / 1000)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Current\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n (0, _utils.parseAndFormatDataSize)(stage.stageStats.userMemoryReservation)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Buffers\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n (0, _utils.formatDataSize)(totalBufferedBytes)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Peak\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n (0, _utils.parseAndFormatDataSize)(stage.stageStats.peakUserMemoryReservation)\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table stage-table-tasks\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-stat-header\" },\n \"Tasks\"\n ),\n _react2.default.createElement(\"th\", null)\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Pending\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.tasks.filter(function (task) {\n return task.taskStatus.state === \"PLANNED\";\n }).length\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Running\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.tasks.filter(function (task) {\n return task.taskStatus.state === \"RUNNING\";\n }).length\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Blocked\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.tasks.filter(function (task) {\n return task.stats.fullyBlocked;\n }).length\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Total\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.tasks.length\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table histogram-table\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-chart-header\" },\n \"Scheduled Time Skew\"\n )\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"histogram-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"histogram\", id: \"scheduled-time-histogram-\" + stageId },\n _react2.default.createElement(\"div\", { className: \"loader\" })\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table histogram-table\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-chart-header\" },\n \"CPU Time Skew\"\n )\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"histogram-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"histogram\", id: \"cpu-time-histogram-\" + stageId },\n _react2.default.createElement(\"div\", { className: \"loader\" })\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"expand-charts-container\" },\n _react2.default.createElement(\n \"a\",\n { onClick: this.toggleExpanded.bind(this), className: \"expand-charts-button\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon \" + this.getExpandedIcon(), style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\", title: \"More\" })\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { style: this.getExpandedStyle() },\n _react2.default.createElement(\n \"td\",\n { colSpan: \"6\" },\n _react2.default.createElement(\n \"table\",\n { className: \"expanded-chart\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title expanded-chart-title\" },\n \"Task Scheduled Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"bar-chart-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"bar-chart\", id: \"scheduled-time-bar-chart-\" + stageId },\n _react2.default.createElement(\"div\", { className: \"loader\" })\n )\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { style: this.getExpandedStyle() },\n _react2.default.createElement(\n \"td\",\n { colSpan: \"6\" },\n _react2.default.createElement(\n \"table\",\n { className: \"expanded-chart\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title expanded-chart-title\" },\n \"Task CPU Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"bar-chart-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"bar-chart\", id: \"cpu-time-bar-chart-\" + stageId },\n _react2.default.createElement(\"div\", { className: \"loader\" })\n )\n )\n )\n )\n )\n )\n )\n )\n )\n )\n );\n }\n }], [{\n key: \"renderHistogram\",\n value: function renderHistogram(histogramId, inputData, numberFormatter) {\n var numBuckets = Math.min(HISTOGRAM_WIDTH, Math.sqrt(inputData.length));\n var dataMin = Math.min.apply(null, inputData);\n var dataMax = Math.max.apply(null, inputData);\n var bucketSize = (dataMax - dataMin) / numBuckets;\n\n var histogramData = [];\n if (bucketSize === 0) {\n histogramData = [inputData.length];\n } else {\n for (var i = 0; i < numBuckets + 1; i++) {\n histogramData.push(0);\n }\n\n for (var _i in inputData) {\n var dataPoint = inputData[_i];\n var bucket = Math.floor((dataPoint - dataMin) / bucketSize);\n histogramData[bucket] = histogramData[bucket] + 1;\n }\n }\n\n var tooltipValueLookups = { 'offset': {} };\n for (var _i2 = 0; _i2 < histogramData.length; _i2++) {\n tooltipValueLookups['offset'][_i2] = numberFormatter(dataMin + _i2 * bucketSize) + \"-\" + numberFormatter(dataMin + (_i2 + 1) * bucketSize);\n }\n\n var stageHistogramProperties = $.extend({}, HISTOGRAM_PROPERTIES, { barWidth: HISTOGRAM_WIDTH / histogramData.length, tooltipValueLookups: tooltipValueLookups });\n $(histogramId).sparkline(histogramData, stageHistogramProperties);\n }\n }]);\n\n return StageSummary;\n}(_react2.default.Component);\n\nvar StageList = function (_React$Component3) {\n _inherits(StageList, _React$Component3);\n\n function StageList() {\n _classCallCheck(this, StageList);\n\n return _possibleConstructorReturn(this, (StageList.__proto__ || Object.getPrototypeOf(StageList)).apply(this, arguments));\n }\n\n _createClass(StageList, [{\n key: \"getStages\",\n value: function getStages(stage) {\n if (stage === undefined || !stage.hasOwnProperty('subStages')) {\n return [];\n }\n\n return [].concat.apply(stage, stage.subStages.map(this.getStages, this));\n }\n }, {\n key: \"render\",\n value: function render() {\n var stages = this.getStages(this.props.outputStage);\n\n if (stages === undefined || stages.length === 0) {\n return _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n \"No stage information available.\"\n )\n );\n }\n\n var renderedStages = stages.map(function (stage) {\n return _react2.default.createElement(StageSummary, { key: stage.stageId, stage: stage });\n });\n\n return _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"table\",\n { className: \"table\", id: \"stage-list\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n renderedStages\n )\n )\n )\n );\n }\n }]);\n\n return StageList;\n}(_react2.default.Component);\n\nvar SMALL_SPARKLINE_PROPERTIES = {\n width: '100%',\n height: '57px',\n fillColor: '#3F4552',\n lineColor: '#747F96',\n spotColor: '#1EDCFF',\n tooltipClassname: 'sparkline-tooltip',\n disableHiddenCheck: true\n};\n\nvar TASK_FILTER = {\n ALL: function ALL() {\n return true;\n },\n PLANNED: function PLANNED(state) {\n return state === 'PLANNED';\n },\n RUNNING: function RUNNING(state) {\n return state === 'RUNNING';\n },\n FINISHED: function FINISHED(state) {\n return state === 'FINISHED';\n },\n FAILED: function FAILED(state) {\n return state === 'FAILED' || state === 'ABORTED' || state === 'CANCELED';\n }\n};\n\nvar QueryDetail = exports.QueryDetail = function (_React$Component4) {\n _inherits(QueryDetail, _React$Component4);\n\n function QueryDetail(props) {\n _classCallCheck(this, QueryDetail);\n\n var _this4 = _possibleConstructorReturn(this, (QueryDetail.__proto__ || Object.getPrototypeOf(QueryDetail)).call(this, props));\n\n _this4.state = {\n query: null,\n lastSnapshotStages: null,\n lastSnapshotTasks: null,\n\n lastScheduledTime: 0,\n lastCpuTime: 0,\n lastRowInput: 0,\n lastByteInput: 0,\n lastPhysicalInput: 0,\n lastPhysicalTime: 0,\n\n scheduledTimeRate: [],\n cpuTimeRate: [],\n rowInputRate: [],\n byteInputRate: [],\n physicalInputRate: [],\n\n reservedMemory: [],\n\n initialized: false,\n queryEnded: false,\n renderingEnded: false,\n\n lastRefresh: null,\n lastRender: null,\n\n stageRefresh: true,\n taskRefresh: true,\n\n taskFilter: TASK_FILTER.ALL\n };\n\n _this4.refreshLoop = _this4.refreshLoop.bind(_this4);\n return _this4;\n }\n\n _createClass(QueryDetail, [{\n key: \"resetTimer\",\n value: function resetTimer() {\n clearTimeout(this.timeoutId);\n // stop refreshing when query finishes or fails\n if (this.state.query === null || !this.state.queryEnded) {\n // task.info-update-interval is set to 3 seconds by default\n this.timeoutId = setTimeout(this.refreshLoop, 3000);\n }\n }\n }, {\n key: \"refreshLoop\",\n value: function refreshLoop() {\n var _this5 = this;\n\n clearTimeout(this.timeoutId); // to stop multiple series of refreshLoop from going on simultaneously\n var queryId = (0, _utils.getFirstParameter)(window.location.search);\n $.get('/ui/api/query/' + queryId, function (query) {\n var lastSnapshotStages = this.state.lastSnapshotStage;\n if (this.state.stageRefresh) {\n lastSnapshotStages = query.outputStage;\n }\n var lastSnapshotTasks = this.state.lastSnapshotTasks;\n if (this.state.taskRefresh) {\n lastSnapshotTasks = query.outputStage;\n }\n\n var lastRefresh = this.state.lastRefresh;\n var lastScheduledTime = this.state.lastScheduledTime;\n var lastCpuTime = this.state.lastCpuTime;\n var lastRowInput = this.state.lastRowInput;\n var lastByteInput = this.state.lastByteInput;\n var lastPhysicalInput = this.state.lastPhysicalInput;\n var lastPhysicalTime = this.state.lastPhysicalTime;\n var alreadyEnded = this.state.queryEnded;\n var nowMillis = Date.now();\n\n this.setState({\n query: query,\n lastSnapshotStage: lastSnapshotStages,\n lastSnapshotTasks: lastSnapshotTasks,\n\n lastPhysicalTime: (0, _utils.parseDuration)(query.queryStats.physicalInputReadTime),\n lastScheduledTime: (0, _utils.parseDuration)(query.queryStats.totalScheduledTime),\n lastCpuTime: (0, _utils.parseDuration)(query.queryStats.totalCpuTime),\n lastRowInput: query.queryStats.processedInputPositions,\n lastByteInput: (0, _utils.parseDataSize)(query.queryStats.processedInputDataSize),\n lastPhysicalInput: (0, _utils.parseDataSize)(query.queryStats.physicalInputDataSize),\n\n initialized: true,\n queryEnded: !!query.finalQueryInfo,\n\n lastRefresh: nowMillis\n });\n\n // i.e. don't show sparklines if we've already decided not to update or if we don't have one previous measurement\n if (alreadyEnded || lastRefresh === null && query.state === \"RUNNING\") {\n this.resetTimer();\n return;\n }\n\n if (lastRefresh === null) {\n lastRefresh = nowMillis - (0, _utils.parseDuration)(query.queryStats.elapsedTime);\n }\n\n var elapsedSecsSinceLastRefresh = (nowMillis - lastRefresh) / 1000.0;\n if (elapsedSecsSinceLastRefresh >= 0) {\n var currentScheduledTimeRate = ((0, _utils.parseDuration)(query.queryStats.totalScheduledTime) - lastScheduledTime) / (elapsedSecsSinceLastRefresh * 1000);\n var currentCpuTimeRate = ((0, _utils.parseDuration)(query.queryStats.totalCpuTime) - lastCpuTime) / (elapsedSecsSinceLastRefresh * 1000);\n var currentPhysicalReadTime = ((0, _utils.parseDuration)(query.queryStats.physicalInputReadTime) - lastPhysicalTime) / 1000;\n var currentRowInputRate = (query.queryStats.processedInputPositions - lastRowInput) / elapsedSecsSinceLastRefresh;\n var currentByteInputRate = ((0, _utils.parseDataSize)(query.queryStats.processedInputDataSize) - lastByteInput) / elapsedSecsSinceLastRefresh;\n var currentPhysicalInputRate = currentPhysicalReadTime > 0 ? ((0, _utils.parseDataSize)(query.queryStats.physicalInputDataSize) - lastPhysicalInput) / currentPhysicalReadTime : 0;\n\n this.setState({\n scheduledTimeRate: (0, _utils.addToHistory)(currentScheduledTimeRate, this.state.scheduledTimeRate),\n cpuTimeRate: (0, _utils.addToHistory)(currentCpuTimeRate, this.state.cpuTimeRate),\n rowInputRate: (0, _utils.addToHistory)(currentRowInputRate, this.state.rowInputRate),\n byteInputRate: (0, _utils.addToHistory)(currentByteInputRate, this.state.byteInputRate),\n reservedMemory: (0, _utils.addToHistory)((0, _utils.parseDataSize)(query.queryStats.totalMemoryReservation), this.state.reservedMemory),\n physicalInputRate: (0, _utils.addToHistory)(currentPhysicalInputRate, this.state.physicalInputRate)\n });\n }\n this.resetTimer();\n }.bind(this)).fail(function () {\n _this5.setState({\n initialized: true\n });\n _this5.resetTimer();\n });\n }\n }, {\n key: \"handleTaskRefreshClick\",\n value: function handleTaskRefreshClick() {\n if (this.state.taskRefresh) {\n this.setState({\n taskRefresh: false,\n lastSnapshotTasks: this.state.query.outputStage\n });\n } else {\n this.setState({\n taskRefresh: true\n });\n }\n }\n }, {\n key: \"renderTaskRefreshButton\",\n value: function renderTaskRefreshButton() {\n if (this.state.taskRefresh) {\n return _react2.default.createElement(\n \"button\",\n { className: \"btn btn-info live-button\", onClick: this.handleTaskRefreshClick.bind(this) },\n \"Auto-Refresh: On\"\n );\n } else {\n return _react2.default.createElement(\n \"button\",\n { className: \"btn btn-info live-button\", onClick: this.handleTaskRefreshClick.bind(this) },\n \"Auto-Refresh: Off\"\n );\n }\n }\n }, {\n key: \"handleStageRefreshClick\",\n value: function handleStageRefreshClick() {\n if (this.state.stageRefresh) {\n this.setState({\n stageRefresh: false,\n lastSnapshotStages: this.state.query.outputStage\n });\n } else {\n this.setState({\n stageRefresh: true\n });\n }\n }\n }, {\n key: \"renderStageRefreshButton\",\n value: function renderStageRefreshButton() {\n if (this.state.stageRefresh) {\n return _react2.default.createElement(\n \"button\",\n { className: \"btn btn-info live-button\", onClick: this.handleStageRefreshClick.bind(this) },\n \"Auto-Refresh: On\"\n );\n } else {\n return _react2.default.createElement(\n \"button\",\n { className: \"btn btn-info live-button\", onClick: this.handleStageRefreshClick.bind(this) },\n \"Auto-Refresh: Off\"\n );\n }\n }\n }, {\n key: \"renderTaskFilterListItem\",\n value: function renderTaskFilterListItem(taskFilter, taskFilterText) {\n return _react2.default.createElement(\n \"li\",\n null,\n _react2.default.createElement(\n \"a\",\n { href: \"#\", className: this.state.taskFilter === taskFilter ? \"selected\" : \"\", onClick: this.handleTaskFilterClick.bind(this, taskFilter) },\n taskFilterText\n )\n );\n }\n }, {\n key: \"handleTaskFilterClick\",\n value: function handleTaskFilterClick(filter, event) {\n this.setState({\n taskFilter: filter\n });\n event.preventDefault();\n }\n }, {\n key: \"getTasksFromStage\",\n value: function getTasksFromStage(stage) {\n if (stage === undefined || !stage.hasOwnProperty('subStages') || !stage.hasOwnProperty('tasks')) {\n return [];\n }\n\n return [].concat.apply(stage.tasks, stage.subStages.map(this.getTasksFromStage, this));\n }\n }, {\n key: \"componentDidMount\",\n value: function componentDidMount() {\n this.refreshLoop();\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n // prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts\n if (this.state.lastRender === null || Date.now() - this.state.lastRender >= 1000 || this.state.ended && !this.state.renderingEnded) {\n var renderTimestamp = Date.now();\n $('#scheduled-time-rate-sparkline').sparkline(this.state.scheduledTimeRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {\n chartRangeMin: 0,\n numberFormatter: _utils.precisionRound\n }));\n $('#cpu-time-rate-sparkline').sparkline(this.state.cpuTimeRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { chartRangeMin: 0, numberFormatter: _utils.precisionRound }));\n $('#row-input-rate-sparkline').sparkline(this.state.rowInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { numberFormatter: _utils.formatCount }));\n $('#byte-input-rate-sparkline').sparkline(this.state.byteInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { numberFormatter: _utils.formatDataSize }));\n $('#reserved-memory-sparkline').sparkline(this.state.reservedMemory, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { numberFormatter: _utils.formatDataSize }));\n $('#physical-input-rate-sparkline').sparkline(this.state.physicalInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { numberFormatter: _utils.formatDataSize }));\n\n if (this.state.lastRender === null) {\n $('#query').each(function (i, block) {\n hljs.highlightBlock(block);\n });\n\n $('#prepared-query').each(function (i, block) {\n hljs.highlightBlock(block);\n });\n }\n\n this.setState({\n renderingEnded: this.state.ended,\n lastRender: renderTimestamp\n });\n }\n\n $('[data-toggle=\"tooltip\"]').tooltip();\n new window.ClipboardJS('.copy-button');\n }\n }, {\n key: \"renderTasks\",\n value: function renderTasks() {\n var _this6 = this;\n\n if (this.state.lastSnapshotTasks === null) {\n return;\n }\n\n var tasks = this.getTasksFromStage(this.state.lastSnapshotTasks).filter(function (task) {\n return _this6.state.taskFilter(task.taskStatus.state);\n }, this);\n\n return _react2.default.createElement(\n \"div\",\n null,\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-9\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Tasks\"\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-3\" },\n _react2.default.createElement(\n \"table\",\n { className: \"header-inline-links\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"div\",\n { className: \"input-group-btn text-right\" },\n _react2.default.createElement(\n \"button\",\n { type: \"button\", className: \"btn btn-default dropdown-toggle pull-right text-right\", \"data-toggle\": \"dropdown\", \"aria-haspopup\": \"true\",\n \"aria-expanded\": \"false\" },\n \"Show \",\n _react2.default.createElement(\"span\", { className: \"caret\" })\n ),\n _react2.default.createElement(\n \"ul\",\n { className: \"dropdown-menu\" },\n this.renderTaskFilterListItem(TASK_FILTER.ALL, \"All\"),\n this.renderTaskFilterListItem(TASK_FILTER.PLANNED, \"Planned\"),\n this.renderTaskFilterListItem(TASK_FILTER.RUNNING, \"Running\"),\n this.renderTaskFilterListItem(TASK_FILTER.FINISHED, \"Finished\"),\n this.renderTaskFilterListItem(TASK_FILTER.FAILED, \"Aborted/Canceled/Failed\")\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n \"\\xA0\\xA0\",\n this.renderTaskRefreshButton()\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(TaskList, { key: this.state.query.queryId, tasks: tasks })\n )\n )\n );\n }\n }, {\n key: \"renderStages\",\n value: function renderStages() {\n if (this.state.lastSnapshotStage === null) {\n return;\n }\n\n return _react2.default.createElement(\n \"div\",\n null,\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-9\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Stages\"\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-3\" },\n _react2.default.createElement(\n \"table\",\n { className: \"header-inline-links\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n this.renderStageRefreshButton()\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(StageList, { key: this.state.query.queryId, outputStage: this.state.lastSnapshotStage })\n )\n )\n );\n }\n }, {\n key: \"renderPreparedQuery\",\n value: function renderPreparedQuery() {\n var query = this.state.query;\n if (!query.hasOwnProperty('preparedQuery') || query.preparedQuery === null) {\n return;\n }\n\n return _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Prepared Query\",\n _react2.default.createElement(\n \"a\",\n { className: \"btn copy-button\", \"data-clipboard-target\": \"#prepared-query-text\", \"data-toggle\": \"tooltip\", \"data-placement\": \"right\", title: \"Copy to clipboard\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-copy\", \"aria-hidden\": \"true\", alt: \"Copy to clipboard\" })\n )\n ),\n _react2.default.createElement(\n \"pre\",\n { id: \"prepared-query\" },\n _react2.default.createElement(\n \"code\",\n { className: \"lang-sql\", id: \"prepared-query-text\" },\n query.preparedQuery\n )\n )\n );\n }\n }, {\n key: \"renderSessionProperties\",\n value: function renderSessionProperties() {\n var query = this.state.query;\n\n var properties = [];\n for (var property in query.session.systemProperties) {\n if (query.session.systemProperties.hasOwnProperty(property)) {\n properties.push(_react2.default.createElement(\n \"span\",\n null,\n \"- \",\n property + \"=\" + query.session.systemProperties[property],\n \" \",\n _react2.default.createElement(\"br\", null)\n ));\n }\n }\n\n for (var catalog in query.session.catalogProperties) {\n if (query.session.catalogProperties.hasOwnProperty(catalog)) {\n for (var _property in query.session.catalogProperties[catalog]) {\n if (query.session.catalogProperties[catalog].hasOwnProperty(_property)) {\n properties.push(_react2.default.createElement(\n \"span\",\n null,\n \"- \",\n catalog + \".\" + _property + \"=\" + query.session.catalogProperties[catalog][_property],\n \" \",\n _react2.default.createElement(\"br\", null)\n ));\n }\n }\n }\n }\n\n return properties;\n }\n }, {\n key: \"renderResourceEstimates\",\n value: function renderResourceEstimates() {\n var query = this.state.query;\n var estimates = query.session.resourceEstimates;\n var renderedEstimates = [];\n\n for (var resource in estimates) {\n if (estimates.hasOwnProperty(resource)) {\n var upperChars = resource.match(/([A-Z])/g) || [];\n var snakeCased = resource;\n for (var i = 0, n = upperChars.length; i < n; i++) {\n snakeCased = snakeCased.replace(new RegExp(upperChars[i]), '_' + upperChars[i].toLowerCase());\n }\n\n renderedEstimates.push(_react2.default.createElement(\n \"span\",\n null,\n \"- \",\n snakeCased + \"=\" + query.session.resourceEstimates[resource],\n \" \",\n _react2.default.createElement(\"br\", null)\n ));\n }\n }\n\n return renderedEstimates;\n }\n }, {\n key: \"renderWarningInfo\",\n value: function renderWarningInfo() {\n var query = this.state.query;\n if (query.warnings.length > 0) {\n return _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Warnings\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\", id: \"warnings-table\" },\n query.warnings.map(function (warning) {\n return _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n warning.warningCode.name\n ),\n _react2.default.createElement(\n \"td\",\n null,\n warning.message\n )\n );\n })\n )\n )\n );\n } else {\n return null;\n }\n }\n }, {\n key: \"renderFailureInfo\",\n value: function renderFailureInfo() {\n var query = this.state.query;\n if (query.failureInfo) {\n return _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Error Information\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Error Type\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.errorType\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Error Code\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.errorCode.name + \" (\" + this.state.query.errorCode.code + \")\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Stack Trace\",\n _react2.default.createElement(\n \"a\",\n { className: \"btn copy-button\", \"data-clipboard-target\": \"#stack-trace\", \"data-toggle\": \"tooltip\", \"data-placement\": \"right\", title: \"Copy to clipboard\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-copy\", \"aria-hidden\": \"true\", alt: \"Copy to clipboard\" })\n )\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n _react2.default.createElement(\n \"pre\",\n { id: \"stack-trace\" },\n QueryDetail.formatStackTrace(query.failureInfo)\n )\n )\n )\n )\n )\n )\n );\n } else {\n return \"\";\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var query = this.state.query;\n\n if (query === null || this.state.initialized === false) {\n var label = _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading...\"\n );\n if (this.state.initialized) {\n label = \"Query not found\";\n }\n return _react2.default.createElement(\n \"div\",\n { className: \"row error-message\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h4\",\n null,\n label\n )\n )\n );\n }\n\n return _react2.default.createElement(\n \"div\",\n null,\n _react2.default.createElement(_QueryHeader.QueryHeader, { query: query }),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-6\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Session\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"User\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n _react2.default.createElement(\n \"span\",\n { id: \"query-user\" },\n query.session.user\n ),\n \"\\xA0\\xA0\",\n _react2.default.createElement(\n \"a\",\n { href: \"#\", className: \"copy-button\", \"data-clipboard-target\": \"#query-user\", \"data-toggle\": \"tooltip\", \"data-placement\": \"right\", title: \"Copy to clipboard\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-copy\", \"aria-hidden\": \"true\", alt: \"Copy to clipboard\" })\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Principal\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n query.session.principal\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Source\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n query.session.source\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Catalog\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.catalog\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Schema\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.schema\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Time zone\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.timeZone\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Client Address\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.remoteUserAddress\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Client Tags\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.clientTags.join(\", \")\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Session Properties\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n this.renderSessionProperties()\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Resource Estimates\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n this.renderResourceEstimates()\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-6\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Execution\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Resource Group\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n query.resourceGroupId ? query.resourceGroupId.join(\".\") : \"n/a\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Submission Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatShortDateTime)(new Date(query.queryStats.createTime))\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Completion Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.endTime ? (0, _utils.formatShortDateTime)(new Date(query.queryStats.endTime)) : \"\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Elapsed Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.elapsedTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Queued Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.queuedTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Analysis Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.analysisTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Planning Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.planningTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Execution Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.executionTime\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-6\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Resource Utilization Summary\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"CPU Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.totalCpuTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Scheduled Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.totalScheduledTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Input Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.processedInputPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Input Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.processedInputDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Input Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.physicalInputPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Input Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.physicalInputDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Input Read Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.physicalInputReadTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Internal Network Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.internalNetworkInputPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Internal Network Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.internalNetworkInputDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Peak User Memory\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.peakUserMemoryReservation)\n )\n ),\n (0, _utils.parseDataSize)(query.queryStats.peakRevocableMemoryReservation) > 0 && _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Peak Revocable Memory\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.peakRevocableMemoryReservation)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Peak Total Memory\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.peakTotalMemoryReservation)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Cumulative User Memory\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatDataSizeBytes)(query.queryStats.cumulativeUserMemory / 1000.0) + \" seconds\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Output Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.outputPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Output Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.outputDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Written Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.writtenPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Logical Written Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.logicalWrittenDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Written Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.physicalWrittenDataSize)\n )\n ),\n (0, _utils.parseDataSize)(query.queryStats.spilledDataSize) > 0 && _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Spilled Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.spilledDataSize)\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-6\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Timeline\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Parallelism\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"cpu-time-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatCount)(this.state.cpuTimeRate[this.state.cpuTimeRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Scheduled Time/s\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"scheduled-time-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatCount)(this.state.scheduledTimeRate[this.state.scheduledTimeRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Input Rows/s\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"row-input-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatCount)(this.state.rowInputRate[this.state.rowInputRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Input Bytes/s\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"byte-input-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatDataSize)(this.state.byteInputRate[this.state.byteInputRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Input Bytes/s\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"physical-input-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatDataSize)(this.state.physicalInputRate[this.state.physicalInputRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Memory Utilization\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"reserved-memory-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatDataSize)(this.state.reservedMemory[this.state.reservedMemory.length - 1])\n )\n )\n )\n )\n )\n )\n )\n ),\n this.renderWarningInfo(),\n this.renderFailureInfo(),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Query\",\n _react2.default.createElement(\n \"a\",\n { className: \"btn copy-button\", \"data-clipboard-target\": \"#query-text\", \"data-toggle\": \"tooltip\", \"data-placement\": \"right\", title: \"Copy to clipboard\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-copy\", \"aria-hidden\": \"true\", alt: \"Copy to clipboard\" })\n )\n ),\n _react2.default.createElement(\n \"pre\",\n { id: \"query\" },\n _react2.default.createElement(\n \"code\",\n { className: \"lang-sql\", id: \"query-text\" },\n query.query\n )\n )\n ),\n this.renderPreparedQuery()\n ),\n this.renderStages(),\n this.renderTasks()\n );\n }\n }], [{\n key: \"formatStackTrace\",\n value: function formatStackTrace(info) {\n return QueryDetail.formatStackTraceHelper(info, [], \"\", \"\");\n }\n }, {\n key: \"formatStackTraceHelper\",\n value: function formatStackTraceHelper(info, parentStack, prefix, linePrefix) {\n var s = linePrefix + prefix + QueryDetail.failureInfoToString(info) + \"\\n\";\n\n if (info.stack) {\n var sharedStackFrames = 0;\n if (parentStack !== null) {\n sharedStackFrames = QueryDetail.countSharedStackFrames(info.stack, parentStack);\n }\n\n for (var i = 0; i < info.stack.length - sharedStackFrames; i++) {\n s += linePrefix + \"\\tat \" + info.stack[i] + \"\\n\";\n }\n if (sharedStackFrames !== 0) {\n s += linePrefix + \"\\t... \" + sharedStackFrames + \" more\" + \"\\n\";\n }\n }\n\n if (info.suppressed) {\n for (var _i3 = 0; _i3 < info.suppressed.length; _i3++) {\n s += QueryDetail.formatStackTraceHelper(info.suppressed[_i3], info.stack, \"Suppressed: \", linePrefix + \"\\t\");\n }\n }\n\n if (info.cause) {\n s += QueryDetail.formatStackTraceHelper(info.cause, info.stack, \"Caused by: \", linePrefix);\n }\n\n return s;\n }\n }, {\n key: \"countSharedStackFrames\",\n value: function countSharedStackFrames(stack, parentStack) {\n var n = 0;\n var minStackLength = Math.min(stack.length, parentStack.length);\n while (n < minStackLength && stack[stack.length - 1 - n] === parentStack[parentStack.length - 1 - n]) {\n n++;\n }\n return n;\n }\n }, {\n key: \"failureInfoToString\",\n value: function failureInfoToString(t) {\n return t.message !== null ? t.type + \": \" + t.message : t.type;\n }\n }]);\n\n return QueryDetail;\n}(_react2.default.Component);\n\n//# sourceURL=webpack:///./components/QueryDetail.jsx?"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.QueryDetail = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _react = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _reactable = __webpack_require__(/*! reactable */ \"./node_modules/reactable/lib/reactable.js\");\n\nvar _reactable2 = _interopRequireDefault(_reactable);\n\nvar _utils = __webpack_require__(/*! ../utils */ \"./utils.js\");\n\nvar _QueryHeader = __webpack_require__(/*! ./QueryHeader */ \"./components/QueryHeader.jsx\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar Table = _reactable2.default.Table,\n Thead = _reactable2.default.Thead,\n Th = _reactable2.default.Th,\n Tr = _reactable2.default.Tr,\n Td = _reactable2.default.Td;\n\nvar TaskList = function (_React$Component) {\n _inherits(TaskList, _React$Component);\n\n function TaskList() {\n _classCallCheck(this, TaskList);\n\n return _possibleConstructorReturn(this, (TaskList.__proto__ || Object.getPrototypeOf(TaskList)).apply(this, arguments));\n }\n\n _createClass(TaskList, [{\n key: \"render\",\n value: function render() {\n var tasks = this.props.tasks;\n\n if (tasks === undefined || tasks.length === 0) {\n return _react2.default.createElement(\n \"div\",\n { className: \"row error-message\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h4\",\n null,\n \"No threads in the selected group\"\n )\n )\n );\n }\n\n var showPortNumbers = TaskList.showPortNumbers(tasks);\n\n var renderedTasks = tasks.map(function (task) {\n var elapsedTime = (0, _utils.parseDuration)(task.stats.elapsedTime);\n if (elapsedTime === 0) {\n elapsedTime = Date.now() - Date.parse(task.stats.createTime);\n }\n\n return _react2.default.createElement(\n Tr,\n { key: task.taskStatus.taskId },\n _react2.default.createElement(\n Td,\n { column: \"id\", value: task.taskStatus.taskId },\n _react2.default.createElement(\n \"a\",\n { href: \"/ui/api/worker/\" + task.taskStatus.nodeId + \"/task/\" + task.taskStatus.taskId + \"?pretty\" },\n (0, _utils.getTaskIdSuffix)(task.taskStatus.taskId)\n )\n ),\n _react2.default.createElement(\n Td,\n { column: \"host\", value: (0, _utils.getHostname)(task.taskStatus.self) },\n _react2.default.createElement(\n \"a\",\n { href: \"worker.html?\" + task.taskStatus.nodeId, className: \"font-light\", target: \"_blank\" },\n showPortNumbers ? (0, _utils.getHostAndPort)(task.taskStatus.self) : (0, _utils.getHostname)(task.taskStatus.self)\n )\n ),\n _react2.default.createElement(\n Td,\n { column: \"state\", value: TaskList.formatState(task.taskStatus.state, task.stats.fullyBlocked) },\n TaskList.formatState(task.taskStatus.state, task.stats.fullyBlocked)\n ),\n _react2.default.createElement(\n Td,\n { column: \"rows\", value: task.stats.rawInputPositions },\n (0, _utils.formatCount)(task.stats.rawInputPositions)\n ),\n _react2.default.createElement(\n Td,\n { column: \"rowsSec\", value: (0, _utils.computeRate)(task.stats.rawInputPositions, elapsedTime) },\n (0, _utils.formatCount)((0, _utils.computeRate)(task.stats.rawInputPositions, elapsedTime))\n ),\n _react2.default.createElement(\n Td,\n { column: \"bytes\", value: (0, _utils.parseDataSize)(task.stats.rawInputDataSize) },\n (0, _utils.formatDataSizeBytes)((0, _utils.parseDataSize)(task.stats.rawInputDataSize))\n ),\n _react2.default.createElement(\n Td,\n { column: \"bytesSec\", value: (0, _utils.computeRate)((0, _utils.parseDataSize)(task.stats.rawInputDataSize), elapsedTime) },\n (0, _utils.formatDataSizeBytes)((0, _utils.computeRate)((0, _utils.parseDataSize)(task.stats.rawInputDataSize), elapsedTime))\n ),\n _react2.default.createElement(\n Td,\n { column: \"splitsPending\", value: task.stats.queuedDrivers },\n task.stats.queuedDrivers\n ),\n _react2.default.createElement(\n Td,\n { column: \"splitsRunning\", value: task.stats.runningDrivers },\n task.stats.runningDrivers\n ),\n _react2.default.createElement(\n Td,\n { column: \"splitsBlocked\", value: task.stats.blockedDrivers },\n task.stats.blockedDrivers\n ),\n _react2.default.createElement(\n Td,\n { column: \"splitsDone\", value: task.stats.completedDrivers },\n task.stats.completedDrivers\n ),\n _react2.default.createElement(\n Td,\n { column: \"elapsedTime\", value: (0, _utils.parseDuration)(task.stats.elapsedTime) },\n task.stats.elapsedTime\n ),\n _react2.default.createElement(\n Td,\n { column: \"cpuTime\", value: (0, _utils.parseDuration)(task.stats.totalCpuTime) },\n task.stats.totalCpuTime\n ),\n _react2.default.createElement(\n Td,\n { column: \"bufferedBytes\", value: task.outputBuffers.totalBufferedBytes },\n (0, _utils.formatDataSizeBytes)(task.outputBuffers.totalBufferedBytes)\n )\n );\n });\n\n return _react2.default.createElement(\n Table,\n { id: \"tasks\", className: \"table table-striped sortable\", sortable: [{\n column: 'id',\n sortFunction: TaskList.compareTaskId\n }, 'host', 'state', 'splitsPending', 'splitsRunning', 'splitsBlocked', 'splitsDone', 'rows', 'rowsSec', 'bytes', 'bytesSec', 'elapsedTime', 'cpuTime', 'bufferedBytes'],\n defaultSort: { column: 'id', direction: 'asc' } },\n _react2.default.createElement(\n Thead,\n null,\n _react2.default.createElement(\n Th,\n { column: \"id\" },\n \"ID\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"host\" },\n \"Host\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"state\" },\n \"State\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"splitsPending\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-pause\", style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\",\n title: \"Pending splits\" })\n ),\n _react2.default.createElement(\n Th,\n { column: \"splitsRunning\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-play\", style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\",\n title: \"Running splits\" })\n ),\n _react2.default.createElement(\n Th,\n { column: \"splitsBlocked\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-bookmark\", style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\",\n title: \"Blocked splits\" })\n ),\n _react2.default.createElement(\n Th,\n { column: \"splitsDone\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-ok\", style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\",\n title: \"Completed splits\" })\n ),\n _react2.default.createElement(\n Th,\n { column: \"rows\" },\n \"Rows\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"rowsSec\" },\n \"Rows/s\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"bytes\" },\n \"Bytes\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"bytesSec\" },\n \"Bytes/s\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"elapsedTime\" },\n \"Elapsed\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"cpuTime\" },\n \"CPU Time\"\n ),\n _react2.default.createElement(\n Th,\n { column: \"bufferedBytes\" },\n \"Buffered\"\n )\n ),\n renderedTasks\n );\n }\n }], [{\n key: \"removeQueryId\",\n value: function removeQueryId(id) {\n var pos = id.indexOf('.');\n if (pos !== -1) {\n return id.substring(pos + 1);\n }\n return id;\n }\n }, {\n key: \"compareTaskId\",\n value: function compareTaskId(taskA, taskB) {\n var taskIdArrA = TaskList.removeQueryId(taskA).split(\".\");\n var taskIdArrB = TaskList.removeQueryId(taskB).split(\".\");\n\n if (taskIdArrA.length > taskIdArrB.length) {\n return 1;\n }\n for (var i = 0; i < taskIdArrA.length; i++) {\n var anum = Number.parseInt(taskIdArrA[i]);\n var bnum = Number.parseInt(taskIdArrB[i]);\n if (anum !== bnum) {\n return anum > bnum ? 1 : -1;\n }\n }\n\n return 0;\n }\n }, {\n key: \"showPortNumbers\",\n value: function showPortNumbers(tasks) {\n // check if any host has multiple port numbers\n var hostToPortNumber = {};\n for (var i = 0; i < tasks.length; i++) {\n var taskUri = tasks[i].taskStatus.self;\n var hostname = (0, _utils.getHostname)(taskUri);\n var port = (0, _utils.getPort)(taskUri);\n if (hostname in hostToPortNumber && hostToPortNumber[hostname] !== port) {\n return true;\n }\n hostToPortNumber[hostname] = port;\n }\n\n return false;\n }\n }, {\n key: \"formatState\",\n value: function formatState(state, fullyBlocked) {\n if (fullyBlocked && state === \"RUNNING\") {\n return \"BLOCKED\";\n } else {\n return state;\n }\n }\n }]);\n\n return TaskList;\n}(_react2.default.Component);\n\nvar BAR_CHART_WIDTH = 800;\n\nvar BAR_CHART_PROPERTIES = {\n type: 'bar',\n barSpacing: '0',\n height: '80px',\n barColor: '#747F96',\n zeroColor: '#8997B3',\n chartRangeMin: 0,\n tooltipClassname: 'sparkline-tooltip',\n tooltipFormat: 'Task {{offset:offset}} - {{value}}',\n disableHiddenCheck: true\n};\n\nvar HISTOGRAM_WIDTH = 175;\n\nvar HISTOGRAM_PROPERTIES = {\n type: 'bar',\n barSpacing: '0',\n height: '80px',\n barColor: '#747F96',\n zeroColor: '#747F96',\n zeroAxis: true,\n chartRangeMin: 0,\n tooltipClassname: 'sparkline-tooltip',\n tooltipFormat: '{{offset:offset}} -- {{value}} tasks',\n disableHiddenCheck: true\n};\n\nvar StageSummary = function (_React$Component2) {\n _inherits(StageSummary, _React$Component2);\n\n function StageSummary(props) {\n _classCallCheck(this, StageSummary);\n\n var _this2 = _possibleConstructorReturn(this, (StageSummary.__proto__ || Object.getPrototypeOf(StageSummary)).call(this, props));\n\n _this2.state = {\n expanded: false,\n lastRender: null\n };\n return _this2;\n }\n\n _createClass(StageSummary, [{\n key: \"getExpandedIcon\",\n value: function getExpandedIcon() {\n return this.state.expanded ? \"glyphicon-chevron-up\" : \"glyphicon-chevron-down\";\n }\n }, {\n key: \"getExpandedStyle\",\n value: function getExpandedStyle() {\n return this.state.expanded ? {} : { display: \"none\" };\n }\n }, {\n key: \"toggleExpanded\",\n value: function toggleExpanded() {\n this.setState({\n expanded: !this.state.expanded\n });\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n var stage = this.props.stage;\n var numTasks = stage.tasks.length;\n\n // sort the x-axis\n stage.tasks.sort(function (taskA, taskB) {\n return (0, _utils.getTaskNumber)(taskA.taskStatus.taskId) - (0, _utils.getTaskNumber)(taskB.taskStatus.taskId);\n });\n\n var scheduledTimes = stage.tasks.map(function (task) {\n return (0, _utils.parseDuration)(task.stats.totalScheduledTime);\n });\n var cpuTimes = stage.tasks.map(function (task) {\n return (0, _utils.parseDuration)(task.stats.totalCpuTime);\n });\n\n // prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts\n if (this.state.lastRender === null || Date.now() - this.state.lastRender >= 1000) {\n var renderTimestamp = Date.now();\n var stageId = (0, _utils.getStageNumber)(stage.stageId);\n\n StageSummary.renderHistogram('#scheduled-time-histogram-' + stageId, scheduledTimes, _utils.formatDuration);\n StageSummary.renderHistogram('#cpu-time-histogram-' + stageId, cpuTimes, _utils.formatDuration);\n\n if (this.state.expanded) {\n // this needs to be a string otherwise it will also be passed to numberFormatter\n var tooltipValueLookups = { 'offset': {} };\n for (var i = 0; i < numTasks; i++) {\n tooltipValueLookups['offset'][i] = (0, _utils.getStageNumber)(stage.stageId) + \".\" + i;\n }\n\n var stageBarChartProperties = $.extend({}, BAR_CHART_PROPERTIES, { barWidth: BAR_CHART_WIDTH / numTasks, tooltipValueLookups: tooltipValueLookups });\n\n $('#scheduled-time-bar-chart-' + stageId).sparkline(scheduledTimes, $.extend({}, stageBarChartProperties, { numberFormatter: _utils.formatDuration }));\n $('#cpu-time-bar-chart-' + stageId).sparkline(cpuTimes, $.extend({}, stageBarChartProperties, { numberFormatter: _utils.formatDuration }));\n }\n\n this.setState({\n lastRender: renderTimestamp\n });\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var stage = this.props.stage;\n if (stage === undefined || !stage.hasOwnProperty('plan')) {\n return _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n \"Information about this stage is unavailable.\"\n )\n );\n }\n\n var totalBufferedBytes = stage.tasks.map(function (task) {\n return task.outputBuffers.totalBufferedBytes;\n }).reduce(function (a, b) {\n return a + b;\n }, 0);\n\n var stageId = (0, _utils.getStageNumber)(stage.stageId);\n\n return _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-id\" },\n _react2.default.createElement(\n \"div\",\n { className: \"stage-state-color\", style: { borderLeftColor: (0, _utils.getStageStateColor)(stage) } },\n stageId\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"table single-stage-table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table stage-table-time\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-stat-header\" },\n \"Time\"\n ),\n _react2.default.createElement(\"th\", null)\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Scheduled\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.stageStats.totalScheduledTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Blocked\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.stageStats.totalBlockedTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"CPU\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.stageStats.totalCpuTime\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table stage-table-memory\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-stat-header\" },\n \"Memory\"\n ),\n _react2.default.createElement(\"th\", null)\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Cumulative\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n (0, _utils.formatDataSizeBytes)(stage.stageStats.cumulativeUserMemory / 1000)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Current\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n (0, _utils.parseAndFormatDataSize)(stage.stageStats.userMemoryReservation)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Buffers\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n (0, _utils.formatDataSize)(totalBufferedBytes)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Peak\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n (0, _utils.parseAndFormatDataSize)(stage.stageStats.peakUserMemoryReservation)\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table stage-table-tasks\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-stat-header\" },\n \"Tasks\"\n ),\n _react2.default.createElement(\"th\", null)\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Pending\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.tasks.filter(function (task) {\n return task.taskStatus.state === \"PLANNED\";\n }).length\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Running\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.tasks.filter(function (task) {\n return task.taskStatus.state === \"RUNNING\";\n }).length\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Blocked\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.tasks.filter(function (task) {\n return task.stats.fullyBlocked;\n }).length\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title\" },\n \"Total\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-text\" },\n stage.tasks.length\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table histogram-table\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-chart-header\" },\n \"Scheduled Time Skew\"\n )\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"histogram-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"histogram\", id: \"scheduled-time-histogram-\" + stageId },\n _react2.default.createElement(\"div\", { className: \"loader\" })\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"table\",\n { className: \"stage-table histogram-table\" },\n _react2.default.createElement(\n \"thead\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"th\",\n { className: \"stage-table-stat-title stage-table-chart-header\" },\n \"CPU Time Skew\"\n )\n )\n ),\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"histogram-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"histogram\", id: \"cpu-time-histogram-\" + stageId },\n _react2.default.createElement(\"div\", { className: \"loader\" })\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"expand-charts-container\" },\n _react2.default.createElement(\n \"a\",\n { onClick: this.toggleExpanded.bind(this), className: \"expand-charts-button\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon \" + this.getExpandedIcon(), style: _utils.GLYPHICON_HIGHLIGHT, \"data-toggle\": \"tooltip\", \"data-placement\": \"top\", title: \"More\" })\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { style: this.getExpandedStyle() },\n _react2.default.createElement(\n \"td\",\n { colSpan: \"6\" },\n _react2.default.createElement(\n \"table\",\n { className: \"expanded-chart\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title expanded-chart-title\" },\n \"Task Scheduled Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"bar-chart-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"bar-chart\", id: \"scheduled-time-bar-chart-\" + stageId },\n _react2.default.createElement(\"div\", { className: \"loader\" })\n )\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { style: this.getExpandedStyle() },\n _react2.default.createElement(\n \"td\",\n { colSpan: \"6\" },\n _react2.default.createElement(\n \"table\",\n { className: \"expanded-chart\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"stage-table-stat-title expanded-chart-title\" },\n \"Task CPU Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"bar-chart-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"bar-chart\", id: \"cpu-time-bar-chart-\" + stageId },\n _react2.default.createElement(\"div\", { className: \"loader\" })\n )\n )\n )\n )\n )\n )\n )\n )\n )\n )\n );\n }\n }], [{\n key: \"renderHistogram\",\n value: function renderHistogram(histogramId, inputData, numberFormatter) {\n var numBuckets = Math.min(HISTOGRAM_WIDTH, Math.sqrt(inputData.length));\n var dataMin = Math.min.apply(null, inputData);\n var dataMax = Math.max.apply(null, inputData);\n var bucketSize = (dataMax - dataMin) / numBuckets;\n\n var histogramData = [];\n if (bucketSize === 0) {\n histogramData = [inputData.length];\n } else {\n for (var i = 0; i < numBuckets + 1; i++) {\n histogramData.push(0);\n }\n\n for (var _i in inputData) {\n var dataPoint = inputData[_i];\n var bucket = Math.floor((dataPoint - dataMin) / bucketSize);\n histogramData[bucket] = histogramData[bucket] + 1;\n }\n }\n\n var tooltipValueLookups = { 'offset': {} };\n for (var _i2 = 0; _i2 < histogramData.length; _i2++) {\n tooltipValueLookups['offset'][_i2] = numberFormatter(dataMin + _i2 * bucketSize) + \"-\" + numberFormatter(dataMin + (_i2 + 1) * bucketSize);\n }\n\n var stageHistogramProperties = $.extend({}, HISTOGRAM_PROPERTIES, { barWidth: HISTOGRAM_WIDTH / histogramData.length, tooltipValueLookups: tooltipValueLookups });\n $(histogramId).sparkline(histogramData, stageHistogramProperties);\n }\n }]);\n\n return StageSummary;\n}(_react2.default.Component);\n\nvar StageList = function (_React$Component3) {\n _inherits(StageList, _React$Component3);\n\n function StageList() {\n _classCallCheck(this, StageList);\n\n return _possibleConstructorReturn(this, (StageList.__proto__ || Object.getPrototypeOf(StageList)).apply(this, arguments));\n }\n\n _createClass(StageList, [{\n key: \"getStages\",\n value: function getStages(stage) {\n if (stage === undefined || !stage.hasOwnProperty('subStages')) {\n return [];\n }\n\n return [].concat.apply(stage, stage.subStages.map(this.getStages, this));\n }\n }, {\n key: \"render\",\n value: function render() {\n var stages = this.getStages(this.props.outputStage);\n\n if (stages === undefined || stages.length === 0) {\n return _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n \"No stage information available.\"\n )\n );\n }\n\n var renderedStages = stages.map(function (stage) {\n return _react2.default.createElement(StageSummary, { key: stage.stageId, stage: stage });\n });\n\n return _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"table\",\n { className: \"table\", id: \"stage-list\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n renderedStages\n )\n )\n )\n );\n }\n }]);\n\n return StageList;\n}(_react2.default.Component);\n\nvar SMALL_SPARKLINE_PROPERTIES = {\n width: '100%',\n height: '57px',\n fillColor: '#3F4552',\n lineColor: '#747F96',\n spotColor: '#1EDCFF',\n tooltipClassname: 'sparkline-tooltip',\n disableHiddenCheck: true\n};\n\nvar TASK_FILTER = {\n ALL: function ALL() {\n return true;\n },\n PLANNED: function PLANNED(state) {\n return state === 'PLANNED';\n },\n RUNNING: function RUNNING(state) {\n return state === 'RUNNING';\n },\n FINISHED: function FINISHED(state) {\n return state === 'FINISHED';\n },\n FAILED: function FAILED(state) {\n return state === 'FAILED' || state === 'ABORTED' || state === 'CANCELED';\n }\n};\n\nvar QueryDetail = exports.QueryDetail = function (_React$Component4) {\n _inherits(QueryDetail, _React$Component4);\n\n function QueryDetail(props) {\n _classCallCheck(this, QueryDetail);\n\n var _this4 = _possibleConstructorReturn(this, (QueryDetail.__proto__ || Object.getPrototypeOf(QueryDetail)).call(this, props));\n\n _this4.state = {\n query: null,\n lastSnapshotStages: null,\n lastSnapshotTasks: null,\n\n lastScheduledTime: 0,\n lastCpuTime: 0,\n lastRowInput: 0,\n lastByteInput: 0,\n lastPhysicalInput: 0,\n lastPhysicalTime: 0,\n\n scheduledTimeRate: [],\n cpuTimeRate: [],\n rowInputRate: [],\n byteInputRate: [],\n physicalInputRate: [],\n\n reservedMemory: [],\n\n initialized: false,\n queryEnded: false,\n renderingEnded: false,\n\n lastRefresh: null,\n lastRender: null,\n\n stageRefresh: true,\n taskRefresh: true,\n\n taskFilter: TASK_FILTER.ALL\n };\n\n _this4.refreshLoop = _this4.refreshLoop.bind(_this4);\n return _this4;\n }\n\n _createClass(QueryDetail, [{\n key: \"resetTimer\",\n value: function resetTimer() {\n clearTimeout(this.timeoutId);\n // stop refreshing when query finishes or fails\n if (this.state.query === null || !this.state.queryEnded) {\n // task.info-update-interval is set to 3 seconds by default\n this.timeoutId = setTimeout(this.refreshLoop, 3000);\n }\n }\n }, {\n key: \"refreshLoop\",\n value: function refreshLoop() {\n var _this5 = this;\n\n clearTimeout(this.timeoutId); // to stop multiple series of refreshLoop from going on simultaneously\n var queryId = (0, _utils.getFirstParameter)(window.location.search);\n $.get('/ui/api/query/' + queryId, function (query) {\n var lastSnapshotStages = this.state.lastSnapshotStage;\n if (this.state.stageRefresh) {\n lastSnapshotStages = query.outputStage;\n }\n var lastSnapshotTasks = this.state.lastSnapshotTasks;\n if (this.state.taskRefresh) {\n lastSnapshotTasks = query.outputStage;\n }\n\n var lastRefresh = this.state.lastRefresh;\n var lastScheduledTime = this.state.lastScheduledTime;\n var lastCpuTime = this.state.lastCpuTime;\n var lastRowInput = this.state.lastRowInput;\n var lastByteInput = this.state.lastByteInput;\n var lastPhysicalInput = this.state.lastPhysicalInput;\n var lastPhysicalTime = this.state.lastPhysicalTime;\n var alreadyEnded = this.state.queryEnded;\n var nowMillis = Date.now();\n\n this.setState({\n query: query,\n lastSnapshotStage: lastSnapshotStages,\n lastSnapshotTasks: lastSnapshotTasks,\n\n lastPhysicalTime: (0, _utils.parseDuration)(query.queryStats.physicalInputReadTime),\n lastScheduledTime: (0, _utils.parseDuration)(query.queryStats.totalScheduledTime),\n lastCpuTime: (0, _utils.parseDuration)(query.queryStats.totalCpuTime),\n lastRowInput: query.queryStats.processedInputPositions,\n lastByteInput: (0, _utils.parseDataSize)(query.queryStats.processedInputDataSize),\n lastPhysicalInput: (0, _utils.parseDataSize)(query.queryStats.physicalInputDataSize),\n\n initialized: true,\n queryEnded: !!query.finalQueryInfo,\n\n lastRefresh: nowMillis\n });\n\n // i.e. don't show sparklines if we've already decided not to update or if we don't have one previous measurement\n if (alreadyEnded || lastRefresh === null && query.state === \"RUNNING\") {\n this.resetTimer();\n return;\n }\n\n if (lastRefresh === null) {\n lastRefresh = nowMillis - (0, _utils.parseDuration)(query.queryStats.elapsedTime);\n }\n\n var elapsedSecsSinceLastRefresh = (nowMillis - lastRefresh) / 1000.0;\n if (elapsedSecsSinceLastRefresh >= 0) {\n var currentScheduledTimeRate = ((0, _utils.parseDuration)(query.queryStats.totalScheduledTime) - lastScheduledTime) / (elapsedSecsSinceLastRefresh * 1000);\n var currentCpuTimeRate = ((0, _utils.parseDuration)(query.queryStats.totalCpuTime) - lastCpuTime) / (elapsedSecsSinceLastRefresh * 1000);\n var currentPhysicalReadTime = ((0, _utils.parseDuration)(query.queryStats.physicalInputReadTime) - lastPhysicalTime) / 1000;\n var currentRowInputRate = (query.queryStats.processedInputPositions - lastRowInput) / elapsedSecsSinceLastRefresh;\n var currentByteInputRate = ((0, _utils.parseDataSize)(query.queryStats.processedInputDataSize) - lastByteInput) / elapsedSecsSinceLastRefresh;\n var currentPhysicalInputRate = currentPhysicalReadTime > 0 ? ((0, _utils.parseDataSize)(query.queryStats.physicalInputDataSize) - lastPhysicalInput) / currentPhysicalReadTime : 0;\n\n this.setState({\n scheduledTimeRate: (0, _utils.addToHistory)(currentScheduledTimeRate, this.state.scheduledTimeRate),\n cpuTimeRate: (0, _utils.addToHistory)(currentCpuTimeRate, this.state.cpuTimeRate),\n rowInputRate: (0, _utils.addToHistory)(currentRowInputRate, this.state.rowInputRate),\n byteInputRate: (0, _utils.addToHistory)(currentByteInputRate, this.state.byteInputRate),\n reservedMemory: (0, _utils.addToHistory)((0, _utils.parseDataSize)(query.queryStats.totalMemoryReservation), this.state.reservedMemory),\n physicalInputRate: (0, _utils.addToHistory)(currentPhysicalInputRate, this.state.physicalInputRate)\n });\n }\n this.resetTimer();\n }.bind(this)).fail(function () {\n _this5.setState({\n initialized: true\n });\n _this5.resetTimer();\n });\n }\n }, {\n key: \"handleTaskRefreshClick\",\n value: function handleTaskRefreshClick() {\n if (this.state.taskRefresh) {\n this.setState({\n taskRefresh: false,\n lastSnapshotTasks: this.state.query.outputStage\n });\n } else {\n this.setState({\n taskRefresh: true\n });\n }\n }\n }, {\n key: \"renderTaskRefreshButton\",\n value: function renderTaskRefreshButton() {\n if (this.state.taskRefresh) {\n return _react2.default.createElement(\n \"button\",\n { className: \"btn btn-info live-button\", onClick: this.handleTaskRefreshClick.bind(this) },\n \"Auto-Refresh: On\"\n );\n } else {\n return _react2.default.createElement(\n \"button\",\n { className: \"btn btn-info live-button\", onClick: this.handleTaskRefreshClick.bind(this) },\n \"Auto-Refresh: Off\"\n );\n }\n }\n }, {\n key: \"handleStageRefreshClick\",\n value: function handleStageRefreshClick() {\n if (this.state.stageRefresh) {\n this.setState({\n stageRefresh: false,\n lastSnapshotStages: this.state.query.outputStage\n });\n } else {\n this.setState({\n stageRefresh: true\n });\n }\n }\n }, {\n key: \"renderStageRefreshButton\",\n value: function renderStageRefreshButton() {\n if (this.state.stageRefresh) {\n return _react2.default.createElement(\n \"button\",\n { className: \"btn btn-info live-button\", onClick: this.handleStageRefreshClick.bind(this) },\n \"Auto-Refresh: On\"\n );\n } else {\n return _react2.default.createElement(\n \"button\",\n { className: \"btn btn-info live-button\", onClick: this.handleStageRefreshClick.bind(this) },\n \"Auto-Refresh: Off\"\n );\n }\n }\n }, {\n key: \"renderTaskFilterListItem\",\n value: function renderTaskFilterListItem(taskFilter, taskFilterText) {\n return _react2.default.createElement(\n \"li\",\n null,\n _react2.default.createElement(\n \"a\",\n { href: \"#\", className: this.state.taskFilter === taskFilter ? \"selected\" : \"\", onClick: this.handleTaskFilterClick.bind(this, taskFilter) },\n taskFilterText\n )\n );\n }\n }, {\n key: \"handleTaskFilterClick\",\n value: function handleTaskFilterClick(filter, event) {\n this.setState({\n taskFilter: filter\n });\n event.preventDefault();\n }\n }, {\n key: \"getTasksFromStage\",\n value: function getTasksFromStage(stage) {\n if (stage === undefined || !stage.hasOwnProperty('subStages') || !stage.hasOwnProperty('tasks')) {\n return [];\n }\n\n return [].concat.apply(stage.tasks, stage.subStages.map(this.getTasksFromStage, this));\n }\n }, {\n key: \"componentDidMount\",\n value: function componentDidMount() {\n this.refreshLoop();\n }\n }, {\n key: \"componentDidUpdate\",\n value: function componentDidUpdate() {\n // prevent multiple calls to componentDidUpdate (resulting from calls to setState or otherwise) within the refresh interval from re-rendering sparklines/charts\n if (this.state.lastRender === null || Date.now() - this.state.lastRender >= 1000 || this.state.ended && !this.state.renderingEnded) {\n var renderTimestamp = Date.now();\n $('#scheduled-time-rate-sparkline').sparkline(this.state.scheduledTimeRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, {\n chartRangeMin: 0,\n numberFormatter: _utils.precisionRound\n }));\n $('#cpu-time-rate-sparkline').sparkline(this.state.cpuTimeRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { chartRangeMin: 0, numberFormatter: _utils.precisionRound }));\n $('#row-input-rate-sparkline').sparkline(this.state.rowInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { numberFormatter: _utils.formatCount }));\n $('#byte-input-rate-sparkline').sparkline(this.state.byteInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { numberFormatter: _utils.formatDataSize }));\n $('#reserved-memory-sparkline').sparkline(this.state.reservedMemory, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { numberFormatter: _utils.formatDataSize }));\n $('#physical-input-rate-sparkline').sparkline(this.state.physicalInputRate, $.extend({}, SMALL_SPARKLINE_PROPERTIES, { numberFormatter: _utils.formatDataSize }));\n\n if (this.state.lastRender === null) {\n $('#query').each(function (i, block) {\n hljs.highlightBlock(block);\n });\n\n $('#prepared-query').each(function (i, block) {\n hljs.highlightBlock(block);\n });\n }\n\n this.setState({\n renderingEnded: this.state.ended,\n lastRender: renderTimestamp\n });\n }\n\n $('[data-toggle=\"tooltip\"]').tooltip();\n new window.ClipboardJS('.copy-button');\n }\n }, {\n key: \"renderTasks\",\n value: function renderTasks() {\n var _this6 = this;\n\n if (this.state.lastSnapshotTasks === null) {\n return;\n }\n\n var tasks = this.getTasksFromStage(this.state.lastSnapshotTasks).filter(function (task) {\n return _this6.state.taskFilter(task.taskStatus.state);\n }, this);\n\n return _react2.default.createElement(\n \"div\",\n null,\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-9\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Tasks\"\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-3\" },\n _react2.default.createElement(\n \"table\",\n { className: \"header-inline-links\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n _react2.default.createElement(\n \"div\",\n { className: \"input-group-btn text-right\" },\n _react2.default.createElement(\n \"button\",\n { type: \"button\", className: \"btn btn-default dropdown-toggle pull-right text-right\", \"data-toggle\": \"dropdown\", \"aria-haspopup\": \"true\",\n \"aria-expanded\": \"false\" },\n \"Show \",\n _react2.default.createElement(\"span\", { className: \"caret\" })\n ),\n _react2.default.createElement(\n \"ul\",\n { className: \"dropdown-menu\" },\n this.renderTaskFilterListItem(TASK_FILTER.ALL, \"All\"),\n this.renderTaskFilterListItem(TASK_FILTER.PLANNED, \"Planned\"),\n this.renderTaskFilterListItem(TASK_FILTER.RUNNING, \"Running\"),\n this.renderTaskFilterListItem(TASK_FILTER.FINISHED, \"Finished\"),\n this.renderTaskFilterListItem(TASK_FILTER.FAILED, \"Aborted/Canceled/Failed\")\n )\n )\n ),\n _react2.default.createElement(\n \"td\",\n null,\n \"\\xA0\\xA0\",\n this.renderTaskRefreshButton()\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(TaskList, { key: this.state.query.queryId, tasks: tasks })\n )\n )\n );\n }\n }, {\n key: \"renderStages\",\n value: function renderStages() {\n if (this.state.lastSnapshotStage === null) {\n return;\n }\n\n return _react2.default.createElement(\n \"div\",\n null,\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-9\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Stages\"\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-3\" },\n _react2.default.createElement(\n \"table\",\n { className: \"header-inline-links\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n this.renderStageRefreshButton()\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(StageList, { key: this.state.query.queryId, outputStage: this.state.lastSnapshotStage })\n )\n )\n );\n }\n }, {\n key: \"renderPreparedQuery\",\n value: function renderPreparedQuery() {\n var query = this.state.query;\n if (!query.hasOwnProperty('preparedQuery') || query.preparedQuery === null) {\n return;\n }\n\n return _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Prepared Query\",\n _react2.default.createElement(\n \"a\",\n { className: \"btn copy-button\", \"data-clipboard-target\": \"#prepared-query-text\", \"data-toggle\": \"tooltip\", \"data-placement\": \"right\", title: \"Copy to clipboard\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-copy\", \"aria-hidden\": \"true\", alt: \"Copy to clipboard\" })\n )\n ),\n _react2.default.createElement(\n \"pre\",\n { id: \"prepared-query\" },\n _react2.default.createElement(\n \"code\",\n { className: \"lang-sql\", id: \"prepared-query-text\" },\n query.preparedQuery\n )\n )\n );\n }\n }, {\n key: \"renderSessionProperties\",\n value: function renderSessionProperties() {\n var query = this.state.query;\n\n var properties = [];\n for (var property in query.session.systemProperties) {\n if (query.session.systemProperties.hasOwnProperty(property)) {\n properties.push(_react2.default.createElement(\n \"span\",\n null,\n \"- \",\n property + \"=\" + query.session.systemProperties[property],\n \" \",\n _react2.default.createElement(\"br\", null)\n ));\n }\n }\n\n for (var catalog in query.session.catalogProperties) {\n if (query.session.catalogProperties.hasOwnProperty(catalog)) {\n for (var _property in query.session.catalogProperties[catalog]) {\n if (query.session.catalogProperties[catalog].hasOwnProperty(_property)) {\n properties.push(_react2.default.createElement(\n \"span\",\n null,\n \"- \",\n catalog + \".\" + _property + \"=\" + query.session.catalogProperties[catalog][_property],\n \" \",\n _react2.default.createElement(\"br\", null)\n ));\n }\n }\n }\n }\n\n return properties;\n }\n }, {\n key: \"renderResourceEstimates\",\n value: function renderResourceEstimates() {\n var query = this.state.query;\n var estimates = query.session.resourceEstimates;\n var renderedEstimates = [];\n\n for (var resource in estimates) {\n if (estimates.hasOwnProperty(resource)) {\n var upperChars = resource.match(/([A-Z])/g) || [];\n var snakeCased = resource;\n for (var i = 0, n = upperChars.length; i < n; i++) {\n snakeCased = snakeCased.replace(new RegExp(upperChars[i]), '_' + upperChars[i].toLowerCase());\n }\n\n renderedEstimates.push(_react2.default.createElement(\n \"span\",\n null,\n \"- \",\n snakeCased + \"=\" + query.session.resourceEstimates[resource],\n \" \",\n _react2.default.createElement(\"br\", null)\n ));\n }\n }\n\n return renderedEstimates;\n }\n }, {\n key: \"renderWarningInfo\",\n value: function renderWarningInfo() {\n var query = this.state.query;\n if (query.warnings.length > 0) {\n return _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Warnings\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\", id: \"warnings-table\" },\n query.warnings.map(function (warning) {\n return _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n null,\n warning.warningCode.name\n ),\n _react2.default.createElement(\n \"td\",\n null,\n warning.message\n )\n );\n })\n )\n )\n );\n } else {\n return null;\n }\n }\n }, {\n key: \"renderFailureInfo\",\n value: function renderFailureInfo() {\n var query = this.state.query;\n if (query.failureInfo) {\n return _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Error Information\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Error Type\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.errorType\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Error Code\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.errorCode.name + \" (\" + this.state.query.errorCode.code + \")\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Stack Trace\",\n _react2.default.createElement(\n \"a\",\n { className: \"btn copy-button\", \"data-clipboard-target\": \"#stack-trace\", \"data-toggle\": \"tooltip\", \"data-placement\": \"right\", title: \"Copy to clipboard\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-copy\", \"aria-hidden\": \"true\", alt: \"Copy to clipboard\" })\n )\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n _react2.default.createElement(\n \"pre\",\n { id: \"stack-trace\" },\n QueryDetail.formatStackTrace(query.failureInfo)\n )\n )\n )\n )\n )\n )\n );\n } else {\n return \"\";\n }\n }\n }, {\n key: \"render\",\n value: function render() {\n var query = this.state.query;\n\n if (query === null || this.state.initialized === false) {\n var label = _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading...\"\n );\n if (this.state.initialized) {\n label = \"Query not found\";\n }\n return _react2.default.createElement(\n \"div\",\n { className: \"row error-message\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h4\",\n null,\n label\n )\n )\n );\n }\n\n return _react2.default.createElement(\n \"div\",\n null,\n _react2.default.createElement(_QueryHeader.QueryHeader, { query: query }),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-6\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Session\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"User\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n _react2.default.createElement(\n \"span\",\n { id: \"query-user\" },\n query.session.user\n ),\n \"\\xA0\\xA0\",\n _react2.default.createElement(\n \"a\",\n { href: \"#\", className: \"copy-button\", \"data-clipboard-target\": \"#query-user\", \"data-toggle\": \"tooltip\", \"data-placement\": \"right\", title: \"Copy to clipboard\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-copy\", \"aria-hidden\": \"true\", alt: \"Copy to clipboard\" })\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Principal\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n query.session.principal\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Source\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n query.session.source\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Catalog\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.catalog\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Schema\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.schema\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Time zone\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.timeZone\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Client Address\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.remoteUserAddress\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Client Tags\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.session.clientTags.join(\", \")\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Session Properties\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n this.renderSessionProperties()\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Resource Estimates\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n this.renderResourceEstimates()\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-6\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Execution\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Resource Group\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text wrap-text\" },\n query.resourceGroupId ? query.resourceGroupId.join(\".\") : \"n/a\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Submission Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatShortDateTime)(new Date(query.queryStats.createTime))\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Completion Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.endTime ? (0, _utils.formatShortDateTime)(new Date(query.queryStats.endTime)) : \"\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Elapsed Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.elapsedTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Queued Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.queuedTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Analysis Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.analysisTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Planning Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.planningTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Execution Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.executionTime\n )\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-6\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Resource Utilization Summary\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"CPU Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.totalCpuTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"CPU Time (failed tasks)\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.failedCpuTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Scheduled Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.totalScheduledTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Scheduled Time (failed tasks)\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.failedScheduledTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Input Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.processedInputPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Input Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.processedInputDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Input Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.physicalInputPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Input Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.physicalInputDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Input Read Time\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n query.queryStats.physicalInputReadTime\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Internal Network Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.internalNetworkInputPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Internal Network Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.internalNetworkInputDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Peak User Memory\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.peakUserMemoryReservation)\n )\n ),\n (0, _utils.parseDataSize)(query.queryStats.peakRevocableMemoryReservation) > 0 && _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Peak Revocable Memory\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.peakRevocableMemoryReservation)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Peak Total Memory\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.peakTotalMemoryReservation)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Cumulative User Memory\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatDataSizeBytes)(query.queryStats.cumulativeUserMemory / 1000.0) + \" seconds\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Cumulative User Memory (failed tasks)\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatDataSizeBytes)(query.queryStats.failedCumulativeUserMemory / 1000.0) + \" seconds\"\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Output Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.outputPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Output Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.outputDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Written Rows\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.formatCount)(query.queryStats.writtenPositions)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Logical Written Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.logicalWrittenDataSize)\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Written Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.physicalWrittenDataSize)\n )\n ),\n (0, _utils.parseDataSize)(query.queryStats.spilledDataSize) > 0 && _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Spilled Data\"\n ),\n _react2.default.createElement(\n \"td\",\n { className: \"info-text\" },\n (0, _utils.parseAndFormatDataSize)(query.queryStats.spilledDataSize)\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-6\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Timeline\"\n ),\n _react2.default.createElement(\"hr\", { className: \"h3-hr\" }),\n _react2.default.createElement(\n \"table\",\n { className: \"table\" },\n _react2.default.createElement(\n \"tbody\",\n null,\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Parallelism\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"cpu-time-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatCount)(this.state.cpuTimeRate[this.state.cpuTimeRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Scheduled Time/s\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"scheduled-time-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatCount)(this.state.scheduledTimeRate[this.state.scheduledTimeRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Input Rows/s\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"row-input-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatCount)(this.state.rowInputRate[this.state.rowInputRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Input Bytes/s\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"byte-input-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatDataSize)(this.state.byteInputRate[this.state.byteInputRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Physical Input Bytes/s\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"physical-input-rate-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatDataSize)(this.state.physicalInputRate[this.state.physicalInputRate.length - 1])\n )\n ),\n _react2.default.createElement(\n \"tr\",\n null,\n _react2.default.createElement(\n \"td\",\n { className: \"info-title\" },\n \"Memory Utilization\"\n ),\n _react2.default.createElement(\n \"td\",\n { rowSpan: \"2\" },\n _react2.default.createElement(\n \"div\",\n { className: \"query-stats-sparkline-container\" },\n _react2.default.createElement(\n \"span\",\n { className: \"sparkline\", id: \"reserved-memory-sparkline\" },\n _react2.default.createElement(\n \"div\",\n { className: \"loader\" },\n \"Loading ...\"\n )\n )\n )\n )\n ),\n _react2.default.createElement(\n \"tr\",\n { className: \"tr-noborder\" },\n _react2.default.createElement(\n \"td\",\n { className: \"info-sparkline-text\" },\n (0, _utils.formatDataSize)(this.state.reservedMemory[this.state.reservedMemory.length - 1])\n )\n )\n )\n )\n )\n )\n )\n ),\n this.renderWarningInfo(),\n this.renderFailureInfo(),\n _react2.default.createElement(\n \"div\",\n { className: \"row\" },\n _react2.default.createElement(\n \"div\",\n { className: \"col-xs-12\" },\n _react2.default.createElement(\n \"h3\",\n null,\n \"Query\",\n _react2.default.createElement(\n \"a\",\n { className: \"btn copy-button\", \"data-clipboard-target\": \"#query-text\", \"data-toggle\": \"tooltip\", \"data-placement\": \"right\", title: \"Copy to clipboard\" },\n _react2.default.createElement(\"span\", { className: \"glyphicon glyphicon-copy\", \"aria-hidden\": \"true\", alt: \"Copy to clipboard\" })\n )\n ),\n _react2.default.createElement(\n \"pre\",\n { id: \"query\" },\n _react2.default.createElement(\n \"code\",\n { className: \"lang-sql\", id: \"query-text\" },\n query.query\n )\n )\n ),\n this.renderPreparedQuery()\n ),\n this.renderStages(),\n this.renderTasks()\n );\n }\n }], [{\n key: \"formatStackTrace\",\n value: function formatStackTrace(info) {\n return QueryDetail.formatStackTraceHelper(info, [], \"\", \"\");\n }\n }, {\n key: \"formatStackTraceHelper\",\n value: function formatStackTraceHelper(info, parentStack, prefix, linePrefix) {\n var s = linePrefix + prefix + QueryDetail.failureInfoToString(info) + \"\\n\";\n\n if (info.stack) {\n var sharedStackFrames = 0;\n if (parentStack !== null) {\n sharedStackFrames = QueryDetail.countSharedStackFrames(info.stack, parentStack);\n }\n\n for (var i = 0; i < info.stack.length - sharedStackFrames; i++) {\n s += linePrefix + \"\\tat \" + info.stack[i] + \"\\n\";\n }\n if (sharedStackFrames !== 0) {\n s += linePrefix + \"\\t... \" + sharedStackFrames + \" more\" + \"\\n\";\n }\n }\n\n if (info.suppressed) {\n for (var _i3 = 0; _i3 < info.suppressed.length; _i3++) {\n s += QueryDetail.formatStackTraceHelper(info.suppressed[_i3], info.stack, \"Suppressed: \", linePrefix + \"\\t\");\n }\n }\n\n if (info.cause) {\n s += QueryDetail.formatStackTraceHelper(info.cause, info.stack, \"Caused by: \", linePrefix);\n }\n\n return s;\n }\n }, {\n key: \"countSharedStackFrames\",\n value: function countSharedStackFrames(stack, parentStack) {\n var n = 0;\n var minStackLength = Math.min(stack.length, parentStack.length);\n while (n < minStackLength && stack[stack.length - 1 - n] === parentStack[parentStack.length - 1 - n]) {\n n++;\n }\n return n;\n }\n }, {\n key: \"failureInfoToString\",\n value: function failureInfoToString(t) {\n return t.message !== null ? t.type + \": \" + t.message : t.type;\n }\n }]);\n\n return QueryDetail;\n}(_react2.default.Component);\n\n//# sourceURL=webpack:///./components/QueryDetail.jsx?"); /***/ }), diff --git a/core/trino-main/src/main/resources/webapp/src/components/QueryDetail.jsx b/core/trino-main/src/main/resources/webapp/src/components/QueryDetail.jsx index 91778522a0a2..e3ab9f8742db 100644 --- a/core/trino-main/src/main/resources/webapp/src/components/QueryDetail.jsx +++ b/core/trino-main/src/main/resources/webapp/src/components/QueryDetail.jsx @@ -1336,6 +1336,14 @@ export class QueryDetail extends React.Component { {query.queryStats.totalCpuTime} + + + CPU Time (failed tasks) + + + {query.queryStats.failedCpuTime} + + Scheduled Time @@ -1344,6 +1352,14 @@ export class QueryDetail extends React.Component { {query.queryStats.totalScheduledTime} + + + Scheduled Time (failed tasks) + + + {query.queryStats.failedScheduledTime} + + Input Rows @@ -1434,6 +1450,14 @@ export class QueryDetail extends React.Component { {formatDataSizeBytes(query.queryStats.cumulativeUserMemory / 1000.0) + " seconds"} + + + Cumulative User Memory (failed tasks) + + + {formatDataSizeBytes(query.queryStats.failedCumulativeUserMemory / 1000.0) + " seconds"} + + Output Rows diff --git a/core/trino-main/src/test/java/io/trino/execution/MockManagedQueryExecution.java b/core/trino-main/src/test/java/io/trino/execution/MockManagedQueryExecution.java index f25bf98c422e..78dd96c3e8a4 100644 --- a/core/trino-main/src/test/java/io/trino/execution/MockManagedQueryExecution.java +++ b/core/trino-main/src/test/java/io/trino/execution/MockManagedQueryExecution.java @@ -131,12 +131,15 @@ public BasicQueryInfo getBasicQueryInfo() 15, DataSize.ofBytes(13), 16.0, + 17.0, memoryUsage, memoryUsage, DataSize.ofBytes(19), DataSize.ofBytes(20), cpuUsage, + new Duration(21, NANOSECONDS), new Duration(22, NANOSECONDS), + new Duration(23, NANOSECONDS), false, ImmutableSet.of(), OptionalDouble.empty()), @@ -175,6 +178,7 @@ public QueryInfo getFullQueryInfo() 9, 10, 11, + 0, 12, 13, @@ -183,6 +187,7 @@ public QueryInfo getFullQueryInfo() 16, 17.0, + 0.0, DataSize.ofBytes(18), DataSize.ofBytes(19), DataSize.ofBytes(20), @@ -196,27 +201,41 @@ public QueryInfo getFullQueryInfo() true, new Duration(20, NANOSECONDS), new Duration(21, NANOSECONDS), + new Duration(22, NANOSECONDS), + new Duration(0, NANOSECONDS), new Duration(23, NANOSECONDS), false, ImmutableSet.of(), DataSize.ofBytes(241), + DataSize.ofBytes(0), 251, + 0, new Duration(24, NANOSECONDS), + new Duration(0, NANOSECONDS), DataSize.ofBytes(242), + DataSize.ofBytes(0), 252, + 0, DataSize.ofBytes(25), + DataSize.ofBytes(0), 26, + 0, DataSize.ofBytes(27), + DataSize.ofBytes(0), 28, + 0, DataSize.ofBytes(29), + DataSize.ofBytes(0), 30, + 0, DataSize.ofBytes(31), + DataSize.ofBytes(0), ImmutableList.of(), DynamicFiltersStats.EMPTY, diff --git a/core/trino-main/src/test/java/io/trino/execution/TestQueryStats.java b/core/trino-main/src/test/java/io/trino/execution/TestQueryStats.java index 12f0d1e98fe5..694582e276df 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestQueryStats.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestQueryStats.java @@ -175,15 +175,16 @@ public class TestQueryStats 9, 10, 11, - 12, + 13, + 14, 15, 30, 16, 17.0, - DataSize.ofBytes(18), + 18.0, DataSize.ofBytes(19), DataSize.ofBytes(20), DataSize.ofBytes(21), @@ -192,31 +193,46 @@ public class TestQueryStats DataSize.ofBytes(24), DataSize.ofBytes(25), DataSize.ofBytes(26), + DataSize.ofBytes(27), true, - new Duration(20, NANOSECONDS), - new Duration(21, NANOSECONDS), - new Duration(23, NANOSECONDS), + new Duration(28, NANOSECONDS), + new Duration(29, NANOSECONDS), + new Duration(30, NANOSECONDS), + new Duration(31, NANOSECONDS), + new Duration(32, NANOSECONDS), false, ImmutableSet.of(), DataSize.ofBytes(241), + DataSize.ofBytes(242), 251, - new Duration(23, NANOSECONDS), + 252, + new Duration(33, NANOSECONDS), + new Duration(34, NANOSECONDS), DataSize.ofBytes(242), - 252, + DataSize.ofBytes(243), + 253, + 254, - DataSize.ofBytes(24), - 25, + DataSize.ofBytes(35), + DataSize.ofBytes(36), + 37, + 38, - DataSize.ofBytes(26), - 27, + DataSize.ofBytes(39), + DataSize.ofBytes(40), + 41, + 42, - DataSize.ofBytes(28), - 29, + DataSize.ofBytes(43), + DataSize.ofBytes(44), + 45, + 46, - DataSize.ofBytes(30), + DataSize.ofBytes(47), + DataSize.ofBytes(48), ImmutableList.of(new StageGcStatistics( 101, @@ -262,45 +278,62 @@ public static void assertExpectedQueryStats(QueryStats actual) assertEquals(actual.getTotalTasks(), 9); assertEquals(actual.getRunningTasks(), 10); assertEquals(actual.getCompletedTasks(), 11); + assertEquals(actual.getFailedTasks(), 12); - assertEquals(actual.getTotalDrivers(), 12); - assertEquals(actual.getQueuedDrivers(), 13); + assertEquals(actual.getTotalDrivers(), 13); + assertEquals(actual.getQueuedDrivers(), 14); assertEquals(actual.getRunningDrivers(), 15); assertEquals(actual.getBlockedDrivers(), 30); assertEquals(actual.getCompletedDrivers(), 16); assertEquals(actual.getCumulativeUserMemory(), 17.0); - assertEquals(actual.getUserMemoryReservation(), DataSize.ofBytes(18)); - assertEquals(actual.getRevocableMemoryReservation(), DataSize.ofBytes(19)); - assertEquals(actual.getTotalMemoryReservation(), DataSize.ofBytes(20)); - assertEquals(actual.getPeakUserMemoryReservation(), DataSize.ofBytes(21)); - assertEquals(actual.getPeakRevocableMemoryReservation(), DataSize.ofBytes(22)); - assertEquals(actual.getPeakTotalMemoryReservation(), DataSize.ofBytes(23)); - assertEquals(actual.getPeakTaskUserMemory(), DataSize.ofBytes(24)); - assertEquals(actual.getPeakTaskRevocableMemory(), DataSize.ofBytes(25)); - assertEquals(actual.getPeakTaskTotalMemory(), DataSize.ofBytes(26)); + assertEquals(actual.getFailedCumulativeUserMemory(), 18.0); + assertEquals(actual.getUserMemoryReservation(), DataSize.ofBytes(19)); + assertEquals(actual.getRevocableMemoryReservation(), DataSize.ofBytes(20)); + assertEquals(actual.getTotalMemoryReservation(), DataSize.ofBytes(21)); + assertEquals(actual.getPeakUserMemoryReservation(), DataSize.ofBytes(22)); + assertEquals(actual.getPeakRevocableMemoryReservation(), DataSize.ofBytes(23)); + assertEquals(actual.getPeakTotalMemoryReservation(), DataSize.ofBytes(24)); + assertEquals(actual.getPeakTaskUserMemory(), DataSize.ofBytes(25)); + assertEquals(actual.getPeakTaskRevocableMemory(), DataSize.ofBytes(26)); + assertEquals(actual.getPeakTaskTotalMemory(), DataSize.ofBytes(27)); assertEquals(actual.getSpilledDataSize(), DataSize.ofBytes(693)); - assertEquals(actual.getTotalScheduledTime(), new Duration(20, NANOSECONDS)); - assertEquals(actual.getTotalCpuTime(), new Duration(21, NANOSECONDS)); - assertEquals(actual.getTotalBlockedTime(), new Duration(23, NANOSECONDS)); + assertEquals(actual.getTotalScheduledTime(), new Duration(28, NANOSECONDS)); + assertEquals(actual.getFailedScheduledTime(), new Duration(29, NANOSECONDS)); + assertEquals(actual.getTotalCpuTime(), new Duration(30, NANOSECONDS)); + assertEquals(actual.getFailedCpuTime(), new Duration(31, NANOSECONDS)); + assertEquals(actual.getTotalBlockedTime(), new Duration(32, NANOSECONDS)); assertEquals(actual.getPhysicalInputDataSize(), DataSize.ofBytes(241)); + assertEquals(actual.getFailedPhysicalInputDataSize(), DataSize.ofBytes(242)); assertEquals(actual.getPhysicalInputPositions(), 251); + assertEquals(actual.getFailedPhysicalInputPositions(), 252); + assertEquals(actual.getPhysicalInputReadTime(), new Duration(33, NANOSECONDS)); + assertEquals(actual.getFailedPhysicalInputReadTime(), new Duration(34, NANOSECONDS)); assertEquals(actual.getInternalNetworkInputDataSize(), DataSize.ofBytes(242)); - assertEquals(actual.getInternalNetworkInputPositions(), 252); - - assertEquals(actual.getRawInputDataSize(), DataSize.ofBytes(24)); - assertEquals(actual.getRawInputPositions(), 25); - - assertEquals(actual.getProcessedInputDataSize(), DataSize.ofBytes(26)); - assertEquals(actual.getProcessedInputPositions(), 27); - - assertEquals(actual.getOutputDataSize(), DataSize.ofBytes(28)); - assertEquals(actual.getOutputPositions(), 29); - - assertEquals(actual.getPhysicalWrittenDataSize(), DataSize.ofBytes(30)); + assertEquals(actual.getFailedInternalNetworkInputDataSize(), DataSize.ofBytes(243)); + assertEquals(actual.getInternalNetworkInputPositions(), 253); + assertEquals(actual.getFailedInternalNetworkInputPositions(), 254); + + assertEquals(actual.getRawInputDataSize(), DataSize.ofBytes(35)); + assertEquals(actual.getFailedRawInputDataSize(), DataSize.ofBytes(36)); + assertEquals(actual.getRawInputPositions(), 37); + assertEquals(actual.getFailedRawInputPositions(), 38); + + assertEquals(actual.getProcessedInputDataSize(), DataSize.ofBytes(39)); + assertEquals(actual.getFailedProcessedInputDataSize(), DataSize.ofBytes(40)); + assertEquals(actual.getProcessedInputPositions(), 41); + assertEquals(actual.getFailedProcessedInputPositions(), 42); + + assertEquals(actual.getOutputDataSize(), DataSize.ofBytes(43)); + assertEquals(actual.getFailedOutputDataSize(), DataSize.ofBytes(44)); + assertEquals(actual.getOutputPositions(), 45); + assertEquals(actual.getFailedOutputPositions(), 46); + + assertEquals(actual.getPhysicalWrittenDataSize(), DataSize.ofBytes(47)); + assertEquals(actual.getFailedPhysicalWrittenDataSize(), DataSize.ofBytes(48)); assertEquals(actual.getStageGcStatistics().size(), 1); StageGcStatistics gcStatistics = actual.getStageGcStatistics().get(0); diff --git a/core/trino-main/src/test/java/io/trino/execution/TestStageStats.java b/core/trino-main/src/test/java/io/trino/execution/TestStageStats.java index d727f388bc9a..1788465ba251 100644 --- a/core/trino-main/src/test/java/io/trino/execution/TestStageStats.java +++ b/core/trino-main/src/test/java/io/trino/execution/TestStageStats.java @@ -46,36 +46,51 @@ public class TestStageStats 11, 12.0, - DataSize.ofBytes(13), + 13.0, DataSize.ofBytes(14), DataSize.ofBytes(15), DataSize.ofBytes(16), DataSize.ofBytes(17), + DataSize.ofBytes(18), - new Duration(15, NANOSECONDS), - new Duration(16, NANOSECONDS), - new Duration(18, NANOSECONDS), + new Duration(19, NANOSECONDS), + new Duration(20, NANOSECONDS), + new Duration(21, NANOSECONDS), + new Duration(22, NANOSECONDS), + new Duration(23, NANOSECONDS), false, ImmutableSet.of(), DataSize.ofBytes(191), - 201, - new Duration(15, NANOSECONDS), - DataSize.ofBytes(192), + 201, 202, + new Duration(24, NANOSECONDS), + new Duration(25, NANOSECONDS), - DataSize.ofBytes(19), - 20, + DataSize.ofBytes(193), + DataSize.ofBytes(194), + 203, + 204, - DataSize.ofBytes(21), - 22, + DataSize.ofBytes(26), + DataSize.ofBytes(27), + 28, + 29, - DataSize.ofBytes(23), - DataSize.ofBytes(24), - 25, + DataSize.ofBytes(30), + DataSize.ofBytes(31), + 32, + 33, - DataSize.ofBytes(26), + DataSize.ofBytes(34), + DataSize.ofBytes(35), + DataSize.ofBytes(36), + 37, + 38, + + DataSize.ofBytes(39), + DataSize.ofBytes(40), new StageGcStatistics( 101, @@ -117,34 +132,49 @@ private static void assertExpectedStageStats(StageStats actual) assertEquals(actual.getCompletedDrivers(), 11); assertEquals(actual.getCumulativeUserMemory(), 12.0); - assertEquals(actual.getUserMemoryReservation(), DataSize.ofBytes(13)); - assertEquals(actual.getRevocableMemoryReservation(), DataSize.ofBytes(14)); - assertEquals(actual.getTotalMemoryReservation(), DataSize.ofBytes(15)); - assertEquals(actual.getPeakUserMemoryReservation(), DataSize.ofBytes(16)); - assertEquals(actual.getPeakRevocableMemoryReservation(), DataSize.ofBytes(17)); - - assertEquals(actual.getTotalScheduledTime(), new Duration(15, NANOSECONDS)); - assertEquals(actual.getTotalCpuTime(), new Duration(16, NANOSECONDS)); - assertEquals(actual.getTotalBlockedTime(), new Duration(18, NANOSECONDS)); + assertEquals(actual.getFailedCumulativeUserMemory(), 13.0); + assertEquals(actual.getUserMemoryReservation(), DataSize.ofBytes(14)); + assertEquals(actual.getRevocableMemoryReservation(), DataSize.ofBytes(15)); + assertEquals(actual.getTotalMemoryReservation(), DataSize.ofBytes(16)); + assertEquals(actual.getPeakUserMemoryReservation(), DataSize.ofBytes(17)); + assertEquals(actual.getPeakRevocableMemoryReservation(), DataSize.ofBytes(18)); + + assertEquals(actual.getTotalScheduledTime(), new Duration(19, NANOSECONDS)); + assertEquals(actual.getFailedScheduledTime(), new Duration(20, NANOSECONDS)); + assertEquals(actual.getTotalCpuTime(), new Duration(21, NANOSECONDS)); + assertEquals(actual.getFailedCpuTime(), new Duration(22, NANOSECONDS)); + assertEquals(actual.getTotalBlockedTime(), new Duration(23, NANOSECONDS)); assertEquals(actual.getPhysicalInputDataSize(), DataSize.ofBytes(191)); + assertEquals(actual.getFailedPhysicalInputDataSize(), DataSize.ofBytes(192)); assertEquals(actual.getPhysicalInputPositions(), 201); - assertEquals(actual.getPhysicalInputReadTime(), new Duration(15, NANOSECONDS)); - - assertEquals(actual.getInternalNetworkInputDataSize(), DataSize.ofBytes(192)); - assertEquals(actual.getInternalNetworkInputPositions(), 202); - - assertEquals(actual.getRawInputDataSize(), DataSize.ofBytes(19)); - assertEquals(actual.getRawInputPositions(), 20); - - assertEquals(actual.getProcessedInputDataSize(), DataSize.ofBytes(21)); - assertEquals(actual.getProcessedInputPositions(), 22); - - assertEquals(actual.getBufferedDataSize(), DataSize.ofBytes(23)); - assertEquals(actual.getOutputDataSize(), DataSize.ofBytes(24)); - assertEquals(actual.getOutputPositions(), 25); - - assertEquals(actual.getPhysicalWrittenDataSize(), DataSize.ofBytes(26)); + assertEquals(actual.getFailedPhysicalInputPositions(), 202); + assertEquals(actual.getPhysicalInputReadTime(), new Duration(24, NANOSECONDS)); + assertEquals(actual.getFailedPhysicalInputReadTime(), new Duration(25, NANOSECONDS)); + + assertEquals(actual.getInternalNetworkInputDataSize(), DataSize.ofBytes(193)); + assertEquals(actual.getFailedInternalNetworkInputDataSize(), DataSize.ofBytes(194)); + assertEquals(actual.getInternalNetworkInputPositions(), 203); + assertEquals(actual.getFailedInternalNetworkInputPositions(), 204); + + assertEquals(actual.getRawInputDataSize(), DataSize.ofBytes(26)); + assertEquals(actual.getFailedRawInputDataSize(), DataSize.ofBytes(27)); + assertEquals(actual.getRawInputPositions(), 28); + assertEquals(actual.getFailedRawInputPositions(), 29); + + assertEquals(actual.getProcessedInputDataSize(), DataSize.ofBytes(30)); + assertEquals(actual.getFailedProcessedInputDataSize(), DataSize.ofBytes(31)); + assertEquals(actual.getProcessedInputPositions(), 32); + assertEquals(actual.getFailedProcessedInputPositions(), 33); + + assertEquals(actual.getBufferedDataSize(), DataSize.ofBytes(34)); + assertEquals(actual.getOutputDataSize(), DataSize.ofBytes(35)); + assertEquals(actual.getFailedOutputDataSize(), DataSize.ofBytes(36)); + assertEquals(actual.getOutputPositions(), 37); + assertEquals(actual.getFailedOutputPositions(), 38); + + assertEquals(actual.getPhysicalWrittenDataSize(), DataSize.ofBytes(39)); + assertEquals(actual.getFailedPhysicalWrittenDataSize(), DataSize.ofBytes(40)); assertEquals(actual.getGcInfo().getStageId(), 101); assertEquals(actual.getGcInfo().getTasks(), 102); diff --git a/core/trino-main/src/test/java/io/trino/server/TestBasicQueryInfo.java b/core/trino-main/src/test/java/io/trino/server/TestBasicQueryInfo.java index 72eee365a042..722718ec29e2 100644 --- a/core/trino-main/src/test/java/io/trino/server/TestBasicQueryInfo.java +++ b/core/trino-main/src/test/java/io/trino/server/TestBasicQueryInfo.java @@ -73,11 +73,11 @@ public void testConstructor() 16, 17, 18, - 34, 19, - 20.0, - DataSize.valueOf("21GB"), - DataSize.valueOf("22GB"), + 34, + 20, + 21.0, + 22.0, DataSize.valueOf("23GB"), DataSize.valueOf("24GB"), DataSize.valueOf("25GB"), @@ -85,24 +85,40 @@ public void testConstructor() DataSize.valueOf("27GB"), DataSize.valueOf("28GB"), DataSize.valueOf("29GB"), + DataSize.valueOf("30GB"), + DataSize.valueOf("31GB"), true, - new Duration(23, MINUTES), - new Duration(24, MINUTES), - new Duration(26, MINUTES), + new Duration(32, MINUTES), + new Duration(33, MINUTES), + new Duration(34, MINUTES), + new Duration(35, MINUTES), + new Duration(36, MINUTES), true, ImmutableSet.of(BlockedReason.WAITING_FOR_MEMORY), DataSize.valueOf("271GB"), + DataSize.valueOf("271GB"), + 281, 281, - new Duration(20, MINUTES), + new Duration(37, MINUTES), + new Duration(38, MINUTES), + DataSize.valueOf("272GB"), DataSize.valueOf("272GB"), 282, - DataSize.valueOf("27GB"), - 28, - DataSize.valueOf("29GB"), - 30, - DataSize.valueOf("31GB"), - 32, - DataSize.valueOf("32GB"), + 282, + DataSize.valueOf("39GB"), + DataSize.valueOf("40GB"), + 41, + 42, + DataSize.valueOf("43GB"), + DataSize.valueOf("44GB"), + 45, + 46, + DataSize.valueOf("47GB"), + DataSize.valueOf("48GB"), + 49, + 50, + DataSize.valueOf("51GB"), + DataSize.valueOf("52GB"), ImmutableList.of(new StageGcStatistics( 101, 102, @@ -147,16 +163,20 @@ public void testConstructor() assertEquals(basicInfo.getQueryStats().getElapsedTime(), new Duration(8, MINUTES)); assertEquals(basicInfo.getQueryStats().getExecutionTime(), new Duration(44, MINUTES)); - assertEquals(basicInfo.getQueryStats().getTotalDrivers(), 16); - assertEquals(basicInfo.getQueryStats().getQueuedDrivers(), 17); - assertEquals(basicInfo.getQueryStats().getRunningDrivers(), 18); - assertEquals(basicInfo.getQueryStats().getCompletedDrivers(), 19); + assertEquals(basicInfo.getQueryStats().getTotalDrivers(), 17); + assertEquals(basicInfo.getQueryStats().getQueuedDrivers(), 18); + assertEquals(basicInfo.getQueryStats().getRunningDrivers(), 19); + assertEquals(basicInfo.getQueryStats().getCompletedDrivers(), 20); - assertEquals(basicInfo.getQueryStats().getCumulativeUserMemory(), 20.0); - assertEquals(basicInfo.getQueryStats().getUserMemoryReservation(), DataSize.valueOf("21GB")); - assertEquals(basicInfo.getQueryStats().getTotalMemoryReservation(), DataSize.valueOf("23GB")); - assertEquals(basicInfo.getQueryStats().getPeakUserMemoryReservation(), DataSize.valueOf("24GB")); - assertEquals(basicInfo.getQueryStats().getTotalCpuTime(), new Duration(24, MINUTES)); + assertEquals(basicInfo.getQueryStats().getCumulativeUserMemory(), 21.0); + assertEquals(basicInfo.getQueryStats().getFailedCumulativeUserMemory(), 22.0); + assertEquals(basicInfo.getQueryStats().getUserMemoryReservation(), DataSize.valueOf("23GB")); + assertEquals(basicInfo.getQueryStats().getTotalMemoryReservation(), DataSize.valueOf("25GB")); + assertEquals(basicInfo.getQueryStats().getPeakUserMemoryReservation(), DataSize.valueOf("26GB")); + assertEquals(basicInfo.getQueryStats().getTotalScheduledTime(), new Duration(32, MINUTES)); + assertEquals(basicInfo.getQueryStats().getFailedScheduledTime(), new Duration(33, MINUTES)); + assertEquals(basicInfo.getQueryStats().getTotalCpuTime(), new Duration(34, MINUTES)); + assertEquals(basicInfo.getQueryStats().getFailedCpuTime(), new Duration(35, MINUTES)); assertEquals(basicInfo.getQueryStats().isFullyBlocked(), true); assertEquals(basicInfo.getQueryStats().getBlockedReasons(), ImmutableSet.of(BlockedReason.WAITING_FOR_MEMORY)); diff --git a/core/trino-main/src/test/java/io/trino/server/TestQueryStateInfo.java b/core/trino-main/src/test/java/io/trino/server/TestQueryStateInfo.java index 9d83b5791875..93ef714f3f51 100644 --- a/core/trino-main/src/test/java/io/trino/server/TestQueryStateInfo.java +++ b/core/trino-main/src/test/java/io/trino/server/TestQueryStateInfo.java @@ -121,12 +121,14 @@ private QueryInfo createQueryInfo(String queryId, QueryState state, String query 13, 14, 15, + 16, 100, 17, 18, 34, 19, 20.0, + 21.0, DataSize.valueOf("21GB"), DataSize.valueOf("22GB"), DataSize.valueOf("23GB"), @@ -139,21 +141,35 @@ private QueryInfo createQueryInfo(String queryId, QueryState state, String query true, new Duration(23, MINUTES), new Duration(24, MINUTES), + new Duration(25, MINUTES), new Duration(26, MINUTES), + new Duration(27, MINUTES), true, ImmutableSet.of(WAITING_FOR_MEMORY), DataSize.valueOf("271GB"), - 281, - new Duration(26, MINUTES), DataSize.valueOf("272GB"), + 281, 282, - DataSize.valueOf("27GB"), - 28, + new Duration(28, MINUTES), + new Duration(29, MINUTES), + DataSize.valueOf("273GB"), + DataSize.valueOf("274GB"), + 283, + 284, + DataSize.valueOf("28GB"), DataSize.valueOf("29GB"), 30, - DataSize.valueOf("31GB"), - 32, + 31, + DataSize.valueOf("32GB"), DataSize.valueOf("33GB"), + 34, + 35, + DataSize.valueOf("36GB"), + DataSize.valueOf("37GB"), + 38, + 39, + DataSize.valueOf("40GB"), + DataSize.valueOf("41GB"), ImmutableList.of(), DynamicFiltersStats.EMPTY, ImmutableList.of()), @@ -167,7 +183,7 @@ private QueryInfo createQueryInfo(String queryId, QueryState state, String query ImmutableSet.of(), Optional.empty(), false, - "33", + "42", Optional.empty(), null, null, diff --git a/core/trino-spi/src/main/java/io/trino/spi/eventlistener/QueryStatistics.java b/core/trino-spi/src/main/java/io/trino/spi/eventlistener/QueryStatistics.java index aaa3d393df63..11ae32c181be 100644 --- a/core/trino-spi/src/main/java/io/trino/spi/eventlistener/QueryStatistics.java +++ b/core/trino-spi/src/main/java/io/trino/spi/eventlistener/QueryStatistics.java @@ -28,9 +28,11 @@ public class QueryStatistics { private final Duration cpuTime; + private final Duration failedCpuTime; private final Duration wallTime; private final Duration queuedTime; private final Optional scheduledTime; + private final Optional failedScheduledTime; private final Optional waitingTime; private final Optional analysisTime; private final Optional planningTime; @@ -51,6 +53,7 @@ public class QueryStatistics private final long writtenRows; private final double cumulativeMemory; + private final double failedCumulativeMemory; private final List stageGcStatistics; @@ -73,9 +76,11 @@ public class QueryStatistics @JsonCreator public QueryStatistics( Duration cpuTime, + Duration failedCpuTime, Duration wallTime, Duration queuedTime, Optional scheduledTime, + Optional failedScheduledTime, Optional waitingTime, Optional analysisTime, Optional planningTime, @@ -94,6 +99,7 @@ public QueryStatistics( long writtenBytes, long writtenRows, double cumulativeMemory, + double failedCumulativeMemory, List stageGcStatistics, int completedSplits, boolean complete, @@ -102,9 +108,11 @@ public QueryStatistics( Optional planNodeStatsAndCosts) { this.cpuTime = requireNonNull(cpuTime, "cpuTime is null"); + this.failedCpuTime = requireNonNull(failedCpuTime, "failedCpuTime is null"); this.wallTime = requireNonNull(wallTime, "wallTime is null"); this.queuedTime = requireNonNull(queuedTime, "queuedTime is null"); this.scheduledTime = requireNonNull(scheduledTime, "scheduledTime is null"); + this.failedScheduledTime = requireNonNull(failedScheduledTime, "failedScheduledTime is null"); this.waitingTime = requireNonNull(waitingTime, "waitingTime is null"); this.analysisTime = requireNonNull(analysisTime, "analysisTime is null"); this.planningTime = requireNonNull(planningTime, "planningTime is null"); @@ -123,6 +131,7 @@ public QueryStatistics( this.writtenBytes = writtenBytes; this.writtenRows = writtenRows; this.cumulativeMemory = cumulativeMemory; + this.failedCumulativeMemory = failedCumulativeMemory; this.stageGcStatistics = requireNonNull(stageGcStatistics, "stageGcStatistics is null"); this.completedSplits = completedSplits; this.complete = complete; @@ -137,6 +146,12 @@ public Duration getCpuTime() return cpuTime; } + @JsonProperty + public Duration getFailedCpuTime() + { + return failedCpuTime; + } + @JsonProperty public Duration getWallTime() { @@ -155,6 +170,12 @@ public Optional getScheduledTime() return scheduledTime; } + @JsonProperty + public Optional getFailedScheduledTime() + { + return failedScheduledTime; + } + @JsonProperty public Optional getResourceWaitingTime() { @@ -263,6 +284,12 @@ public double getCumulativeMemory() return cumulativeMemory; } + @JsonProperty + public double getFailedCumulativeMemory() + { + return failedCumulativeMemory; + } + @JsonProperty public List getStageGcStatistics() { diff --git a/plugin/trino-http-event-listener/src/test/java/io/trino/plugin/httpquery/TestHttpEventListener.java b/plugin/trino-http-event-listener/src/test/java/io/trino/plugin/httpquery/TestHttpEventListener.java index a2ac353ec6d3..b3493568ae2e 100644 --- a/plugin/trino-http-event-listener/src/test/java/io/trino/plugin/httpquery/TestHttpEventListener.java +++ b/plugin/trino-http-event-listener/src/test/java/io/trino/plugin/httpquery/TestHttpEventListener.java @@ -143,6 +143,8 @@ public class TestHttpEventListener ofMillis(1000), ofMillis(1000), ofMillis(1000), + ofMillis(1000), + Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), @@ -161,6 +163,7 @@ public class TestHttpEventListener 0L, 0L, 0L, + 0L, 0.0f, Collections.emptyList(), 0, diff --git a/testing/trino-tests/src/test/java/io/trino/memory/TestClusterMemoryLeakDetector.java b/testing/trino-tests/src/test/java/io/trino/memory/TestClusterMemoryLeakDetector.java index 4602b89cdae7..e03c47bfc0d3 100644 --- a/testing/trino-tests/src/test/java/io/trino/memory/TestClusterMemoryLeakDetector.java +++ b/testing/trino-tests/src/test/java/io/trino/memory/TestClusterMemoryLeakDetector.java @@ -89,14 +89,17 @@ private static BasicQueryInfo createQueryInfo(String queryId, QueryState state) 100, DataSize.valueOf("21GB"), 22, - DataSize.valueOf("20GB"), - 23, DataSize.valueOf("23GB"), - DataSize.valueOf("24GB"), - DataSize.valueOf("25GB"), + 24, + 25, DataSize.valueOf("26GB"), - new Duration(23, MINUTES), - new Duration(24, MINUTES), + DataSize.valueOf("27GB"), + DataSize.valueOf("28GB"), + DataSize.valueOf("29GB"), + new Duration(30, MINUTES), + new Duration(31, MINUTES), + new Duration(32, MINUTES), + new Duration(33, MINUTES), true, ImmutableSet.of(WAITING_FOR_MEMORY), OptionalDouble.of(20)),