Skip to content

Commit 76ef02e

Browse files
pgandhitgravescs
authored andcommitted
[SPARK-21809] Change Stage Page to use datatables to support sorting columns and searching
Support column sort, pagination and search for Stage Page using jQuery DataTable and REST API. Before this commit, the Stage page generated a hard-coded HTML table that could not support search. Supporting search and sort (over all applications rather than the 20 entries in the current page) in any case will greatly improve the user experience. Created the stagespage-template.html for displaying application information in datables. Added REST api endpoint and javascript code to fetch data from the endpoint and display it on the data table. Because of the above change, certain functionalities in the page had to be modified to support the addition of datatables. For example, the toggle checkbox 'Select All' previously would add the checked fields as columns in the Task table and as rows in the Summary Metrics table, but after the change, only columns are added in the Task Table as it got tricky to add rows dynamically in the datatables. ## How was this patch tested? I have attached the screenshots of the Stage Page UI before and after the fix. **Before:** <img width="1419" alt="30564304-35991e1c-9c8a-11e7-850f-2ac7a347f600" src="https://user-images.githubusercontent.com/22228190/42137915-52054558-7d3a-11e8-8c85-433b2c94161d.png"> <img width="1435" alt="31360592-cbaa2bae-ad14-11e7-941d-95b4c7d14970" src="https://user-images.githubusercontent.com/22228190/42137928-79df500a-7d3a-11e8-9068-5630afe46ff3.png"> **After:** <img width="1432" alt="31360591-c5650ee4-ad14-11e7-9665-5a08d8f21830" src="https://user-images.githubusercontent.com/22228190/42137936-a3fb9f42-7d3a-11e8-8502-22b3897cbf64.png"> <img width="1388" alt="31360604-d266b6b0-ad14-11e7-94b5-dcc4bb5443f4" src="https://user-images.githubusercontent.com/22228190/42137970-0fabc58c-7d3b-11e8-95ad-383b1bd1f106.png"> Closes apache#21688 from pgandhi999/SPARK-21809-2.3. Authored-by: pgandhi <[email protected]> Signed-off-by: Thomas Graves <[email protected]>
1 parent 3df307a commit 76ef02e

33 files changed

+3064
-1358
lines changed

core/src/main/resources/org/apache/spark/ui/static/executorspage-template.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
-->
1717

1818
<script id="executors-summary-template" type="text/html">
19-
<h4 style="clear: left; display: inline-block;">Summary</h4>
19+
<h4 class="title-table">Summary</h4>
2020
<div class="container-fluid">
2121
<div class="container-fluid">
22-
<table id="summary-execs-table" class="table table-striped compact">
22+
<table id="summary-execs-table" class="table table-striped compact cell-border">
2323
<thead>
2424
<th></th>
2525
<th>RDD Blocks</th>
@@ -64,10 +64,10 @@ <h4 style="clear: left; display: inline-block;">Summary</h4>
6464
</table>
6565
</div>
6666
</div>
67-
<h4 style="clear: left; display: inline-block;">Executors</h4>
67+
<h4 class="title-table">Executors</h4>
6868
<div class="container-fluid">
6969
<div class="container-fluid">
70-
<table id="active-executors-table" class="table table-striped compact">
70+
<table id="active-executors-table" class="table table-striped compact cell-border">
7171
<thead>
7272
<tr>
7373
<th>

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

Lines changed: 4 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -59,78 +59,6 @@ $(document).ajaxStart(function () {
5959
$.blockUI({message: '<h3>Loading Executors Page...</h3>'});
6060
});
6161

