Skip to content

Commit bda2fa1

Browse files
author
Marcelo Vanzin
committed
Rudimentary paging support for the history UI.
The provider's list api was tweaked a little bit so that the caller can get an atomic view of the data currently held in the provider.
1 parent b284478 commit bda2fa1

File tree

3 files changed

+35
-15
lines changed

3 files changed

+35
-15
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,21 @@ class FsHistoryProvider(conf: SparkConf) extends ApplicationHistoryProvider
8383
}
8484

8585
checkForLogs()
86+
logCheckingThread.setDaemon(true)
8687
logCheckingThread.start()
8788
}
8889

8990
override def stop() = {
9091
stopped = true
9192
logCheckingThread.interrupt()
9293
logCheckingThread.join()
94+
fs.close()
9395
}
9496

95-
override def getListing(offset: Int, limit: Int): Seq[ApplicationHistoryInfo] = {
96-
appList.get()
97+
override def getListing(offset: Int, count: Int) = {
98+
val list = appList.get()
99+
val theOffset = if (offset < list.size) offset else 0
100+
(list.slice(theOffset, Math.min(theOffset + count, list.size)), theOffset, list.size)
97101
}
98102

99103
override def getAppInfo(appId: String): ApplicationHistoryInfo = {

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,29 @@ import org.apache.spark.ui.{WebUIPage, UIUtils}
2525

2626
private[spark] class HistoryPage(parent: HistoryServer) extends WebUIPage("") {
2727

28+
val pageSize = 20
29+
2830
def render(request: HttpServletRequest): Seq[Node] = {
29-
val apps = parent.getApplicationList(0, -1)
31+
val requestedPage = Option(request.getParameter("page")).getOrElse("1").toInt
32+
val requestedFirst = (requestedPage - 1) * pageSize
33+
val (apps, actualFirst, count) = parent.getApplicationList(requestedFirst, pageSize)
34+
val actualPage = (actualFirst / pageSize) + 1
35+
val last = Math.min(actualFirst + pageSize, count) - 1
36+
val pageCount = count / pageSize + (if (count % pageSize > 0) 1 else 0)
37+
3038
val appTable = UIUtils.listingTable(appHeader, appRow, apps)
3139
val content =
3240
<div class="row-fluid">
3341
<div class="span12">
3442
{
35-
if (apps.size > 0) {
43+
if (count > 0) {
3644
<h4>
37-
Showing {apps.size}/{apps.size}
38-
Completed Application{if (apps.size > 1) "s" else ""}
45+
Showing {actualFirst + 1}-{last + 1} of {count}
46+
Application{if (last - actualFirst > 1) "s" else ""}
47+
<span style="float: right">
48+
{if (actualPage > 1) <a href={"/?page=" + (actualPage - 1)}>&lt;</a>}
49+
{if (actualPage < pageCount) <a href={"/?page=" + (actualPage + 1)}>&gt;</a>}
50+
</span>
3951
</h4> ++
4052
appTable
4153
} else {

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,12 @@ class HistoryServer(
155155
* Returns a list of available applications, in descending order according to their last
156156
* updated time.
157157
*
158-
* @param offset Offset of the first entry to return.
159-
* @param limit Maximum number of entries to return (-1 = no limit).
158+
* @param offset Starting offset for returned objects.
159+
* @param count Max number of objects to return.
160+
* @return 3-tuple (requested app list, adjusted offset, count of all available apps)
160161
*/
161-
def getApplicationList(offset: Int, limit: Int) = {
162-
provider.getListing(offset, limit)
162+
def getApplicationList(offset: Int, count: Int) = {
163+
provider.getListing(offset, count)
163164
}
164165

165166
}
@@ -269,13 +270,16 @@ private[spark] abstract class ApplicationHistoryProvider {
269270

270271
/**
271272
* This method should return a list of applications available for the history server to
272-
* show. The listing is assumed to be in descending time order (so that the parameters
273-
* make sense).
273+
* show. The listing is assumed to be in descending time order.
274274
*
275-
* @param offset Offset of the first entry to return.
276-
* @param limit Maximum number of entries to return (-1 = no limit).
275+
* An adjusted offset should be returned if the app list has changed and the request
276+
* references an invalid start offset. Otherwise, the provided offset should be returned.
277+
*
278+
* @param offset Starting offset for returned objects.
279+
* @param count Max number of objects to return.
280+
* @return 3-tuple (requested app list, adjusted offset, count of all available apps)
277281
*/
278-
def getListing(offset: Int, limit: Int): Seq[ApplicationHistoryInfo]
282+
def getListing(offset: Int, count: Int): (Seq[ApplicationHistoryInfo], Int, Int)
279283

280284
/**
281285
* This method should return the application information, including a rendered SparkUI.

0 commit comments

Comments
 (0)