Github user vanzin commented on a diff in the pull request:
https://github.com/apache/spark/pull/20663#discussion_r170407936
--- Diff: core/src/main/scala/org/apache/spark/ui/jobs/AllStagesPage.scala
---
@@ -143,76 +72,105 @@ private[ui] class AllStagesPage(parent: StagesTab)
extends WebUIPage("") {
Seq.empty[Node]
}
}
- if (shouldShowActiveStages) {
- content ++=
- <span id="active" class="collapse-aggregated-allActiveStages
collapse-table"
- onClick="collapseTable('collapse-aggregated-allActiveStages',
- 'aggregated-allActiveStages')">
- <h4>
- <span class="collapse-table-arrow arrow-open"></span>
- <a>Active Stages ({activeStages.size})</a>
- </h4>
- </span> ++
- <div class="aggregated-allActiveStages collapsible-table">
- {activeStagesTable.toNodeSeq}
- </div>
- }
- if (shouldShowPendingStages) {
- content ++=
- <span id="pending" class="collapse-aggregated-allPendingStages
collapse-table"
- onClick="collapseTable('collapse-aggregated-allPendingStages',
- 'aggregated-allPendingStages')">
- <h4>
- <span class="collapse-table-arrow arrow-open"></span>
- <a>Pending Stages ({pendingStages.size})</a>
- </h4>
- </span> ++
- <div class="aggregated-allPendingStages collapsible-table">
- {pendingStagesTable.toNodeSeq}
- </div>
+
+ tables.flatten.foreach(content ++= _)
+
+ UIUtils.headerSparkPage("Stages for All Jobs", content, parent)
+ }
+
+ def summaryAndTableForStatus(
+ status: StageStatus,
+ request: HttpServletRequest): (Option[Elem], Option[NodeSeq]) = {
+ val stages = if (status == StageStatus.FAILED) {
+ allStages.filter(_.status == status).reverse
+ } else {
+ allStages.filter(_.status == status)
}
- if (shouldShowCompletedStages) {
- content ++=
- <span id="completed" class="collapse-aggregated-allCompletedStages
collapse-table"
-
onClick="collapseTable('collapse-aggregated-allCompletedStages',
- 'aggregated-allCompletedStages')">
- <h4>
- <span class="collapse-table-arrow arrow-open"></span>
- <a>Completed Stages ({completedStageNumStr})</a>
- </h4>
- </span> ++
- <div class="aggregated-allCompletedStages collapsible-table">
- {completedStagesTable.toNodeSeq}
- </div>
+
+ if (stages.isEmpty) {
+ (None, None)
+ } else {
+ val killEnabled = status == StageStatus.ACTIVE && parent.killEnabled
+ val isFailedStage = status == StageStatus.FAILED
+
+ val stagesTable =
+ new StageTableBase(parent.store, request, stages,
tableHeaderID(status), stageTag(status),
+ parent.basePath, subPath, parent.isFairScheduler, killEnabled,
isFailedStage)
+ val stagesSize = stages.size
+ (Some(summary(status, stagesSize)), Some(table(status, stagesTable,
stagesSize)))
}
- if (shouldShowSkippedStages) {
- content ++=
- <span id="skipped" class="collapse-aggregated-allSkippedStages
collapse-table"
-
onClick="collapseTable('collapse-aggregated-allSkippedStages',
- 'aggregated-allSkippedStages')">
- <h4>
- <span class="collapse-table-arrow arrow-open"></span>
- <a>Skipped Stages ({skippedStages.size})</a>
- </h4>
- </span> ++
- <div class="aggregated-allSkippedStages collapsible-table">
- {skippedStagesTable.toNodeSeq}
- </div>
+ }
+
+ private def tableHeaderID(status: StageStatus): String = status match {
+ case StageStatus.ACTIVE => "active"
+ case StageStatus.COMPLETE => "completed"
+ case StageStatus.FAILED => "failed"
+ case StageStatus.PENDING => "pending"
+ case StageStatus.SKIPPED => "skipped"
+ }
+
+ private def stageTag(status: StageStatus): String = status match {
+ case StageStatus.ACTIVE => "activeStage"
+ case StageStatus.COMPLETE => "completedStage"
+ case StageStatus.FAILED => "failedStage"
+ case StageStatus.PENDING => "pendingStage"
+ case StageStatus.SKIPPED => "skippedStage"
+ }
+
+ private def headerDescription(status: StageStatus): String = status
match {
+ case StageStatus.ACTIVE => "Active"
+ case StageStatus.COMPLETE => "Completed"
+ case StageStatus.FAILED => "Failed"
+ case StageStatus.PENDING => "Pending"
+ case StageStatus.SKIPPED => "Skipped"
+ }
+
+ private def classSuffix(status: StageStatus): String = status match {
+ case StageStatus.ACTIVE => "ActiveStages"
+ case StageStatus.COMPLETE => "CompletedStages"
+ case StageStatus.FAILED => "FailedStages"
+ case StageStatus.PENDING => "PendingStages"
+ case StageStatus.SKIPPED => "SkippedStages"
+ }
+
+ private def summaryContent(status: StageStatus, size: Int): String = {
+ if (status == StageStatus.COMPLETE
+ && appSummary.numCompletedStages != size) {
+ s"${appSummary.numCompletedStages}, only showing $size"
+ } else {
+ s"$size"
}
- if (shouldShowFailedStages) {
- content ++=
- <span id ="failed" class="collapse-aggregated-allFailedStages
collapse-table"
- onClick="collapseTable('collapse-aggregated-allFailedStages',
- 'aggregated-allFailedStages')">
- <h4>
- <span class="collapse-table-arrow arrow-open"></span>
- <a>Failed Stages ({numFailedStages})</a>
- </h4>
- </span> ++
- <div class="aggregated-allFailedStages collapsible-table">
- {failedStagesTable.toNodeSeq}
- </div>
+ }
+
+ private def summary(status: StageStatus, size: Int): Elem = {
+ val summary =
+ <li>
+ <a href={s"#${tableHeaderID(status)}"}>
+ <strong>{headerDescription(status)} Stages:</strong>
+ </a>
+ {summaryContent(status, size)}
+ </li>
+
+ if (status == StageStatus.COMPLETE) {
+ summary % Attribute(None, "id", Text("completed-summary"), Null)
--- End diff --
In the previous code this was also the case for `SKIPPED`, are you changing
that intentionally?
---
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]