From 7ca3405bdb885957f08acd6aa555a4396d66f6b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien?= Date: Tue, 10 Oct 2023 08:47:18 -0400 Subject: [PATCH] More details and no extraneous SQL query for segments unless needed --- .../src/druid-models/execution/execution.ts | 38 +++++++++++++++---- .../helpers/execution/sql-task-execution.ts | 5 +++ .../execution-details-pane.tsx | 30 ++++++++++++++- .../execution-progress-bar-pane.tsx | 5 ++- .../ingest-success-pane.tsx | 5 ++- 5 files changed, 70 insertions(+), 13 deletions(-) diff --git a/web-console/src/druid-models/execution/execution.ts b/web-console/src/druid-models/execution/execution.ts index 83199f94c318..1899f1260724 100644 --- a/web-console/src/druid-models/execution/execution.ts +++ b/web-console/src/druid-models/execution/execution.ts @@ -164,6 +164,18 @@ function formatPendingMessage( } } +interface SegmentStatus { + duration: number; + onDemandSegments: number; + pendingSegments: number; + precachedSegments: number; + startTime: Date; + state: 'INIT' | 'WAITING' | 'SUCCESS'; + totalSegments: number; + unknownSegments: number; + usedSegments: number; +} + export interface ExecutionValue { engine: DruidEngine; id: string; @@ -182,7 +194,7 @@ export interface ExecutionValue { warnings?: ExecutionError[]; capacityInfo?: CapacityInfo; _payload?: MsqTaskPayloadResponse; - segmentStatus?: string; + segmentStatus?: SegmentStatus; } export class Execution { @@ -319,7 +331,7 @@ export class Execution { engine: 'sql-msq-task', id, status: Execution.normalizeTaskStatus(status), - segmentStatus: segmentLoaderStatus?.state, + segmentStatus: segmentLoaderStatus, startTime: isNaN(startTime.getTime()) ? undefined : startTime, duration: typeof durationMs === 'number' ? durationMs : undefined, usageInfo: getUsageInfoFromStatusPayload( @@ -376,7 +388,7 @@ export class Execution { public readonly error?: ExecutionError; public readonly warnings?: ExecutionError[]; public readonly capacityInfo?: CapacityInfo; - public readonly segmentStatus?: string; + public readonly segmentStatus?: SegmentStatus; public readonly _payload?: { payload: any; task: string }; @@ -539,19 +551,29 @@ export class Execution { public getSegmentStatusDescription() { const { segmentStatus } = this; - switch (segmentStatus) { + let label = ''; + + switch (segmentStatus?.state) { case 'INIT': - return 'Waiting for segments loading to start...'; + label = 'Waiting for segments loading to start...'; + break; case 'WAITING': - return 'Waiting for segments loading to complete...'; + label = 'Waiting for segments loading to complete...'; + break; case 'SUCCESS': - return 'Segments loaded successfully'; + label = 'Segments loaded successfully in ' + segmentStatus.duration + 'ms.'; + break; default: - return ''; + break; } + + return { + label, + ...segmentStatus, + }; } public isFullyComplete(): boolean { diff --git a/web-console/src/helpers/execution/sql-task-execution.ts b/web-console/src/helpers/execution/sql-task-execution.ts index ef4a077196ee..75b82d17b868 100644 --- a/web-console/src/helpers/execution/sql-task-execution.ts +++ b/web-console/src/helpers/execution/sql-task-execution.ts @@ -267,6 +267,11 @@ export async function updateExecutionWithDatasourceLoadedIfNeeded( return execution; } + // This means we don't have to perform the SQL query to check if the segments are loaded + if (execution.queryContext?.waitTillSegmentsLoad === true) { + return execution.markDestinationDatasourceLoaded(); + } + const endTime = execution.getEndTime(); if ( !endTime || // If endTime is not set (this is not expected to happen) then just bow out diff --git a/web-console/src/views/workbench-view/execution-details-pane/execution-details-pane.tsx b/web-console/src/views/workbench-view/execution-details-pane/execution-details-pane.tsx index 72a6350d7ba1..0f1200a8661f 100644 --- a/web-console/src/views/workbench-view/execution-details-pane/execution-details-pane.tsx +++ b/web-console/src/views/workbench-view/execution-details-pane/execution-details-pane.tsx @@ -23,7 +23,7 @@ import React, { useState } from 'react'; import { FancyTabPane } from '../../../components'; import type { Execution } from '../../../druid-models'; -import { pluralIfNeeded } from '../../../utils'; +import { formatDuration, formatDurationWithMs, pluralIfNeeded } from '../../../utils'; import { DestinationPagesPane } from '../destination-pages-pane/destination-pages-pane'; import { ExecutionErrorPane } from '../execution-error-pane/execution-error-pane'; import { ExecutionStagesPane } from '../execution-stages-pane/execution-stages-pane'; @@ -40,7 +40,8 @@ export type ExecutionDetailsTab = | 'result' | 'pages' | 'error' - | 'warnings'; + | 'warnings' + | 'segmentStatus'; interface ExecutionDetailsPaneProps { execution: Execution; @@ -53,6 +54,7 @@ export const ExecutionDetailsPane = React.memo(function ExecutionDetailsPane( ) { const { execution, initTab, goToTask } = props; const [activeTab, setActiveTab] = useState(initTab || 'general'); + const segmentStatusDescription = execution.getSegmentStatusDescription(); function renderContent() { switch (activeTab) { @@ -120,6 +122,25 @@ export const ExecutionDetailsPane = React.memo(function ExecutionDetailsPane( case 'warnings': return ; + case 'segmentStatus': + return ( + <> +

+ Duration:{' '} + {segmentStatusDescription.duration + ? formatDurationWithMs(segmentStatusDescription.duration) + : '-'} + {execution.duration + ? ` (query duration was ${formatDuration(execution.duration)})` + : ''} +

+

Total segments: {segmentStatusDescription.totalSegments ?? '-'}

+

Used segments: {segmentStatusDescription.usedSegments ?? '-'}

+

Precached segments: {segmentStatusDescription.precachedSegments ?? '-'}

+

On demand segments: {segmentStatusDescription.onDemandSegments ?? '-'}

+ + ); + default: return; } @@ -146,6 +167,11 @@ export const ExecutionDetailsPane = React.memo(function ExecutionDetailsPane( label: 'Native query', icon: IconNames.COG, }, + Boolean(execution.segmentStatus) && { + id: 'segmentStatus', + label: 'Segments', + icon: IconNames.HEAT_GRID, + }, execution.result && { id: 'result', label: 'Results', diff --git a/web-console/src/views/workbench-view/execution-progress-bar-pane/execution-progress-bar-pane.tsx b/web-console/src/views/workbench-view/execution-progress-bar-pane/execution-progress-bar-pane.tsx index fc6ace703175..4520c20a39b1 100644 --- a/web-console/src/views/workbench-view/execution-progress-bar-pane/execution-progress-bar-pane.tsx +++ b/web-console/src/views/workbench-view/execution-progress-bar-pane/execution-progress-bar-pane.tsx @@ -50,6 +50,9 @@ export const ExecutionProgressBarPane = React.memo(function ExecutionProgressBar const idx = stages ? stages.currentStageIndex() : -1; const waitingForSegments = stages && !execution.isWaitingForQuery(); + + const segmentStatusDescription = execution?.getSegmentStatusDescription(); + return (