Skip to content

Commit 444b4f4

Browse files
kosztiraunaqmorarka
authored andcommitted
Add query stages view to Preview Web UI
1 parent c2b309a commit 444b4f4

File tree

4 files changed

+886
-1
lines changed

4 files changed

+886
-1
lines changed

core/trino-web-ui/src/main/resources/webapp-preview/src/api/webapp/api.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,43 @@ export interface QueryStageStats {
242242
bufferedDataSize: string
243243
outputDataSize: string
244244
outputPositions: number
245+
totalBlockedTime: string
246+
failedScheduledTime: string
247+
failedCpuTime: string
248+
cumulativeUserMemory: number
249+
totalBufferedBytes: number
250+
failedCumulativeUserMemory: number
251+
peakUserMemoryReservation: string
252+
}
253+
254+
export interface QueryTask {
255+
lastHeartbeat: string
256+
needsPlan: boolean
257+
estimatedMemory: string
258+
outputBuffers: {
259+
totalBufferedBytes: number
260+
}
261+
stats: {
262+
createTime: string
263+
elapsedTime: string
264+
fullyBlocked: boolean
265+
blockedDrivers: number
266+
completedDrivers: number
267+
queuedDrivers: number
268+
peakUserMemoryReservation: string
269+
runningDrivers: number
270+
processedInputDataSize: string
271+
processedInputPositions: number
272+
totalCpuTime: string
273+
totalScheduledTime: string
274+
userMemoryReservation: string
275+
}
276+
taskStatus: {
277+
nodeId: string
278+
taskId: string
279+
self: string
280+
state: string
281+
}
245282
}
246283

247284
export interface QueryStage {
@@ -250,6 +287,7 @@ export interface QueryStage {
250287
stageId: string
251288
state: string
252289
stageStats: QueryStageStats
290+
tasks: QueryTask[]
253291
}
254292

255293
export interface QueryStages {
@@ -270,6 +308,10 @@ export interface QueryStatusInfo extends QueryInfoBase {
270308
stages: QueryStages
271309
}
272310

311+
export interface WorkerTaskInfo {
312+
dummy: string
313+
}
314+
273315
export async function statsApi(): Promise<ApiResponse<Stats>> {
274316
return await api.get<Stats>('/ui/api/stats')
275317
}
@@ -282,6 +324,10 @@ export async function workerStatusApi(nodeId: string): Promise<ApiResponse<Worke
282324
return await api.get<WorkerStatusInfo>(`/ui/api/worker/${nodeId}/status`)
283325
}
284326

327+
export async function workerTaskApi(nodeId: string, taskId: string): Promise<ApiResponse<WorkerTaskInfo>> {
328+
return await api.get<WorkerTaskInfo>(`/ui/api/worker/${nodeId}/task/${taskId}`)
329+
}
330+
285331
export async function queryApi(): Promise<ApiResponse<QueryInfo[]>> {
286332
return await api.get<QueryInfo[]>('/ui/api/query')
287333
}

core/trino-web-ui/src/main/resources/webapp-preview/src/components/QueryOverview.tsx

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
} from '@mui/material'
3030
import { SparkLineChart } from '@mui/x-charts/SparkLineChart'
3131
import { Texts } from '../constant.ts'
32-
import { StackInfo, queryStatusApi, QueryStatusInfo, Session } from '../api/webapp/api.ts'
32+
import { StackInfo, queryStatusApi, QueryStatusInfo, QueryStage, QueryStages, Session } from '../api/webapp/api.ts'
3333
import { ApiResponse } from '../api/base.ts'
3434
import {
3535
addToHistory,
@@ -40,10 +40,12 @@ import {
4040
parseDataSize,
4141
parseDuration,
4242
} from '../utils/utils.ts'
43+
import { QueryStageCard } from './QueryStageCard'
4344
import { CodeBlock } from './CodeBlock.tsx'
4445

4546
interface IQueryStatus {
4647
info: QueryStatusInfo | null
48+
lastQueryStages: QueryStages | null
4749

4850
lastScheduledTime: number
4951
lastCpuTime: number
@@ -66,6 +68,7 @@ export const QueryOverview = () => {
6668
const { queryId } = useParams()
6769
const initialQueryStatus: IQueryStatus = {
6870
info: null,
71+
lastQueryStages: null,
6972

7073
lastScheduledTime: 0,
7174
lastCpuTime: 0,
@@ -117,6 +120,7 @@ export const QueryOverview = () => {
117120
const newQueryStatusInfo: QueryStatusInfo = apiResponse.data
118121
setQueryStatus((prevQueryStatus) => {
119122
let lastRefresh = prevQueryStatus.lastRefresh
123+
120124
const lastScheduledTime = prevQueryStatus.lastScheduledTime
121125
const lastCpuTime = prevQueryStatus.lastCpuTime
122126
const lastPhysicalInputReadTime = prevQueryStatus.lastPhysicalInputReadTime
@@ -205,6 +209,7 @@ export const QueryOverview = () => {
205209

206210
return {
207211
info: newQueryStatusInfo,
212+
lastQueryStages: newQueryStatusInfo.stages,
208213

209214
lastScheduledTime: parseDuration(newQueryStats.totalScheduledTime) || 0,
210215
lastCpuTime: parseDuration(newQueryStats.totalCpuTime) || 0,
@@ -416,6 +421,38 @@ export const QueryOverview = () => {
416421
}
417422
}
418423

424+
const renderStages = (taskRetriesEnabled: boolean) => {
425+
const stages = queryStatus.lastQueryStages?.stages
426+
427+
return (
428+
<Grid size={{ xs: 12 }}>
429+
<Box sx={{ pt: 2 }}>
430+
<Typography variant="h6">Stages</Typography>
431+
<Divider />
432+
433+
{stages ? (
434+
stages
435+
.slice()
436+
.sort((a, b) => a.stageId.localeCompare(b.stageId))
437+
.map((stage: QueryStage) => (
438+
<QueryStageCard
439+
key={stage.stageId}
440+
stage={stage}
441+
taskRetriesEnabled={taskRetriesEnabled}
442+
/>
443+
))
444+
) : (
445+
<>
446+
<Box sx={{ width: '100%', mt: 1 }}>
447+
<Alert severity="info">No stage information available.</Alert>
448+
</Box>
449+
</>
450+
)}
451+
</Box>
452+
</Grid>
453+
)
454+
}
455+
419456
const taskRetriesEnabled = queryStatus.info?.retryPolicy == 'TASK'
420457
return (
421458
<>
@@ -839,6 +876,7 @@ export const QueryOverview = () => {
839876
</Box>
840877
</Grid>
841878
{renderPreparedQuery()}
879+
{renderStages(taskRetriesEnabled)}
842880
</Grid>
843881
</Grid>
844882
)}

0 commit comments

Comments
 (0)