You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by pa...@apache.org on 2026/04/15 16:53:54 UTC
(flink) 02/02: [FLINK-38898][runtime-web] Refactor Rescale Details related parts into templates for reusing in Rescales/Overview and Rescales/History
This is an automated email from the ASF dual-hosted git repository.
panyuepeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
commit 096f031b9502337979c06f067c1289fe03173aaf
Author: och5351 <dh...@gmail.com>
AuthorDate: Wed Apr 15 19:35:12 2026 +0900
[FLINK-38898][runtime-web] Refactor Rescale Details related parts into templates for reusing in Rescales/Overview and Rescales/History
Co-authored-by: Yuepeng Pan <hi...@gmail.com>
Co-authored-by: Matthias Pohl <mp...@confluent.io>
---
.../pages/job/rescales/job-rescales.component.html | 515 +++++----------------
.../pages/job/rescales/job-rescales.component.less | 42 --
2 files changed, 103 insertions(+), 454 deletions(-)
diff --git a/flink-runtime-web/web-dashboard/src/app/pages/job/rescales/job-rescales.component.html b/flink-runtime-web/web-dashboard/src/app/pages/job/rescales/job-rescales.component.html
index 1b4342fac02..5bc5c64f5de 100644
--- a/flink-runtime-web/web-dashboard/src/app/pages/job/rescales/job-rescales.component.html
+++ b/flink-runtime-web/web-dashboard/src/app/pages/job/rescales/job-rescales.component.html
@@ -24,9 +24,9 @@
(nzSelectedIndexChange)="refresh()"
>
<nz-tab nzTitle="Overview">
- <!-- Reusable template for rescale details -->
- <ng-template #rescaleDetailsTemplate let-rescale="rescale">
- <div class="overview-rescale-section">
+ <!-- Reusable template for rescale details - unified version with containerClass parameter -->
+ <ng-template #rescaleDetailsTemplate let-rescale="rescale" let-containerClass="containerClass">
+ <div [class]="containerClass || 'rescale-details-box'">
<h3><strong>Rescale Details</strong></h3>
<div>
<span>
@@ -251,185 +251,114 @@
</div>
</ng-template>
- <ng-container *ngIf="rescalesOverview">
- <div class="rescale-header rescale-counts-header">
- <h3><strong>Rescale Counts</strong></h3>
- <span class="rescale-time-info">
+ <!-- Reusable template for latest rescale section (like checkpoint component) -->
+ <ng-template #latestRescaleTemplate let-title="title" let-rescale="rescale">
+ <tr>
+ <td>
+ <strong>{{ title }}</strong>
+ </td>
+ <td *ngIf="rescale">
<span>
- <strong>Total:</strong>
- {{ getTotalRescaleCount() }}
+ <strong>Start Time:</strong>
+ {{ rescale.startTimestampInMillis | date: 'yyyy-MM-dd HH:mm:ss.SSS' }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
- <strong>In Progress:</strong>
- {{ rescalesOverview.rescalesCounts.inProgress }}
+ <strong>End Time:</strong>
+ {{
+ rescale.endTimestampInMillis
+ ? (rescale.endTimestampInMillis | date: 'yyyy-MM-dd HH:mm:ss.SSS')
+ : '-'
+ }}
</span>
<nz-divider nzType="vertical"></nz-divider>
<span>
- <strong>Completed:</strong>
- {{ rescalesOverview.rescalesCounts.completed }}
+ <strong>Duration:</strong>
+ {{
+ (rescale.endTimestampInMillis || Date.now()) - rescale.startTimestampInMillis
+ | humanizeDuration
+ }}
</span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Failed:</strong>
- {{ rescalesOverview.rescalesCounts.failed }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Ignored:</strong>
- {{ rescalesOverview.rescalesCounts.ignored }}
- </span>
- </span>
- </div>
- <nz-divider></nz-divider>
-
- <ng-container *ngIf="rescalesOverview.latest.completed">
- <div class="rescale-header">
- <h3><strong>Latest Completed Rescale</strong></h3>
- <span class="rescale-time-info">
- <span>
- <strong>Start Time:</strong>
- {{
- rescalesOverview.latest.completed.startTimestampInMillis
- | date: 'yyyy-MM-dd HH:mm:ss.SSS'
- }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>End Time:</strong>
- {{
- rescalesOverview.latest.completed.endTimestampInMillis
- ? (rescalesOverview.latest.completed.endTimestampInMillis
- | date: 'yyyy-MM-dd HH:mm:ss.SSS')
- : '-'
- }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Duration:</strong>
- {{
- (rescalesOverview.latest.completed.endTimestampInMillis || Date.now()) -
- rescalesOverview.latest.completed.startTimestampInMillis | humanizeDuration
- }}
- </span>
- </span>
- </div>
- <nz-divider></nz-divider>
- <ng-container
- *ngTemplateOutlet="
- rescaleDetailsTemplate;
- context: { rescale: rescalesOverview.latest.completed }
- "
- ></ng-container>
- </ng-container>
- <ng-container *ngIf="!rescalesOverview.latest.completed">
- <div class="rescale-header">
- <h3><strong>Latest Completed Rescale</strong></h3>
- <span class="rescale-time-info">None</span>
- </div>
- <nz-divider></nz-divider>
- </ng-container>
-
- <ng-container *ngIf="rescalesOverview.latest.ignored">
- <div class="rescale-header">
- <h3><strong>Latest Ignored Rescale</strong></h3>
- <span class="rescale-time-info">
- <span>
- <strong>Start Time:</strong>
- {{
- rescalesOverview.latest.ignored.startTimestampInMillis
- | date: 'yyyy-MM-dd HH:mm:ss.SSS'
- }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>End Time:</strong>
- {{
- rescalesOverview.latest.ignored.endTimestampInMillis
- ? (rescalesOverview.latest.ignored.endTimestampInMillis
- | date: 'yyyy-MM-dd HH:mm:ss.SSS')
- : '-'
- }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Duration:</strong>
- {{
- (rescalesOverview.latest.ignored.endTimestampInMillis || Date.now()) -
- rescalesOverview.latest.ignored.startTimestampInMillis | humanizeDuration
- }}
- </span>
- </span>
- </div>
- <nz-divider></nz-divider>
- <ng-container
- *ngTemplateOutlet="
- rescaleDetailsTemplate;
- context: { rescale: rescalesOverview.latest.ignored }
- "
- ></ng-container>
- </ng-container>
- <ng-container *ngIf="!rescalesOverview.latest.ignored">
- <div class="rescale-header">
- <h3><strong>Latest Ignored Rescale</strong></h3>
- <span class="rescale-time-info">None</span>
- </div>
- <nz-divider></nz-divider>
- </ng-container>
+ </td>
+ <td *ngIf="!rescale">None</td>
+ </tr>
+ <tr *ngIf="rescale">
+ <td colspan="2" class="collapse-td">
+ <ng-container
+ *ngTemplateOutlet="rescaleDetailsTemplate; context: { rescale: rescale }"
+ ></ng-container>
+ </td>
+ </tr>
+ </ng-template>
- <ng-container *ngIf="rescalesOverview.latest.failed">
- <div class="rescale-header">
- <h3><strong>Latest Failed Rescale</strong></h3>
- <span class="rescale-time-info">
- <span>
- <strong>Start Time:</strong>
- {{
- rescalesOverview.latest.failed.startTimestampInMillis
- | date: 'yyyy-MM-dd HH:mm:ss.SSS'
- }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>End Time:</strong>
- {{
- rescalesOverview.latest.failed.endTimestampInMillis
- ? (rescalesOverview.latest.failed.endTimestampInMillis
- | date: 'yyyy-MM-dd HH:mm:ss.SSS')
- : '-'
- }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Duration:</strong>
- {{
- (rescalesOverview.latest.failed.endTimestampInMillis || Date.now()) -
- rescalesOverview.latest.failed.startTimestampInMillis | humanizeDuration
- }}
- </span>
- </span>
- </div>
- <nz-divider></nz-divider>
- <ng-container
- *ngTemplateOutlet="
- rescaleDetailsTemplate;
- context: { rescale: rescalesOverview.latest.failed }
- "
- ></ng-container>
- </ng-container>
- <ng-container *ngIf="!rescalesOverview.latest.failed">
- <div class="rescale-header">
- <h3><strong>Latest Failed Rescale</strong></h3>
- <span class="rescale-time-info">None</span>
- </div>
- <nz-divider></nz-divider>
- </ng-container>
- </ng-container>
+ <nz-table
+ class="no-border small"
+ [nzData]="rescalesOverview ? [''] : []"
+ [nzSize]="'small'"
+ [nzFrontPagination]="false"
+ [nzShowPagination]="false"
+ >
+ <tbody>
+ <ng-container *ngIf="rescalesOverview">
+ <tr>
+ <td><strong>Rescale Counts</strong></td>
+ <td>
+ <span>
+ <strong>Total:</strong>
+ {{ getTotalRescaleCount() }}
+ </span>
+ <nz-divider nzType="vertical"></nz-divider>
+ <span>
+ <strong>In Progress:</strong>
+ {{ rescalesOverview.rescalesCounts.inProgress }}
+ </span>
+ <nz-divider nzType="vertical"></nz-divider>
+ <span>
+ <strong>Completed:</strong>
+ {{ rescalesOverview.rescalesCounts.completed }}
+ </span>
+ <nz-divider nzType="vertical"></nz-divider>
+ <span>
+ <strong>Failed:</strong>
+ {{ rescalesOverview.rescalesCounts.failed }}
+ </span>
+ <nz-divider nzType="vertical"></nz-divider>
+ <span>
+ <strong>Ignored:</strong>
+ {{ rescalesOverview.rescalesCounts.ignored }}
+ </span>
+ </td>
+ </tr>
+ <ng-container
+ *ngTemplateOutlet="
+ latestRescaleTemplate;
+ context: {
+ title: 'Latest Completed Rescale',
+ rescale: rescalesOverview.latest.completed
+ }
+ "
+ ></ng-container>
+ <ng-container
+ *ngTemplateOutlet="
+ latestRescaleTemplate;
+ context: { title: 'Latest Ignored Rescale', rescale: rescalesOverview.latest.ignored }
+ "
+ ></ng-container>
+ <ng-container
+ *ngTemplateOutlet="
+ latestRescaleTemplate;
+ context: { title: 'Latest Failed Rescale', rescale: rescalesOverview.latest.failed }
+ "
+ ></ng-container>
+ </ng-container>
+ </tbody>
+ </nz-table>
</nz-tab>
<nz-tab nzTitle="History">
<nz-table
class="no-border small"
[nzSize]="'small'"
- [nzData]="jobRescaleDetails || []"
+ [nzData]="rescalesHistory || []"
[nzFrontPagination]="false"
[nzShowPagination]="false"
>
@@ -524,250 +453,12 @@
<tr [nzExpand]="isExpanded(jobRescaleDetails.rescaleUuid)">
<td colspan="10" *ngIf="isExpanded(jobRescaleDetails.rescaleUuid)" class="collapse-td">
<div class="rescale-details-wrapper">
- <div class="rescale-details-box">
- <h3><strong>Rescale Details</strong></h3>
- <tr>
- <td>
- <span>
- <strong>Rescale UUID:</strong>
- {{ truncateUuid(jobRescaleDetails.rescaleUuid) }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Requirements ID:</strong>
- {{ truncateUuid(jobRescaleDetails.resourceRequirementsUuid) }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Attempt ID:</strong>
- {{ jobRescaleDetails.rescaleAttemptId }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Trigger Cause:</strong>
- {{ jobRescaleDetails.triggerCause }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Terminal State:</strong>
- {{ jobRescaleDetails?.terminalState || '-' }}
- </span>
- <nz-divider nzType="vertical"></nz-divider>
- <span>
- <strong>Terminal Reason:</strong>
- {{ jobRescaleDetails?.terminatedReason || '-' }}
- </span>
- </td>
- </tr>
- <ng-container *ngIf="getDetail(jobRescaleDetails.rescaleUuid) as detail">
- <nz-table
- class="small"
- [nzData]="detail.vertices | keyvalue"
- [nzSize]="'small'"
- [nzFrontPagination]="false"
- [nzShowPagination]="false"
- [nzTitle]="verticesTitle"
- [nzBordered]="true"
- >
- <thead>
- <tr>
- <th
- nz-tooltip
- nzTooltipTitle="The unique ID of target JobVertex consists of 32 hexadecimal characters"
- >
- <strong>ID</strong>
- </th>
- <th nz-tooltip nzTooltipTitle="The short name of target vertex">
- <strong>Name</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The previous parallelism of target vertex before the current rescale"
- >
- <strong>Previous Parallelism</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The acquired parallelism of target vertex after the current rescale"
- >
- <strong>Acquired Parallelism</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The desired parallelism of the target vertex"
- >
- <strong>Desired Parallelism</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The minimal parallelism of target vertex to run"
- >
- <strong>Sufficient Parallelism</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The unique ID of the slot sharing group consists of 32 hexadecimal characters"
- >
- <strong>Slot Sharing Group ID</strong>
- </th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let vertex of detail.vertices | keyvalue">
- <td nz-tooltip [nzTooltipTitle]="vertex.value.jobVertexId">
- {{ truncateUuid(vertex.value.jobVertexId) }}
- </td>
- <td nz-tooltip [nzTooltipTitle]="vertex.value.jobVertexName">
- {{ truncateName(vertex.value.jobVertexName) }}
- </td>
- <td>{{ vertex.value.preRescaleParallelism }}</td>
- <td>{{ vertex.value.postRescaleParallelism || '-' }}</td>
- <td>{{ vertex.value.desiredParallelism }}</td>
- <td>{{ vertex.value.sufficientParallelism }}</td>
- <td nz-tooltip [nzTooltipTitle]="vertex.value.slotSharingGroupId">
- {{ truncateUuid(vertex.value.slotSharingGroupId) }}
- </td>
- </tr>
- </tbody>
- </nz-table>
-
- <nz-table
- class="small"
- [nzData]="detail.slots | keyvalue"
- [nzSize]="'small'"
- [nzFrontPagination]="false"
- [nzShowPagination]="false"
- [nzTitle]="slotsTitle"
- [nzBordered]="true"
- >
- <thead>
- <tr>
- <th
- nz-tooltip
- nzTooltipTitle="The ID of the slot sharing group to which the slot belongs consists of 32 hexadecimal characters"
- >
- <strong>Slot Sharing Group ID</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The name of the slot sharing group to which the slot belongs"
- >
- <strong>Slot Sharing Group Name</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The previous number of slots before the rescale"
- >
- <strong>Previous Slots</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The acquired number of slots after the rescale"
- >
- <strong>Acquired Slots</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The desired number of slots of the rescale"
- >
- <strong>Desired Slots</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The minimal number of slots to deploy tasks in the rescale"
- >
- <strong>Sufficient Slots</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The required resource profile of the slot sharing group in the rescale"
- >
- <strong>Required Profile</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The acquired resource profile of the slot sharing group in the rescale"
- >
- <strong>Acquired Profile</strong>
- </th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let slot of detail.slots | keyvalue">
- <td nz-tooltip [nzTooltipTitle]="slot.value.slotSharingGroupId">
- {{ truncateUuid(slot.value.slotSharingGroupId) }}
- </td>
- <td>{{ slot.value.slotSharingGroupName }}</td>
- <td>{{ slot.value.preRescaleSlots }}</td>
- <td>{{ slot.value.postRescaleSlots || '-' }}</td>
- <td>{{ slot.value.desiredSlots }}</td>
- <td>{{ slot.value.minimalRequiredSlots }}</td>
- <td>
- <pre style="margin: 0">{{
- slot.value.requestResourceProfile | json
- }}</pre>
- </td>
- <td>
- <pre style="margin: 0">{{
- slot.value.acquiredResourceProfile | json
- }}</pre>
- </td>
- </tr>
- </tbody>
- </nz-table>
-
- <nz-table
- class="small"
- [nzData]="detail.schedulerStates"
- [nzSize]="'small'"
- [nzFrontPagination]="false"
- [nzShowPagination]="false"
- [nzTitle]="schedulerStatesTitle"
- [nzBordered]="true"
- >
- <thead>
- <tr>
- <th nz-tooltip nzTooltipTitle="The scheduler state name">
- <strong>State</strong>
- </th>
- <th nz-tooltip nzTooltipTitle="The time to enter the state">
- <strong>Enter Time</strong>
- </th>
- <th nz-tooltip nzTooltipTitle="The time to leave the state">
- <strong>Leave Time</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The duration time from enter time to leave time of the state"
- >
- <strong>Duration</strong>
- </th>
- <th
- nz-tooltip
- nzTooltipTitle="The exception information about current rescale during the state"
- >
- <strong>Exception</strong>
- </th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let state of detail.schedulerStates">
- <td>{{ state.state }}</td>
- <td>
- {{ state.enterTimestampInMillis | date: 'yyyy-MM-dd HH:mm:ss.SSS' }}
- </td>
- <td>
- {{ state.leaveTimestampInMillis | date: 'yyyy-MM-dd HH:mm:ss.SSS' }}
- </td>
- <td>{{ state.durationInMillis | humanizeDuration }}</td>
- <td>{{ state.stringifiedException }}</td>
- </tr>
- </tbody>
- </nz-table>
- </ng-container>
-
- <div *ngIf="!getDetail(jobRescaleDetails.rescaleUuid)">Loading...</div>
- </div>
+ <ng-container
+ *ngTemplateOutlet="
+ rescaleDetailsTemplate;
+ context: { rescale: jobRescaleDetails, containerClass: 'rescale-details-box' }
+ "
+ ></ng-container>
</div>
</td>
</tr>
diff --git a/flink-runtime-web/web-dashboard/src/app/pages/job/rescales/job-rescales.component.less b/flink-runtime-web/web-dashboard/src/app/pages/job/rescales/job-rescales.component.less
index a5ad73dde77..aa43d203d71 100644
--- a/flink-runtime-web/web-dashboard/src/app/pages/job/rescales/job-rescales.component.less
+++ b/flink-runtime-web/web-dashboard/src/app/pages/job/rescales/job-rescales.component.less
@@ -31,28 +31,6 @@
> nz-divider {
margin: 8px 0;
}
-
- .rescale-header {
- display: flex;
- align-items: center;
- margin-top: 8px;
- margin-bottom: 8px;
-
- h3 {
- flex-shrink: 0;
- width: 280px;
- margin: 0;
- }
-
- .rescale-time-info {
- color: rgba(0, 0, 0, 0.85);
- font-size: 14px;
- }
-
- &.rescale-counts-header {
- margin-top: -2px;
- }
- }
}
.ant-tabs-nav-list {
@@ -95,26 +73,6 @@ nz-empty {
padding: 24px;
}
-.overview-rescale-section {
- margin: 16px 0;
- padding: 16px;
- border: 1px solid #f0f0f0;
- background-color: #fff;
-
- h3 {
- margin-top: 0;
- margin-bottom: 8px;
- }
-
- nz-table {
- margin-bottom: 16px;
-
- &:last-child {
- margin-bottom: 0;
- }
- }
-}
-
.rescale-details-wrapper {
display: block;
box-sizing: border-box;