Skip to content

Commit 04f04e0

Browse files
sarutakgengliangwang
authored andcommitted
[SPARK-31420][WEBUI] Infinite timeline redraw in job details page
### What changes were proposed in this pull request? Upgrade vis.js to fix an infinite re-drawing issue. As reported here, old releases of vis.js have that issue. Fortunately, the latest version seems to resolve the issue. With the latest release of vis.js, there are some performance issues with the original `timeline-view.js` and `timeline-view.css` so I also changed them. ### Why are the changes needed? For better UX. ### Does this PR introduce any user-facing change? No. Appearance and functionalities are not changed. ### How was this patch tested? I confirmed infinite redrawing doesn't happen with a JobPage which I had reproduced the issue. With the original version of vis.js, I reproduced the issue with the following conditions. * Use history server and load core/src/test/resources/spark-events. * Visit the JobPage for job2 in application_1553914137147_0018. * Zoom out to 80% on Safari / Chrome / Firefox. Maybe, it depends on OS and the version of browsers. Closes #28192 from sarutak/upgrade-visjs. Authored-by: Kousuke Saruta <sarutak@oss.nttdata.com> Signed-off-by: Gengliang Wang <gengliang.wang@databricks.com>
1 parent 5d4f5d3 commit 04f04e0

File tree

15 files changed

+140
-114
lines changed

15 files changed

+140
-114
lines changed

core/src/main/resources/org/apache/spark/ui/static/timeline-view.css

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -238,18 +238,6 @@ tr.corresponding-item-hover > td, tr.corresponding-item-hover > th {
238238
background-color: #D6FFE4 !important;
239239
}
240240

241-
#application-timeline.collapsed {
242-
display: none;
243-
}
244-
245-
#job-timeline.collapsed {
246-
display: none;
247-
}
248-
249-
#task-assignment-timeline.collapsed {
250-
display: none;
251-
}
252-
253241
.control-panel {
254242
margin-bottom: 5px;
255243
}