62-
function createTemplateURI(appId) {
63-
var words = document.baseURI.split('/');
64-
var ind = words.indexOf("proxy");
65-
if (ind > 0) {
66-
var baseURI = words.slice(0, ind + 1).join('/') + '/' + appId + '/static/executorspage-template.html';
67-
return baseURI;
68-
}
69-
ind = words.indexOf("history");
70-
if(ind > 0) {
71-
var baseURI = words.slice(0, ind).join('/') + '/static/executorspage-template.html';
72-
return baseURI;
73-
}
74-
return location.origin + "/static/executorspage-template.html";
75-
}
76-
77-
function getStandAloneppId(cb) {
78-
var words = document.baseURI.split('/');
79-
var ind = words.indexOf("proxy");
80-
if (ind > 0) {
81-
var appId = words[ind + 1];
82-
cb(appId);
83-
return;
84-
}
85-
ind = words.indexOf("history");
86-
if (ind > 0) {
87-
var appId = words[ind + 1];
88-
cb(appId);
89-
return;
90-
}
91-
//Looks like Web UI is running in standalone mode
92-
//Let's get application-id using REST End Point
93-
$.getJSON(location.origin + "/api/v1/applications", function(response, status, jqXHR) {
94-
if (response && response.length > 0) {
95-
var appId = response[0].id
96-
cb(appId);
97-
return;
98-
}
99-
});
100-
}
101-
102-
function createRESTEndPoint(appId) {
103-
var words = document.baseURI.split('/');
104-
var ind = words.indexOf("proxy");
105-
if (ind > 0) {
106-
var appId = words[ind + 1];
107-
var newBaseURI = words.slice(0, ind + 2).join('/');
108-
return newBaseURI + "/api/v1/applications/" + appId + "/allexecutors"
109-
}
110-
ind = words.indexOf("history");
111-
if (ind > 0) {
112-
var appId = words[ind + 1];
113-
var attemptId = words[ind + 2];
114-
var newBaseURI = words.slice(0, ind).join('/');
115-
if (isNaN(attemptId)) {
116-
return newBaseURI + "/api/v1/applications/" + appId + "/allexecutors";
117-
} else {
118-
return newBaseURI + "/api/v1/applications/" + appId + "/" + attemptId + "/allexecutors";
119-
}
120-
}
121-
return location.origin + "/api/v1/applications/" + appId + "/allexecutors";
122-
}
123-
124-
function formatLogsCells(execLogs, type) {
125-
if (type !== 'display') return Object.keys(execLogs);
126-
if (!execLogs) return;
127-
var result = '';
128-
$.each(execLogs, function (logName, logUrl) {
129-
result += '<div><a href=' + logUrl + '>' + logName + '</a></div>'
130-
});
131-
return result;
132-
}
133-
13462
function logsExist(execs) {
13563
return execs.some(function(exec) {
13664
return !($.isEmptyObject(exec["executorLogs"]));
@@ -178,17 +106,13 @@ function totalDurationColor(totalGCTime, totalDuration) {
178106
}
179107

180108
$(document).ready(function () {
181-
$.extend($.fn.dataTable.defaults, {
182-
stateSave: true,
183-
lengthMenu: [[20, 40, 60, 100, -1], [20, 40, 60, 100, "All"]],
184-
pageLength: 20
185-
});
109+
setDataTableDefaults();
186110

187111
executorsSummary = $("#active-executors");
188112

189-
getStandAloneppId(function (appId) {
113+
getStandAloneAppId(function (appId) {
190114

191-
var endPoint = createRESTEndPoint(appId);
115+
var endPoint = createRESTEndPointForExecutorsPage(appId);
192116
$.getJSON(endPoint, function (response, status, jqXHR) {
193117
var summary = [];
194118
var allExecCnt = 0;
@@ -408,7 +332,7 @@ $(document).ready(function () {
408332
};
409333

410334
var data = {executors: response, "execSummary": [activeSummary, deadSummary, totalSummary]};
411-
$.get(createTemplateURI(appId), function (template) {
335+
$.get(createTemplateURI(appId, "executorspage"), function (template) {
412336

413337
executorsSummary.append(Mustache.render($(template).filter("#executors-summary-template").html(), data));
414338
var selector = "#active-executors-table";
160 Bytes
Loading
148 Bytes
Loading
201 Bytes
Loading
158 Bytes
Loading
146 Bytes
Loading

0 commit comments

Comments
 (0)