aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorKay Ousterhout <kayousterhout@gmail.com>2015-05-15 17:45:14 -0700
committerKay Ousterhout <kayousterhout@gmail.com>2015-05-15 17:45:14 -0700
commite74545647684b3047248ca3cfee894ac5378dead (patch)
treee49d7b37c311ac8aca915e5935c2b9262d651449 /core
parentc8696337e2a5878f3171eb574c0a1365d45814c9 (diff)
downloadspark-e74545647684b3047248ca3cfee894ac5378dead.tar.gz
spark-e74545647684b3047248ca3cfee894ac5378dead.tar.bz2
spark-e74545647684b3047248ca3cfee894ac5378dead.zip
[SPARK-7676] Bug fix and cleanup of stage timeline view
cc pwendell sarutak This commit cleans up some unnecessary code, eliminates the feature where when you mouse-over a box in the timeline, the corresponding task is highlighted in the table (because that feature is only useful in the rare case when you have a very small number of tasks, in which case it's easy to figure out the mapping anyway), and fixes a bug where nothing shows up if you try to visualize a stage with only 1 task. Author: Kay Ousterhout <kayousterhout@gmail.com> Closes #6202 from kayousterhout/SPARK-7676 and squashes the following commits: dfd29d4 [Kay Ousterhout] [SPARK-7676] Bug fix and cleanup of stage timeline view
Diffstat (limited to 'core')
-rw-r--r--core/src/main/resources/org/apache/spark/ui/static/timeline-view.js48
-rw-r--r--core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala19
2 files changed, 20 insertions, 47 deletions
diff --git a/core/src/main/resources/org/apache/spark/ui/static/timeline-view.js b/core/src/main/resources/org/apache/spark/ui/static/timeline-view.js
index e1150359bc..604c299941 100644
--- a/core/src/main/resources/org/apache/spark/ui/static/timeline-view.js
+++ b/core/src/main/resources/org/apache/spark/ui/static/timeline-view.js
@@ -133,7 +133,7 @@ function drawJobTimeline(groupArray, eventObjArray, startTime) {
});
}
-function drawTaskAssignmentTimeline(groupArray, eventObjArray, minLaunchTime, zoomMax) {
+function drawTaskAssignmentTimeline(groupArray, eventObjArray, minLaunchTime, maxFinishTime) {
var groups = new vis.DataSet(groupArray);
var items = new vis.DataSet(eventObjArray);
var container = $("#task-assignment-timeline")[0]
@@ -146,8 +146,8 @@ function drawTaskAssignmentTimeline(groupArray, eventObjArray, minLaunchTime, zo
selectable: false,
showCurrentTime: false,
min: minLaunchTime,
- zoomable: false,
- zoomMax: zoomMax
+ max: maxFinishTime,
+ zoomable: false
};
var taskTimeline = new vis.Timeline(container)
@@ -155,48 +155,32 @@ function drawTaskAssignmentTimeline(groupArray, eventObjArray, minLaunchTime, zo
taskTimeline.setGroups(groups);
taskTimeline.setItems(items);
- taskTimeline.on("rangechange", function(prop) {
- if (currentDisplayedTooltip !== null) {
- $(currentDisplayedTooltip).tooltip("hide");
- }
- });
-
- function getTaskIdxAndAttempt(selector) {
- var taskIdxText = $(selector).attr("data-title");
- var taskIdxAndAttempt = taskIdxText.match("Task (\\d+) \\(attempt (\\d+)");
- var taskIdx = taskIdxAndAttempt[1];
- var taskAttempt = taskIdxAndAttempt[2];
- return taskIdx + "-" + taskAttempt;
- }
-
- // If we zoom up and a box moves away when the corresponding tooltip is shown,
- // the tooltip can be remain.
- // So, we need to hide tooltips using another mechanism.
+ // If a user zooms while a tooltip is displayed, the user may zoom such that the cursor is no
+ // longer over the task that the tooltip corresponds to. So, when a user zooms, we should hide
+ // any currently displayed tooltips.
var currentDisplayedTooltip = null;
-
$("#task-assignment-timeline").on({
"mouseenter": function() {
- var taskIdxAndAttempt = getTaskIdxAndAttempt(this);
- $("#task-" + taskIdxAndAttempt).addClass("corresponding-item-hover");
- $(this).tooltip("show");
currentDisplayedTooltip = this;
},
- "mouseleave" : function() {
- var taskIdxAndAttempt = getTaskIdxAndAttempt(this);
- $("#task-" + taskIdxAndAttempt).removeClass("corresponding-item-hover");
- $(this).tooltip("hide");
+ "mouseleave": function() {
currentDisplayedTooltip = null;
}
}, ".task-assignment-timeline-content");
+ taskTimeline.on("rangechange", function(prop) {
+ if (currentDisplayedTooltip !== null) {
+ $(currentDisplayedTooltip).tooltip("hide");
+ }
+ });
- setupZoomable('#task-assignment-timeline-zoom-lock', taskTimeline);
+ setupZoomable("#task-assignment-timeline-zoom-lock", taskTimeline);
$("span.expand-task-assignment-timeline").click(function() {
- $("#task-assignment-timeline").toggleClass('collapsed');
+ $("#task-assignment-timeline").toggleClass("collapsed");
// Switch the class of the arrow from open to closed.
- $(this).find('.expand-task-assignment-timeline-arrow').toggleClass('arrow-open');
- $(this).find('.expand-task-assignment-timeline-arrow').toggleClass('arrow-closed');
+ $(this).find(".expand-task-assignment-timeline-arrow").toggleClass("arrow-open");
+ $(this).find(".expand-task-assignment-timeline-arrow").toggleClass("arrow-closed");
});
}
diff --git a/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala b/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
index 1a75ea6250..31e2e7fba9 100644
--- a/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
+++ b/core/src/main/scala/org/apache/spark/ui/jobs/StagePage.scala
@@ -521,21 +521,11 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
val host = taskInfo.host
executorsSet += ((executorId, host))
- val classNameByStatus = {
- if (taskInfo.successful) {
- "succeeded"
- } else if (taskInfo.failed) {
- "failed"
- } else if (taskInfo.running) {
- "running"
- }
- }
-
val launchTime = taskInfo.launchTime
val finishTime = if (!taskInfo.running) taskInfo.finishTime else currentTime
val totalExecutionTime = finishTime - launchTime
minLaunchTime = launchTime.min(minLaunchTime)
- maxFinishTime = launchTime.max(maxFinishTime)
+ maxFinishTime = finishTime.max(maxFinishTime)
def toProportion(time: Long) = (time.toDouble / totalExecutionTime * 100).toLong
@@ -583,7 +573,7 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
val timelineObject =
s"""
{
- 'className': 'task task-assignment-timeline-object $classNameByStatus',
+ 'className': 'task task-assignment-timeline-object',
'group': '$executorId',
'content': '<div class="task-assignment-timeline-content"' +
'data-toggle="tooltip" data-placement="top"' +
@@ -644,7 +634,6 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
"""
}.mkString("[", ",", "]")
- val maxZoom = maxFinishTime - minLaunchTime
<span class="expand-task-assignment-timeline">
<span class="expand-task-assignment-timeline-arrow arrow-closed"></span>
<a>Event Timeline</a>
@@ -671,7 +660,7 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
</div> ++
<script type="text/javascript">
{Unparsed(s"drawTaskAssignmentTimeline(" +
- s"$groupArrayStr, $executorsArrayStr, $minLaunchTime, $maxZoom)")}
+ s"$groupArrayStr, $executorsArrayStr, $minLaunchTime, $maxFinishTime)")}
</script>
}
@@ -748,7 +737,7 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
val diskBytesSpilledSortable = maybeDiskBytesSpilled.map(_.toString).getOrElse("")
val diskBytesSpilledReadable = maybeDiskBytesSpilled.map(Utils.bytesToString).getOrElse("")
- <tr id={"task-" + info.index + "-" + info.attempt}>
+ <tr>
<td>{info.index}</td>
<td>{info.taskId}</td>
<td sorttable_customkey={info.attempt.toString}>{