Skip to content

Commit a41ac4b

Browse files
committed
History Server: updated order for multiple attempts
1 parent ab65fa1 commit a41ac4b

File tree

2 files changed

+86
-108
lines changed

2 files changed

+86
-108
lines changed

core/src/main/scala/org/apache/spark/deploy/history/FsHistoryProvider.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ private[history] class FsHistoryProvider(conf: SparkConf, clock: Clock)
414414
/**
415415
* Comparison function that defines the sort order for application attempts within the same
416416
* application. Order is: running attempts before complete attempts, running attempts sorted
417-
* by start time, completed attempts sorted by end time.
417+
* by start time showing whichever started first,
418+
* completed attempts sorted by end time showing whichever ended first.
418419
*
419420
* Normally applications should have a single running attempt; but failure to call sc.stop()
420421
* may cause multiple running attempts to show up.
@@ -425,9 +426,9 @@ private[history] class FsHistoryProvider(conf: SparkConf, clock: Clock)
425426
a1: FsApplicationAttemptInfo,
426427
a2: FsApplicationAttemptInfo): Boolean = {
427428
if (a1.completed == a2.completed) {
428-
if (a1.completed) a1.endTime >= a2.endTime else a1.startTime >= a2.startTime
429+
if (a1.completed) a1.endTime <= a2.endTime else a1.startTime <= a2.startTime
429430
} else {
430-
!a1.completed
431+
a1.completed
431432
}
432433
}
433434

core/src/main/scala/org/apache/spark/deploy/history/HistoryPage.scala

Lines changed: 82 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("")
3535
Option(request.getParameter("showIncomplete")).getOrElse("false").toBoolean
3636

3737
val allApps = parent.getApplicationList()
38+
.filter(_.attempts.head.completed != requestedIncomplete)
3839
val allAppsSize = allApps.size
3940

4041
val actualFirst = if (requestedFirst < allAppsSize) requestedFirst else 0
@@ -50,15 +51,9 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("")
5051
val hasMultipleAttempts = appsToShow.exists(_.attempts.size > 1)
5152
val appTable =
5253
if (hasMultipleAttempts) {
53-
UIUtils.listingTable(
54-
appWithAttemptHeader,
55-
appWithAttemptRow(_, requestedIncomplete),
56-
appsToShow)
54+
UIUtils.listingTable(appWithAttemptHeader, appWithAttemptRow, appsToShow)
5755
} else {
58-
UIUtils.listingTable(
59-
appHeader,
60-
appRow(_, requestedIncomplete),
61-
appsToShow)
56+
UIUtils.listingTable(appHeader, appRow, appsToShow)
6257
}
6358

6459
val providerConfig = parent.getProviderConfig()
@@ -69,61 +64,61 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("")
6964
{providerConfig.map { case (k, v) => <li><strong>{k}:</strong> {v}</li> }}
7065
</ul>
7166
{
72-
// This displays the indices of pages that are within `plusOrMinus` pages of
73-
// the current page. Regardless of where the current page is, this also links
74-
// to the first and last page. If the current page +/- `plusOrMinus` is greater
75-
// than the 2nd page from the first page or less than the 2nd page from the last
76-
// page, `...` will be displayed.
77-
if (allAppsSize > 0) {
78-
val leftSideIndices =
79-
rangeIndices(actualPage - plusOrMinus until actualPage, 1 < _, requestedIncomplete)
80-
val rightSideIndices =
81-
rangeIndices(actualPage + 1 to actualPage + plusOrMinus, _ < pageCount,
82-
requestedIncomplete)
83-
84-
<h4>
85-
Showing {actualFirst + 1}-{last + 1} of {allAppsSize}
86-
{if (requestedIncomplete) "(Incomplete applications)"}
87-
<span style="float: right">
88-
{
89-
if (actualPage > 1) {
90-
<a href={makePageLink(actualPage - 1, requestedIncomplete)}>&lt; </a>
91-
<a href={makePageLink(1, requestedIncomplete)}>1</a>
92-
}
93-
}
94-
{if (actualPage - plusOrMinus > secondPageFromLeft) " ... "}
95-
{leftSideIndices}
96-
{actualPage}
97-
{rightSideIndices}
98-
{if (actualPage + plusOrMinus < secondPageFromRight) " ... "}
99-
{
100-
if (actualPage < pageCount) {
101-
<a href={makePageLink(pageCount, requestedIncomplete)}>{pageCount}</a>
102-
<a href={makePageLink(actualPage + 1, requestedIncomplete)}> &gt;</a>
103-
}
104-
}
105-
</span>
106-
</h4> ++
67+
// This displays the indices of pages that are within `plusOrMinus` pages of
68+
// the current page. Regardless of where the current page is, this also links
69+
// to the first and last page. If the current page +/- `plusOrMinus` is greater
70+
// than the 2nd page from the first page or less than the 2nd page from the last
71+
// page, `...` will be displayed.
72+
if (allAppsSize > 0) {
73+
val leftSideIndices =
74+
rangeIndices(actualPage - plusOrMinus until actualPage, 1 < _, requestedIncomplete)
75+
val rightSideIndices =
76+
rangeIndices(actualPage + 1 to actualPage + plusOrMinus, _ < pageCount,
77+
requestedIncomplete)
78+
79+
<h4>
80+
Showing {actualFirst + 1}-{last + 1} of {allAppsSize}
81+
{if (requestedIncomplete) "(Incomplete applications)"}
82+
<span style="float: right">
83+
{
84+
if (actualPage > 1) {
85+
<a href={makePageLink(actualPage - 1, requestedIncomplete)}>&lt; </a>
86+
<a href={makePageLink(1, requestedIncomplete)}>1</a>
87+
}
88+
}
89+
{if (actualPage - plusOrMinus > secondPageFromLeft) " ... "}
90+
{leftSideIndices}
91+
{actualPage}
92+
{rightSideIndices}
93+
{if (actualPage + plusOrMinus < secondPageFromRight) " ... "}
94+
{
95+
if (actualPage < pageCount) {
96+
<a href={makePageLink(pageCount, requestedIncomplete)}>{pageCount}</a>
97+
<a href={makePageLink(actualPage + 1, requestedIncomplete)}> &gt;</a>
98+
}
99+
}
100+
</span>
101+
</h4> ++
107102
appTable
108-
} else if (requestedIncomplete) {
109-
<h4>No incomplete applications found!</h4>
110-
} else {
111-
<h4>No completed applications found!</h4> ++
103+
} else if (requestedIncomplete) {
104+
<h4>No incomplete applications found!</h4>
105+
} else {
106+
<h4>No completed applications found!</h4> ++
112107
<p>Did you specify the correct logging directory?
113108
Please verify your setting of <span style="font-style:italic">
114109
spark.history.fs.logDirectory</span> and whether you have the permissions to
115110
access it.<br /> It is also possible that your application did not run to
116111
completion or did not stop the SparkContext.
117112
</p>
118-
}
113+
}
119114
}
120115
<a href={makePageLink(actualPage, !requestedIncomplete)}>
121116
{
122-
if (requestedIncomplete) {
123-
"Back to completed applications"
124-
} else {
125-
"Show incomplete applications"
126-
}
117+
if (requestedIncomplete) {
118+
"Back to completed applications"
119+
} else {
120+
"Show incomplete applications"
121+
}
127122
}
128123
</a>
129124
</div>
@@ -151,19 +146,18 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("")
151146
"Last Updated")
152147

153148
private def rangeIndices(
154-
range: Seq[Int],
155-
condition: Int => Boolean,
156-
showIncomplete: Boolean): Seq[Node] = {
149+
range: Seq[Int],
150+
condition: Int => Boolean,
151+
showIncomplete: Boolean): Seq[Node] = {
157152
range.filter(condition).map(nextPage =>
158153
<a href={makePageLink(nextPage, showIncomplete)}> {nextPage} </a>)
159154
}
160155

161156
private def attemptRow(
162-
renderAttemptIdColumn: Boolean,
163-
info: ApplicationHistoryInfo,
164-
attempt: ApplicationAttemptInfo,
165-
isFirst: Boolean,
166-
requestedIncomplete: Boolean): Seq[Node] = {
157+
renderAttemptIdColumn: Boolean,
158+
info: ApplicationHistoryInfo,
159+
attempt: ApplicationAttemptInfo,
160+
isFirst: Boolean): Seq[Node] = {
167161
val uiAddress = HistoryServer.getAttemptURI(info.id, attempt.attemptId)
168162
val startTime = UIUtils.formatDate(attempt.startTime)
169163
val endTime = if (attempt.endTime > 0) UIUtils.formatDate(attempt.endTime) else "-"
@@ -174,67 +168,50 @@ private[history] class HistoryPage(parent: HistoryServer) extends WebUIPage("")
174168
"-"
175169
}
176170
val lastUpdated = UIUtils.formatDate(attempt.lastUpdated)
177-
var someAttemptCompleted = false
178-
info.attempts.foreach{ attempt =>
179-
if (attempt.completed) someAttemptCompleted = true
180-
}
181171
<tr>
182172
{
183-
if (isFirst) {
184-
if (info.attempts.size > 1 || renderAttemptIdColumn) {
185-
<td rowspan={info.attempts.size.toString} style="background-color: #ffffff">
186-
<a href={uiAddress}>{info.id}</a></td>
173+
if (isFirst) {
174+
if (info.attempts.size > 1 || renderAttemptIdColumn) {
175+
<td rowspan={info.attempts.size.toString} style="background-color: #ffffff">
176+
<a href={uiAddress}>{info.id}</a></td>
187177
<td rowspan={info.attempts.size.toString} style="background-color: #ffffff">
188178
{info.name}</td>
189-
} else {
190-
<td><a href={uiAddress}>{info.id}</a></td>
191-
<td>{info.name}</td>
192-
}
193179
} else {
194-
Nil
180+
<td><a href={uiAddress}>{info.id}</a></td>
181+
<td>{info.name}</td>
195182
}
183+
} else {
184+
Nil
196185
}
197-
{
198-
if (renderAttemptIdColumn &&
199-
(requestedIncomplete || (!requestedIncomplete && someAttemptCompleted))) {
200-
if (info.attempts.size > 1 && attempt.attemptId.isDefined) {
201-
<td><a href={HistoryServer.getAttemptURI(info.id, attempt.attemptId)}>
202-
{attempt.attemptId.get}</a></td>
203-
} else {
204-
<td>&nbsp;</td>
205-
}
206-
} else {
207-
Nil
208-
}
209186
}
210187
{
211-
if (requestedIncomplete || (!requestedIncomplete && someAttemptCompleted)) {
212-
<td sorttable_customkey={attempt.startTime.toString}>{startTime}</td>
213-
<td sorttable_customkey={attempt.endTime.toString}>{endTime}</td>
214-
<td sorttable_customkey={(attempt.endTime - attempt.startTime).toString}>
215-
{duration}</td>
216-
<td>{attempt.sparkUser}</td>
217-
<td sorttable_customkey={attempt.lastUpdated.toString}>{lastUpdated}</td>
188+
if (renderAttemptIdColumn) {
189+
if (info.attempts.size > 1 && attempt.attemptId.isDefined) {
190+
<td><a href={HistoryServer.getAttemptURI(info.id, attempt.attemptId)}>
191+
{attempt.attemptId.get}</a></td>
218192
} else {
219-
Nil
193+
<td>&nbsp;</td>
220194
}
195+
} else {
196+
Nil
197+
}
221198
}
199+
<td sorttable_customkey={attempt.startTime.toString}>{startTime}</td>
200+
<td sorttable_customkey={attempt.endTime.toString}>{endTime}</td>
201+
<td sorttable_customkey={(attempt.endTime - attempt.startTime).toString}>
202+
{duration}</td>
203+
<td>{attempt.sparkUser}</td>
204+
<td sorttable_customkey={attempt.lastUpdated.toString}>{lastUpdated}</td>
222205
</tr>
223206
}
224207

225-
226-
227-
private def appRow(
228-
info: ApplicationHistoryInfo,
229-
requestedIncomplete: Boolean): Seq[Node] = {
230-
attemptRow(false, info, info.attempts.head, true, requestedIncomplete)
208+
private def appRow(info: ApplicationHistoryInfo): Seq[Node] = {
209+
attemptRow(false, info, info.attempts.head, true)
231210
}
232211

233-
private def appWithAttemptRow(
234-
info: ApplicationHistoryInfo,
235-
requestedIncomplete: Boolean): Seq[Node] = {
236-
attemptRow(true, info, info.attempts.head, true, requestedIncomplete) ++
237-
info.attempts.drop(1).flatMap(attemptRow(true, info, _, false, requestedIncomplete))
212+
private def appWithAttemptRow(info: ApplicationHistoryInfo): Seq[Node] = {
213+
attemptRow(true, info, info.attempts.head, true) ++
214+
info.attempts.drop(1).flatMap(attemptRow(true, info, _, false))
238215
}
239216

240217
private def makePageLink(linkPage: Int, showIncomplete: Boolean): String = {

0 commit comments

Comments
 (0)