| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| --> |
| <div ng-if="checkpoint"> |
| <table class="table table-inner"> |
| <thead> |
| <tr> |
| <td><strong>ID</strong></td> |
| <td><strong>Status</strong></td> |
| <td><strong>Acknowledged</strong></td> |
| <td><strong>Trigger Time</strong></td> |
| <td><strong>Latest Acknowledgement</strong></td> |
| <td ng-if="checkpoint['failure_timestamp']"><strong>Failure Time</strong></td> |
| <td><strong>End to End Duration</strong></td> |
| <td><strong>State Size</strong></td> |
| <td><strong>Buffered During Alignment</strong></td> |
| <td ng-if="checkpoint['status'] == 'COMPLETED'"><strong>Discarded</strong></td> |
| <td ng-if="checkpoint['external_path']"><strong>Path</strong></td> |
| <td ng-if="checkpoint['failure_message']"><strong>Failure Message</strong></td> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td>{{ checkpoint['id'] }}</td> |
| <td ng-if="checkpoint['status'] == 'IN_PROGRESS'"><i aria-hidden="true" class="fa fa-circle-o-notch fa-spin fa-fw"></i> In progress <i ng-if="checkpoint['is_savepoint']">savepoint</i></td> |
| <td ng-if="checkpoint['status'] == 'COMPLETED'"><i aria-hidden="true" class="fa fa-check"></i> Completed <i ng-if="checkpoint['is_savepoint']">savepoint</i></td> |
| <td ng-if="checkpoint['status'] == 'FAILED'"><i aria-hidden="true" class="fa fa-remove"></i> Failed <i ng-if="checkpoint['is_savepoint']">savepoint</i></td> |
| <td>{{ checkpoint['num_acknowledged_subtasks'] }}/{{ checkpoint['num_subtasks'] }} ({{ checkpoint['num_acknowledged_subtasks']/checkpoint['num_subtasks'] | percentage }})</td> |
| <td>{{ checkpoint['trigger_timestamp'] | amDateFormat:'H:mm:ss' }}</td> |
| <td ng-if="checkpoint['latest_ack_timestamp'] >= 0">{{ checkpoint['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}</td> |
| <td ng-if="checkpoint['latest_ack_timestamp'] < 0">n/a</td> |
| <td ng-if="checkpoint['failure_timestamp']">{{ checkpoint['failure_timestamp'] | amDateFormat:'H:mm:ss' }}</td> |
| <td ng-if="checkpoint['end_to_end_duration'] >= 0">{{ checkpoint['end_to_end_duration'] | humanizeDuration }}</td> |
| <td ng-if="heckpoint['end_to_end_duration'] < 0">n/a</td> |
| <td>{{ checkpoint['state_size'] | humanizeBytes }}</td> |
| <td> {{ checkpoint['alignment_buffered'] | humanizeBytes }}</td> |
| <td ng-if="checkpoint['status'] == 'COMPLETED'"><span ng-if="checkpoint['discarded']">Yes</span><span ng-if="!checkpoint['discarded']">No</span></td> |
| <td ng-if="checkpoint['external_path']">{{ checkpoint['external_path'] }}</td> |
| <td ng-if="checkpoint['status'] == 'FAILED' && checkpoint['failure_message']">{{ checkpoint['failure_message'] }}</td> |
| <td ng-if="checkpoint['status'] == 'FAILED' && !checkpoint['failure_message']">n/a</td> |
| </tr> |
| </tbody> |
| </table> |
| <h4>Operators</h4> |
| <table class="table table-body-hover table-clickable table-activable subtask-details"> |
| <thead> |
| <tr> |
| <td><strong>Name</strong></td> |
| <td><strong>Acknowledged</strong></td> |
| <td><strong>Latest Acknowledgment</strong></td> |
| <td><strong>End to End Duration</strong></td> |
| <td><strong>State Size</strong></td> |
| <td><strong>Buffered During Alignment</strong></td> |
| <td></td> |
| </tr> |
| </thead> |
| <tbody ng-repeat="v in job.vertices" ng-class="{ active: v.id == nodeid }" ng-click="changeNode(v.id)"> |
| <tr ng-if="v.type == 'regular'"> |
| <td>{{ v.name | humanizeText }}</td> |
| <td>{{ checkpoint['tasks'][v.id]['num_acknowledged_subtasks'] }}/{{ checkpoint['tasks'][v.id]['num_subtasks'] }} ({{ checkpoint['tasks'][v.id]['num_acknowledged_subtasks']/checkpoint['tasks'][v.id]['num_subtasks'] | percentage }})</td> |
| <td ng-if="checkpoint['tasks'][v.id]['latest_ack_timestamp'] >= 0">{{ checkpoint['tasks'][v.id]['latest_ack_timestamp'] | amDateFormat:'H:mm:ss' }}</td> |
| <td ng-if="checkpoint['tasks'][v.id]['latest_ack_timestamp'] < 0">n/a</td> |
| <td ng-if="checkpoint['tasks'][v.id]['end_to_end_duration'] >= 0">{{ checkpoint['tasks'][v.id]['end_to_end_duration'] | humanizeDuration }}</td> |
| <td ng-if="checkpoint['tasks'][v.id]['end_to_end_duration'] < 0">n/a</td> |
| <td>{{ checkpoint['tasks'][v.id]['state_size'] | humanizeBytes }}</td> |
| <td>{{ checkpoint['tasks'][v.id]['alignment_buffered'] | humanizeBytes }}</td> |
| <td> |
| <div ng-if="!nodeid || v.id != nodeid"><a ng-click="toggleFold()" class="btn btn-default">Show Subtasks <i class="fa fa-chevron-down"></i></a></div> |
| <div ng-if="nodeid && v.id == nodeid"><a ng-click="toggleFold()" class="btn btn-default">Hide Subtasks <i class="fa fa-chevron-up"></i></a></div> |
| </td> |
| </tr> |
| <tr ng-if="nodeid && v.id == nodeid"> |
| <td colspan="7"> |
| <table class="table table-body-hover table-inner subtask-details"> |
| <thead ng-if="subtaskDetails[v.id]['summary']"> |
| <tr> |
| <td></td> |
| <td></td> |
| <td><strong>End to End Duration</strong></td> |
| <td><strong>State Size</strong></td> |
| <td><strong>Checkpoint Duration (Sync)</strong></td> |
| <td><strong>Checkpoint Duration (Async)</strong></td> |
| <td><strong>Alignment Buffered</strong></td> |
| <td><strong>Alignment Duration</strong></td> |
| </tr> |
| <tr> |
| <td></td> |
| <td><strong>Minimum</strong></td> |
| <td>{{ subtaskDetails[v.id]['summary']['end_to_end_duration']['min'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['state_size']['min'] | humanizeBytes }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['sync']['min'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['async']['min'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['alignment']['buffered']['min'] | humanizeBytes }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['alignment']['duration']['min'] | humanizeDuration }}</td> |
| </tr> |
| <tr> |
| <td></td> |
| <td><strong>Average</strong></td> |
| <td>{{ subtaskDetails[v.id]['summary']['end_to_end_duration']['avg'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['state_size']['avg'] | humanizeBytes }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['sync']['avg'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['async']['avg'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['alignment']['buffered']['avg'] | humanizeBytes }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['alignment']['duration']['avg'] | humanizeDuration }}</td> |
| </tr> |
| <tr> |
| <td></td> |
| <td><strong>Maximum</strong></td> |
| <td>{{ subtaskDetails[v.id]['summary']['end_to_end_duration']['max'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['state_size']['max'] | humanizeBytes }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['sync']['max'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['checkpoint_duration']['async']['max'] | humanizeDuration }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['alignment']['buffered']['max'] | humanizeBytes }}</td> |
| <td>{{ subtaskDetails[v.id]['summary']['alignment']['duration']['max'] | humanizeDuration }}</td> |
| </tr> |
| <tr class="blank"> |
| <td colspan="8"></td> |
| </tr> |
| </thead> |
| <thead> |
| <tr> |
| <td><strong>Subtask #</strong></td> |
| <td><strong>Acknowledgement Time</strong></td> |
| <td><strong>End to End Duration</strong></td> |
| <td><strong>State Size</strong></td> |
| <td><strong>Checkpoint Duration (Sync)</strong></td> |
| <td><strong>Checkpoint Duration (Async)</strong></td> |
| <td><strong>Alignment Buffered</strong></td> |
| <td><strong>Alignment Duration</strong></td> |
| </tr> |
| </thead> |
| <tbody> |
| <tr ng-repeat="subtask in subtaskDetails[v.id]['subtasks']"> |
| <td>{{ subtask['index'] + 1 }}</td> |
| <td ng-if-start="subtask['status'] == 'completed'">{{ subtask['ack_timestamp'] | amDateFormat:'H:mm:ss' }}</td> |
| <td>{{ subtask['end_to_end_duration'] | humanizeDuration }}</td> |
| <td>{{ subtask['state_size'] | humanizeBytes }}</td> |
| <td>{{ subtask['checkpoint']['sync'] | humanizeDuration }}</td> |
| <td>{{ subtask['checkpoint']['async'] | humanizeDuration }}</td> |
| <td>{{ subtask['alignment']['buffered'] | humanizeBytes}}</td> |
| <td ng-if-end="ng-if-end">{{ subtask['alignment']['duration'] | humanizeDuration }}</td> |
| <td ng-if="subtask['status'] == 'pending_or_failed'" colspan="7">n/a</td> |
| </tr> |
| </tbody> |
| </table> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| <div ng-if="!checkpoint"> |
| <p ng-if="unknown_checkpoint" role="alert" class="alert alert-danger"><strong>Unknown or expired checkpoint ID.</strong></p> |
| <p ng-if="!unknown_checkpoint" role="alert" class="alert alert-info"><strong>Waiting for response from JobManager with checkpoint details...</strong> <i aria-hidden="true" class="fa fa-circle-o-notch fa-spin fa-fw"></i> |
| </p> |
| </div> |