Web console: fix progress indication for table input (#17334) (#17505)

* fix porgress indication for table input

* fix snapshot

Co-authored-by: Vadim Ogievetsky <vadim@ogievetsky.com>
This commit is contained in:
Clint Wylie 2024-11-22 11:50:38 -08:00 committed by GitHub
parent c5d0fcde50
commit b1802c4ff3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 51 additions and 20 deletions

View File

@ -32,7 +32,7 @@ describe('aggregateSortProgressCounters', () => {
},
{
type: 'sortProgress',
totalMergingLevels: 4,
totalMergingLevels: -1,
levelToTotalBatches: { 0: 2, 1: 4, 2: 6, 3: 5 },
levelToMergedBatches: { 0: 2, 1: 4, 2: 6, 3: 5 },
totalMergersForUltimateLevel: 1,
@ -41,7 +41,6 @@ describe('aggregateSortProgressCounters', () => {
).toEqual({
totalMergingLevels: {
'2': 1,
'4': 1,
},
levelToBatches: {
'0': {

View File

@ -200,7 +200,10 @@ export function aggregateSortProgressCounters(
sortProgressCounters: SortProgressCounter[],
): AggregatedSortProgress {
return {
totalMergingLevels: countBy(sortProgressCounters, c => c.totalMergingLevels),
totalMergingLevels: countBy(
sortProgressCounters.filter(c => c.totalMergingLevels >= 0),
c => c.totalMergingLevels,
),
levelToBatches: groupByAsMap(
sortProgressCounters.flatMap(c =>
Object.entries(c.levelToMergedBatches).map(([level, merged]) => [
@ -430,9 +433,8 @@ export class Stages {
if (inputFileCount) {
// If we know how many files there are base the progress on how many files were read
return (
sum(input, (input, i) =>
input.type === 'external' ? this.getTotalCounterForStage(stage, `input${i}`, 'files') : 0,
) / inputFileCount
sum(input, (_, i) => this.getTotalCounterForStage(stage, `input${i}`, 'files')) /
inputFileCount
);
} else {
// Otherwise, base it on the stage input divided by the output of all non-broadcast input stages,

View File

@ -31,6 +31,11 @@
padding: 0;
}
}
.rt-th.wrapped,
.rt-td.wrapped {
white-space: normal;
}
}
&.padded-header .rt-thead .rt-th {

View File

@ -134,7 +134,7 @@ export const CurrentDartPanel = React.memo(function CurrentViberPanel(
const anonymous = w.identity === 'allowAll' && w.authenticator === 'allowAll';
return (
<Popover className="work-entry" key={w.sqlQueryId} position="left" content={menu}>
<div>
<div onDoubleClick={() => setShowSql(w.sql)}>
<div className="line1">
<Icon
className={'status-icon ' + w.state.toLowerCase()}

View File

@ -80,7 +80,7 @@ exports[`ExecutionStagesPane matches snapshot 1`] = `
"accessor": "stageNumber",
"className": "padded",
"id": "stage",
"width": 140,
"width": 160,
},
{
"Cell": [Function],
@ -102,7 +102,7 @@ exports[`ExecutionStagesPane matches snapshot 1`] = `
"accessor": [Function],
"className": "padded",
"id": "rows_processed",
"width": 160,
"width": 200,
},
{
"Cell": [Function],

View File

@ -125,6 +125,13 @@
vertical-align: top;
background: $dark-gray3;
}
.detail-counters-for-sort {
.count {
font-style: italic;
opacity: 0.8;
}
}
}
.cpu-label {

View File

@ -245,7 +245,7 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
Header: 'Worker',
id: 'worker',
accessor: d => d.index,
width: 100,
width: 95,
Cell({ value }) {
const taskId = `${execution.id}-worker${value}_0`;
return (
@ -270,7 +270,8 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
id: 'cpu',
accessor: d => d.cpu?.main?.cpu || 0,
className: 'padded',
width: 220,
width: 240,
show: stages.hasCounterForStage(stage, 'cpu'),
Cell({ original }) {
const cpuTotals = original.cpu || {};
return (
@ -310,7 +311,7 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
id: counterName,
accessor: d => d[counterName]!.rows,
className: 'padded',
width: 160,
width: 200,
Cell({ value, original }) {
const c = (original as SimpleWideCounter)[counterName]!;
return (
@ -397,12 +398,27 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
{
Header: `Counts`,
accessor: 'counts',
className: 'padded',
width: 180,
className: 'padded wrapped',
width: 300,
Cell({ value }) {
return Object.entries(value)
.map(([n, v]) => (Number(v) > 1 ? `${n} (${v})` : n))
.join(', ');
const entries = Object.entries(value);
if (!entries.length) return '-';
return (
<>
{entries.map(([n, v], i) => (
<>
<span
key={n}
data-tooltip={`${pluralIfNeeded(Number(v), 'worker')} reporting: ${n}`}
>
{n}
{Number(v) > 1 && <span className="count">{` (${v})`}</span>}
</span>
{i < entries.length - 1 && <span key={`${n}_sep`}>, </span>}
</>
))}
</>
);
},
},
]}
@ -686,7 +702,7 @@ ${title} uncompressed size: ${formatBytesCompact(
id: 'stage',
accessor: 'stageNumber',
className: 'padded',
width: 140,
width: 160,
Cell(props) {
const stage = props.original as StageDefinition;
const myError = error && error.stageNumber === stage.stageNumber;
@ -770,7 +786,7 @@ ${title} uncompressed size: ${formatBytesCompact(
id: 'rows_processed',
accessor: () => null,
className: 'padded',
width: 160,
width: 200,
Cell({ original }) {
const stage = original as StageDefinition;
const { input, broadcast } = stage.definition;

View File

@ -217,7 +217,9 @@ LIMIT 100`,
return (
<Popover className="work-entry" key={w.taskId} position="left" content={menu}>
<div
data-tooltip={w.errorMessage}
data-tooltip={
`ID: ${w.taskId}` + (w.errorMessage ? `\n\nError:\n${w.errorMessage}` : '')
}
onDoubleClick={() => onExecutionDetails(w.taskId)}
>
<div className="line1">