Skip to content

Commit 43175cd

Browse files
author
Andrew Or
committed
Handle removed jobs and stages gracefully
1 parent 5db18ba commit 43175cd

File tree

3 files changed

+25
-8
lines changed

3 files changed

+25
-8
lines changed

core/src/main/resources/org/apache/spark/ui/static/spark-dag-viz.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
stroke-width: 1px;
4545
}
4646

47+
#dag-viz-graph div#empty-dag-viz-message {
48+
margin: 15px;
49+
}
50+
4751
/* Job page specific styles */
4852

4953
#dag-viz-graph svg.job marker#marker-arrow path {

core/src/main/resources/org/apache/spark/ui/static/spark-dag-viz.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function toggleDagViz(forJob) {
8686
$(arrowSelector).toggleClass('arrow-open');
8787
var shouldShow = $(arrowSelector).hasClass("arrow-open");
8888
if (shouldShow) {
89-
var shouldRender = graphContainer().select("svg").empty();
89+
var shouldRender = graphContainer().select("*").empty();
9090
if (shouldRender) {
9191
renderDagViz(forJob);
9292
}
@@ -117,10 +117,18 @@ function renderDagViz(forJob) {
117117

118118
// If there is not a dot file to render, fail fast and report error
119119
var jobOrStage = forJob ? "job" : "stage";
120-
if (metadataContainer().empty()) {
121-
graphContainer()
122-
.append("div")
123-
.text("No visualization information available for this " + jobOrStage);
120+
if (metadataContainer().empty() ||
121+
metadataContainer().selectAll("div").empty()) {
122+
var message =
123+
"<b>No visualization information available for this " + jobOrStage + "!</b><br/>" +
124+
"If this is an old " + jobOrStage + ", its visualization metadata may have been " +
125+
"cleaned up over time.<br/> You may consider increasing the value of ";
126+
if (forJob) {
127+
message += "<i>spark.ui.retainedJobs</i> and <i>spark.ui.retainedStages</i>.";
128+
} else {
129+
message += "<i>spark.ui.retainedStages</i>";
130+
}
131+
graphContainer().append("div").attr("id", "empty-dag-viz-message").html(message);
124132
return;
125133
}
126134

core/src/main/scala/org/apache/spark/ui/scope/RDDOperationGraphListener.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,14 @@ private[ui] class RDDOperationGraphListener(conf: SparkConf) extends SparkListen
3737

3838
/** Return the graph metadata for the given stage, or None if no such information exists. */
3939
def getOperationGraphForJob(jobId: Int): Seq[RDDOperationGraph] = {
40-
jobIdToStageIds.get(jobId)
41-
.map { sids => sids.flatMap { sid => stageIdToGraph.get(sid) } }
42-
.getOrElse { Seq.empty }
40+
val stageIds = jobIdToStageIds.get(jobId).getOrElse { Seq.empty }
41+
val graphs = stageIds.flatMap { sid => stageIdToGraph.get(sid) }
42+
// If the metadata for some stages have been removed, do not bother rendering this job
43+
if (stageIds.size != graphs.size) {
44+
Seq.empty
45+
} else {
46+
graphs
47+
}
4348
}
4449

4550
/** Return the graph metadata for the given stage, or None if no such information exists. */

0 commit comments

Comments
 (0)