core/src/main/resources/org/apache/spark/ui/static/timeline-view.js

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function drawApplicationTimeline(groupArray, eventObjArray, startTime, offset) {
2626
editable: false,
2727
align: 'left',
2828
showCurrentTime: false,
29-
min: startTime,
29+
start: startTime,
3030
zoomable: false,
3131
moment: function (date) {
3232
return vis.moment(date).utcOffset(offset);
@@ -50,7 +50,7 @@ function drawApplicationTimeline(groupArray, eventObjArray, startTime, offset) {
5050
};
5151

5252
$(this).click(function() {
53-
var jobPagePath = $(getSelectorForJobEntry(this)).find("a.name-link").attr("href")
53+
var jobPagePath = $(getSelectorForJobEntry(this)).find("a.name-link").attr("href");
5454
window.location.href = jobPagePath
5555
});
5656

@@ -75,6 +75,9 @@ function drawApplicationTimeline(groupArray, eventObjArray, startTime, offset) {
7575

7676
$("#application-timeline").toggleClass('collapsed');
7777

78+
var visibilityState = status ? "" : "none";
79+
$("#application-timeline").css("display", visibilityState);
80+
7881
// Switch the class of the arrow from open to closed.
7982
$(this).find('.expand-application-timeline-arrow').toggleClass('arrow-open');
8083
$(this).find('.expand-application-timeline-arrow').toggleClass('arrow-closed');
@@ -89,6 +92,8 @@ $(function () {
8992
// Set it to false so that the click function can revert it
9093
window.localStorage.setItem("expand-application-timeline", "false");
9194
$("span.expand-application-timeline").trigger('click');
95+
} else {
96+
$("#application-timeline").css("display", "none");
9297
}
9398
});
9499

@@ -103,7 +108,7 @@ function drawJobTimeline(groupArray, eventObjArray, startTime, offset) {
103108
editable: false,
104109
align: 'left',
105110
showCurrentTime: false,
106-
min: startTime,
111+
start: startTime,
107112
zoomable: false,
108113
moment: function (date) {
109114
return vis.moment(date).utcOffset(offset);
@@ -152,6 +157,9 @@ function drawJobTimeline(groupArray, eventObjArray, startTime, offset) {
152157

153158
$("#job-timeline").toggleClass('collapsed');
154159

160+
var visibilityState = status ? "" : "none";
161+
$("#job-timeline").css("display", visibilityState);
162+
155163
// Switch the class of the arrow from open to closed.
156164
$(this).find('.expand-job-timeline-arrow').toggleClass('arrow-open');
157165
$(this).find('.expand-job-timeline-arrow').toggleClass('arrow-closed');
@@ -166,13 +174,15 @@ $(function () {
166174
// Set it to false so that the click function can revert it
167175
window.localStorage.setItem("expand-job-timeline", "false");
168176
$("span.expand-job-timeline").trigger('click');
177+
} else {
178+
$("#job-timeline").css("display", "none");
169179
}
170180
});
171181

172182
function drawTaskAssignmentTimeline(groupArray, eventObjArray, minLaunchTime, maxFinishTime, offset) {
173183
var groups = new vis.DataSet(groupArray);
174184
var items = new vis.DataSet(eventObjArray);
175-
var container = $("#task-assignment-timeline")[0]
185+
var container = $("#task-assignment-timeline")[0];
176186
var options = {
177187
groupOrder: function(a, b) {
178188
return a.value - b.value
@@ -181,15 +191,15 @@ function drawTaskAssignmentTimeline(groupArray, eventObjArray, minLaunchTime, ma
181191
align: 'left',
182192
selectable: false,
183193
showCurrentTime: false,
184-
min: minLaunchTime,
185-
max: maxFinishTime,
194+
start: minLaunchTime,
195+
end: maxFinishTime,
186196
zoomable: false,
187197
moment: function (date) {
188198
return vis.moment(date).utcOffset(offset);
189199
}
190200
};
191201

192-
var taskTimeline = new vis.Timeline(container)
202+
var taskTimeline = new vis.Timeline(container);
193203
taskTimeline.setOptions(options);
194204
taskTimeline.setGroups(groups);
195205
taskTimeline.setItems(items);
@@ -220,6 +230,9 @@ function drawTaskAssignmentTimeline(groupArray, eventObjArray, minLaunchTime, ma
220230

221231
$("#task-assignment-timeline").toggleClass("collapsed");
222232

233+
var visibilityState = status ? "" : "none";
234+
$("#task-assignment-timeline").css("display", visibilityState);
235+
223236
// Switch the class of the arrow from open to closed.
224237
$(this).find(".expand-task-assignment-timeline-arrow").toggleClass("arrow-open");
225238
$(this).find(".expand-task-assignment-timeline-arrow").toggleClass("arrow-closed");
@@ -234,6 +247,8 @@ $(function () {
234247
// Set it to false so that the click function can revert it
235248
window.localStorage.setItem("expand-task-assignment-timeline", "false");
236249
$("span.expand-task-assignment-timeline").trigger('click');
250+
} else {
251+
$("#task-assignment-timeline").css("display", "none");
237252
}
238253
});
239254

core/src/main/resources/org/apache/spark/ui/static/vis-timeline-graph2d.min.css

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/main/resources/org/apache/spark/ui/static/vis-timeline-graph2d.min.css.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/main/resources/org/apache/spark/ui/static/vis-timeline-graph2d.min.js

Lines changed: 60 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/main/resources/org/apache/spark/ui/static/vis-timeline-graph2d.min.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/main/resources/org/apache/spark/ui/static/vis.min.css

Lines changed: 0 additions & 1 deletion
This file was deleted.

core/src/main/resources/org/apache/spark/ui/static/vis.min.js

Lines changed: 0 additions & 45 deletions
This file was deleted.

core/src/main/scala/org/apache/spark/ui/UIUtils.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,14 @@ private[spark] object UIUtils extends Logging {
225225
<meta name="viewport" content="width=device-width, initial-scale=1" />
226226
<link rel="stylesheet"
227227
href={prependBaseUri(request, "/static/bootstrap.min.css")} type="text/css"/>
228-
<link rel="stylesheet" href={prependBaseUri(request, "/static/vis.min.css")} type="text/css"/>
228+
<link rel="stylesheet"
229+
href={prependBaseUri(request, "/static/vis-timeline-graph2d.min.css")} type="text/css"/>
229230
<link rel="stylesheet" href={prependBaseUri(request, "/static/webui.css")} type="text/css"/>
230231
<link rel="stylesheet"
231232
href={prependBaseUri(request, "/static/timeline-view.css")} type="text/css"/>
232233
<script src={prependBaseUri(request, "/static/sorttable.js")} ></script>
233234
<script src={prependBaseUri(request, "/static/jquery-3.4.1.min.js")}></script>
234-
<script src={prependBaseUri(request, "/static/vis.min.js")}></script>
235+
<script src={prependBaseUri(request, "/static/vis-timeline-graph2d.min.js")}></script>
235236
<script src={prependBaseUri(request, "/static/bootstrap.bundle.min.js")}></script>
236237
<script src={prependBaseUri(request, "/static/initialize-tooltips.js")}></script>
237238
<script src={prependBaseUri(request, "/static/table.js")}></script>

core/src/test/scala/org/apache/spark/ui/UISeleniumSuite.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import org.apache.spark.status.api.v1.{JacksonMessageWriter, RDDDataDistribution
4747

4848
private[spark] class SparkUICssErrorHandler extends DefaultCssErrorHandler {
4949

50-
private val cssWhiteList = List("bootstrap.min.css", "vis.min.css")
50+
private val cssWhiteList = List("bootstrap.min.css", "vis-timeline-graph2d.min.css")
5151

5252
private def isInWhileList(uri: String): Boolean = cssWhiteList.exists(uri.endsWith)
5353

0 commit comments

Comments
 (0)