@@ -226,7 +226,9 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
226226 val accumulableHeaders : Seq [String ] = Seq (" Accumulable" , " Value" )
227227 def accumulableRow (acc : AccumulableInfo ): Elem =
228228 <tr ><td >{acc.name}</td ><td >{acc.value}</td ></tr >
229- val accumulableTable = UIUtils .listingTable(accumulableHeaders, accumulableRow,
229+ val accumulableTable = UIUtils .listingTable(
230+ accumulableHeaders,
231+ accumulableRow,
230232 accumulables.values.toSeq)
231233
232234 val taskHeadersAndCssClasses : Seq [(String , String )] =
@@ -265,9 +267,14 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
265267 val currentTime = System .currentTimeMillis()
266268 val taskTable = UIUtils .listingTable(
267269 unzipped._1,
268- taskRow(hasAccumulators, stageData.hasInput, stageData.hasOutput,
269- stageData.hasShuffleRead, stageData.hasShuffleWrite,
270- stageData.hasBytesSpilled, currentTime),
270+ taskRow(
271+ hasAccumulators,
272+ stageData.hasInput,
273+ stageData.hasOutput,
274+ stageData.hasShuffleRead,
275+ stageData.hasShuffleWrite,
276+ stageData.hasBytesSpilled,
277+ currentTime),
271278 tasks,
272279 headerClasses = unzipped._2)
273280 // Excludes tasks which failed and have incomplete metrics
@@ -515,49 +522,42 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
515522 val host = taskInfo.host
516523 executorsSet += ((executorId, host))
517524
518- val isSucceeded = taskInfo.successful
519- val isFailed = taskInfo.failed
520- val isRunning = taskInfo.running
521525 val classNameByStatus = {
522- if (isSucceeded ) {
526+ if (taskInfo.successful ) {
523527 " succeeded"
524- } else if (isFailed ) {
528+ } else if (taskInfo.failed ) {
525529 " failed"
526- } else if (isRunning ) {
530+ } else if (taskInfo.running ) {
527531 " running"
528532 }
529533 }
530534
531535 val launchTime = taskInfo.launchTime
532- val finishTime = if (! isRunning ) taskInfo.finishTime else currentTime
536+ val finishTime = if (! taskInfo.running ) taskInfo.finishTime else currentTime
533537 val totalExecutionTime = finishTime - launchTime
534538 minLaunchTime = launchTime.min(minLaunchTime)
535539 maxFinishTime = launchTime.max(maxFinishTime)
536540 numEffectiveTasks += 1
537541
542+ def toProportion (time : Long ) = (time.toDouble / totalExecutionTime * 100 ).toLong
543+
538544 val metricsOpt = taskUIData.taskMetrics
539545 val shuffleReadTime =
540546 metricsOpt.flatMap(_.shuffleReadMetrics.map(_.fetchWaitTime)).getOrElse(0L )
541- val shuffleReadTimeProportion =
542- (shuffleReadTime.toDouble / totalExecutionTime * 100 ).toLong
547+ val shuffleReadTimeProportion = toProportion(shuffleReadTime)
543548 val shuffleWriteTime =
544549 (metricsOpt.flatMap(_.shuffleWriteMetrics
545550 .map(_.shuffleWriteTime)).getOrElse(0L ) / 1e6 ).toLong
546- val shuffleWriteTimeProportion =
547- (shuffleWriteTime.toDouble / totalExecutionTime * 100 ).toLong
551+ val shuffleWriteTimeProportion = toProportion(shuffleWriteTime)
548552 val executorComputingTime = metricsOpt.map(_.executorRunTime).getOrElse(0L ) -
549553 shuffleReadTime - shuffleWriteTime
550- val executorComputingTimeProportion =
551- (executorComputingTime.toDouble / totalExecutionTime * 100 ).toLong
554+ val executorComputingTimeProportion = toProportion(executorComputingTime)
552555 val serializationTime = metricsOpt.map(_.resultSerializationTime).getOrElse(0L )
553- val serializationTimeProportion =
554- (serializationTime.toDouble / totalExecutionTime * 100 ).toLong
556+ val serializationTimeProportion = toProportion(serializationTime)
555557 val deserializationTime = metricsOpt.map(_.executorDeserializeTime).getOrElse(0L )
556- val deserializationTimeProportion =
557- (deserializationTime.toDouble / totalExecutionTime * 100 ).toLong
558+ val deserializationTimeProportion = toProportion(deserializationTime)
558559 val gettingResultTime = getGettingResultTime(taskUIData.taskInfo)
559- val gettingResultTimeProportion =
560- (gettingResultTime.toDouble / totalExecutionTime * 100 ).toLong
560+ val gettingResultTimeProportion = toProportion(gettingResultTime)
561561 val schedulerDelay = totalExecutionTime -
562562 (executorComputingTime + shuffleReadTime + shuffleWriteTime +
563563 serializationTime + deserializationTime + gettingResultTime)
@@ -585,22 +585,22 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
585585 val timelineObject =
586586 s """
587587 {
588- 'className': 'task task-assignment-timeline-object ${ classNameByStatus} ',
589- 'group': ' ${ executorId} ',
588+ 'className': 'task task-assignment-timeline-object $classNameByStatus',
589+ 'group': ' $executorId',
590590 'content': '<div class="task-assignment-timeline-content"' +
591591 'data-toggle="tooltip" data-placement="top"' +
592592 'data-html="true" data-container="body"' +
593593 'data-title=" ${s " Task " + index + " (attempt " + attempt + " )" }<br>' +
594594 'Status: ${taskInfo.status}<br>' +
595595 'Launch Time: ${UIUtils .formatDate(new Date (launchTime))}' +
596596 ' ${
597- if (! isRunning ) {
597+ if (! taskInfo.running ) {
598598 s """ <br>Finish Time: ${UIUtils .formatDate(new Date (finishTime))}"""
599599 } else {
600600 " "
601601 }
602602 }' +
603- '<br>Scheduler Delay: ${ schedulerDelay} ms' +
603+ '<br>Scheduler Delay: $schedulerDelay ms' +
604604 '<br>Task Deserialization Time: ${UIUtils .formatDuration(deserializationTime)}' +
605605 '<br>Shuffle Read Time: ${UIUtils .formatDuration(shuffleReadTime)}' +
606606 '<br>Executor Computing Time: ${UIUtils .formatDuration(executorComputingTime)}' +
@@ -609,28 +609,28 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
609609 '<br>Getting Result Time: ${UIUtils .formatDuration(gettingResultTime)}">' +
610610 '<svg class="task-assignment-timeline-duration-bar">' +
611611 '<rect class="scheduler-delay-proportion" ' +
612- 'x=" ${ schedulerDelayProportionPos} %" y="0px" height="26px"' +
613- 'width=" ${ schedulerDelayProportion} %""></rect>' +
612+ 'x=" $schedulerDelayProportionPos%" y="0px" height="26px"' +
613+ 'width=" $schedulerDelayProportion%""></rect>' +
614614 '<rect class="deserialization-time-proportion" '+
615- 'x=" ${ deserializationTimeProportionPos} %" y="0px" height="26px"' +
616- 'width=" ${ deserializationTimeProportion} %"></rect>' +
615+ 'x=" $deserializationTimeProportionPos%" y="0px" height="26px"' +
616+ 'width=" $deserializationTimeProportion%"></rect>' +
617617 '<rect class="shuffle-read-time-proportion" ' +
618- 'x=" ${ shuffleReadTimeProportionPos} %" y="0px" height="26px"' +
619- 'width=" ${ shuffleReadTimeProportion} %"></rect>' +
618+ 'x=" $shuffleReadTimeProportionPos%" y="0px" height="26px"' +
619+ 'width=" $shuffleReadTimeProportion%"></rect>' +
620620 '<rect class="executor-runtime-proportion" ' +
621- 'x=" ${ executorRuntimeProportionPos} %" y="0px" height="26px"' +
622- 'width=" ${ executorComputingTimeProportion} %"></rect>' +
621+ 'x=" $executorRuntimeProportionPos%" y="0px" height="26px"' +
622+ 'width=" $executorComputingTimeProportion%"></rect>' +
623623 '<rect class="shuffle-write-time-proportion" ' +
624- 'x=" ${ shuffleWriteTimeProportionPos} %" y="0px" height="26px"' +
625- 'width=" ${ shuffleWriteTimeProportion} %"></rect>' +
624+ 'x=" $shuffleWriteTimeProportionPos%" y="0px" height="26px"' +
625+ 'width=" $shuffleWriteTimeProportion%"></rect>' +
626626 '<rect class="serialization-time-proportion" ' +
627- 'x=" ${ serializationTimeProportionPos} %" y="0px" height="26px"' +
628- 'width=" ${ serializationTimeProportion} %"></rect>' +
627+ 'x=" $serializationTimeProportionPos%" y="0px" height="26px"' +
628+ 'width=" $serializationTimeProportion%"></rect>' +
629629 '<rect class="getting-result-time-proportion" ' +
630- 'x=" ${ gettingResultTimeProportionPos} %" y="0px" height="26px"' +
631- 'width=" ${ gettingResultTimeProportion} %"></rect></svg>',
632- 'start': new Date( ${ launchTime} ),
633- 'end': new Date( ${ finishTime} )
630+ 'x=" $gettingResultTimeProportionPos%" y="0px" height="26px"' +
631+ 'width=" $gettingResultTimeProportion%"></rect></svg>',
632+ 'start': new Date( $launchTime),
633+ 'end': new Date( $finishTime)
634634 }
635635 """
636636 timelineObject
@@ -640,23 +640,29 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
640640 case (executorId, host) =>
641641 s """
642642 {
643- 'id': ' ${ executorId} ',
644- 'content': ' ${ executorId} / ${ host} ',
643+ 'id': ' $executorId',
644+ 'content': ' $executorId / $host',
645645 }
646646 """
647647 }.mkString(" [" , " ," , " ]" )
648648
649649 val maxZoom = maxFinishTime - minLaunchTime
650650 <span class =" expand-task-assignment-timeline" >
651651 <span class =" expand-task-assignment-timeline-arrow arrow-closed" ></span >
652- <a >Event Timeline {
653- if (MAX_TIMELINE_TASKS <= numEffectiveTasks) {
654- s " (Most recent ${MAX_TIMELINE_TASKS }) "
655- }
656- }
657- </a >
652+ <a >Event Timeline </a >
658653 </span > ++
659654 <div id =" task-assignment-timeline" class =" collapsed" >
655+ {
656+ if (MAX_TIMELINE_TASKS < numEffectiveTasks) {
657+ <strong >
658+ This stage has more than the maximum number of tasks that can be shown in the
659+ visualization! Only the first {MAX_TIMELINE_TASKS } tasks
660+ (of {numEffectiveTasks} total) are shown.
661+ </strong >
662+ } else {
663+ Seq .empty
664+ }
665+ }
660666 <div class =" control-panel" >
661667 <div id =" task-assignment-timeline-zoom-lock" >
662668 <input type =" checkbox" ></input >
@@ -667,7 +673,7 @@ private[ui] class StagePage(parent: StagesTab) extends WebUIPage("stage") {
667673 </div > ++
668674 <script type =" text/javascript" >
669675 {Unparsed (s " drawTaskAssignmentTimeline( " +
670- s " ${ groupArrayStr} , ${ executorsArrayStr} , ${ minLaunchTime} , ${ maxZoom} ) " )}
676+ s " $groupArrayStr, $executorsArrayStr, $minLaunchTime, $maxZoom) " )}
671677 </script >
672678 }
673679
0 commit comments