Github user vanzin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/20663#discussion_r170685539
  
    --- Diff: core/src/main/scala/org/apache/spark/ui/jobs/AllStagesPage.scala 
---
    @@ -67,152 +41,120 @@ private[ui] class AllStagesPage(parent: StagesTab) 
extends WebUIPage("") {
         }.toMap
         val poolTable = new PoolTable(pools, parent)
     
    -    val shouldShowActiveStages = activeStages.nonEmpty
    -    val shouldShowPendingStages = pendingStages.nonEmpty
    -    val shouldShowCompletedStages = completedStages.nonEmpty
    -    val shouldShowSkippedStages = skippedStages.nonEmpty
    -    val shouldShowFailedStages = failedStages.nonEmpty
    +    val allStatuses = Seq(StageStatus.ACTIVE, StageStatus.PENDING, 
StageStatus.COMPLETE,
    +      StageStatus.SKIPPED, StageStatus.FAILED)
     
    +    val allStages = parent.store.stageList(null)
         val appSummary = parent.store.appSummary()
    -    val completedStageNumStr = if (appSummary.numCompletedStages == 
completedStages.size) {
    -      s"${appSummary.numCompletedStages}"
    -    } else {
    -      s"${appSummary.numCompletedStages}, only showing 
${completedStages.size}"
    -    }
    +
    +    val (summaries, tables) = allStatuses.map(
    +      summaryAndTableForStatus(allStages, appSummary, _, request)).unzip
     
         val summary: NodeSeq =
           <div>
             <ul class="unstyled">
    -          {
    -            if (shouldShowActiveStages) {
    -              <li>
    -                <a href="#active"><strong>Active Stages:</strong></a>
    -                {activeStages.size}
    -              </li>
    -            }
    -          }
    -          {
    -            if (shouldShowPendingStages) {
    -              <li>
    -                <a href="#pending"><strong>Pending Stages:</strong></a>
    -                {pendingStages.size}
    -              </li>
    -            }
    -          }
    -          {
    -            if (shouldShowCompletedStages) {
    -              <li id="completed-summary">
    -                <a href="#completed"><strong>Completed Stages:</strong></a>
    -                {completedStageNumStr}
    -              </li>
    -            }
    -          }
    -          {
    -            if (shouldShowSkippedStages) {
    -              <li id="completed-summary">
    -                <a href="#skipped"><strong>Skipped Stages:</strong></a>
    -                {skippedStages.size}
    -              </li>
    -            }
    -          }
    -          {
    -            if (shouldShowFailedStages) {
    -              <li>
    -                <a href="#failed"><strong>Failed Stages:</strong></a>
    -                {numFailedStages}
    -              </li>
    -            }
    -          }
    +          {summaries.flatten}
             </ul>
           </div>
     
    -    var content = summary ++
    -      {
    -        if (sc.isDefined && isFairScheduler) {
    -          <span class="collapse-aggregated-poolTable collapse-table"
    -              
onClick="collapseTable('collapse-aggregated-poolTable','aggregated-poolTable')">
    -            <h4>
    -              <span class="collapse-table-arrow arrow-open"></span>
    -              <a>Fair Scheduler Pools ({pools.size})</a>
    -            </h4>
    -          </span> ++
    -          <div class="aggregated-poolTable collapsible-table">
    -            {poolTable.toNodeSeq}
    -          </div>
    -        } else {
    -          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')">
    +    val poolsDescription = if (sc.isDefined && isFairScheduler) {
    +        <span class="collapse-aggregated-poolTable collapse-table"
    +            
onClick="collapseTable('collapse-aggregated-poolTable','aggregated-poolTable')">
               <h4>
                 <span class="collapse-table-arrow arrow-open"></span>
    -            <a>Pending Stages ({pendingStages.size})</a>
    +            <a>Fair Scheduler Pools ({pools.size})</a>
               </h4>
             </span> ++
    -        <div class="aggregated-allPendingStages collapsible-table">
    -          {pendingStagesTable.toNodeSeq}
    +        <div class="aggregated-poolTable collapsible-table">
    +          {poolTable.toNodeSeq}
             </div>
    +      } else {
    +        Seq.empty[Node]
    +      }
    +
    +    val content = summary ++ poolsDescription ++ tables.flatten.flatten
    +
    +    UIUtils.headerSparkPage("Stages for All Jobs", content, parent)
    +  }
    +
    +  def summaryAndTableForStatus(
    +      allStages: Seq[StageData],
    +      appSummary: AppSummary,
    +      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, 
statusName(status), stageTag(status),
    +          parent.basePath, subPath, parent.isFairScheduler, killEnabled, 
isFailedStage)
    +      val stagesSize = stages.size
    +      (Some(summary(appSummary, status, stagesSize)),
    +        Some(table(appSummary, 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 statusName(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 = 
s"${statusName(status)}Stage"
    +
    +  private def headerDescription(status: StageStatus): String = 
statusName(status).capitalize
    +
    +  private def summaryContent(appSummary: AppSummary, 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(appSummary: AppSummary, status: StageStatus, size: 
Int): Elem = {
    +    val summary =
    +      <li>
    +        <a href={s"#${statusName(status)}"}>
    +          <strong>{headerDescription(status)} Stages:</strong>
    +        </a>
    +        {summaryContent(appSummary, status, size)}
    +      </li>
    +
    +    if (status == StageStatus.COMPLETE) {
    +      summary % Attribute(None, "id", Text("completed-summary"), Null)
    +    } else {
    +      summary
         }
    -    UIUtils.headerSparkPage("Stages for All Jobs", content, parent)
    +  }
    +
    +  private def table(
    +      appSummary: AppSummary,
    +      status: StageStatus,
    +      stagesTable: StageTableBase, size: Int): NodeSeq = {
    --- End diff --
    
    nit: `size` goes in next line


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org
For additional commands, e-mail: reviews-h...@spark.apache.org

Reply via email to