From 49f46b9bd44ad0898e045382cec3831ad0f52248 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Wed, 19 Jul 2023 15:44:49 -0700 Subject: [PATCH 1/4] account for all canceled states --- web-console/src/druid-models/task/task.ts | 9 +++++++++ web-console/src/views/tasks-view/tasks-view.tsx | 16 +++++----------- .../recent-query-task-panel.tsx | 4 ++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/web-console/src/druid-models/task/task.ts b/web-console/src/druid-models/task/task.ts index 4bb04f0cd879..65dbb62c065f 100644 --- a/web-console/src/druid-models/task/task.ts +++ b/web-console/src/druid-models/task/task.ts @@ -16,11 +16,20 @@ * limitations under the License. */ +import { C } from '@druid-toolkit/query'; + import type { StageDefinition } from '../stages/stages'; export type TaskStatus = 'WAITING' | 'PENDING' | 'RUNNING' | 'FAILED' | 'SUCCESS'; export type TaskStatusWithCanceled = TaskStatus | 'CANCELED'; +export const TASK_CANCELED_ERROR_MESSAGES: string[] = [ + 'Shutdown request from user', + 'Canceled: Query canceled by user or by task shutdown.', +]; + +export const TASK_CANCELED_PREDICATE = C('error_msg').in(TASK_CANCELED_ERROR_MESSAGES); + export interface TaskStatusResponse { task: string; status: { diff --git a/web-console/src/views/tasks-view/tasks-view.tsx b/web-console/src/views/tasks-view/tasks-view.tsx index 17336238a474..b9208cbed0a1 100644 --- a/web-console/src/views/tasks-view/tasks-view.tsx +++ b/web-console/src/views/tasks-view/tasks-view.tsx @@ -36,6 +36,7 @@ import { } from '../../components'; import { AlertDialog, AsyncActionDialog, SpecDialog, TaskTableActionDialog } from '../../dialogs'; import type { QueryWithContext } from '../../druid-models'; +import { TASK_CANCELED_ERROR_MESSAGES, TASK_CANCELED_PREDICATE } from '../../druid-models'; import type { Capabilities } from '../../helpers'; import { SMALL_TABLE_PAGE_SIZE, SMALL_TABLE_PAGE_SIZE_OPTIONS } from '../../react-table'; import { Api, AppToaster } from '../../singletons'; @@ -66,8 +67,6 @@ const taskTableColumns: string[] = [ ACTION_COLUMN_LABEL, ]; -const CANCELED_ERROR_MSG = 'Shutdown request from user'; - interface TaskQueryResultRow { task_id: string; group_id: string; @@ -137,7 +136,7 @@ export class TasksView extends React.PureComponent - + ●  {status} - {errorMsg && errorMsg !== CANCELED_ERROR_MSG && ( - this.setState({ alertErrorMsg: errorMsg })} - title={errorMsg} - > -  ? - + {errorMsg && !TASK_CANCELED_ERROR_MESSAGES.includes(errorMsg) && ( + this.setState({ alertErrorMsg: errorMsg })}> ? )} diff --git a/web-console/src/views/workbench-view/recent-query-task-panel/recent-query-task-panel.tsx b/web-console/src/views/workbench-view/recent-query-task-panel/recent-query-task-panel.tsx index 13e8f716a7c0..718f5315c109 100644 --- a/web-console/src/views/workbench-view/recent-query-task-panel/recent-query-task-panel.tsx +++ b/web-console/src/views/workbench-view/recent-query-task-panel/recent-query-task-panel.tsx @@ -28,7 +28,7 @@ import { useStore } from 'zustand'; import { Loader } from '../../../components'; import type { TaskStatusWithCanceled } from '../../../druid-models'; -import { Execution, WorkbenchQuery } from '../../../druid-models'; +import { Execution, TASK_CANCELED_PREDICATE, WorkbenchQuery } from '../../../druid-models'; import { cancelTaskExecution, getTaskExecution } from '../../../helpers'; import { useClock, useInterval, useQueryManager } from '../../../hooks'; import { AppToaster } from '../../../singletons'; @@ -105,7 +105,7 @@ export const RecentQueryTaskPanel = React.memo(function RecentQueryTaskPanel( processQuery: async _ => { return await queryDruidSql({ query: `SELECT - CASE WHEN "error_msg" = 'Shutdown request from user' THEN 'CANCELED' ELSE "status" END AS "taskStatus", + CASE WHEN ${TASK_CANCELED_PREDICATE} THEN 'CANCELED' ELSE "status" END AS "taskStatus", "task_id" AS "taskId", "datasource", "created_time" AS "createdTime", From 635fb5f4914d8e9f03553e1ead159b222dc5b513 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Wed, 19 Jul 2023 17:17:16 -0700 Subject: [PATCH 2/4] control for selectDestination --- .../query-context/query-context.tsx | 3 ++- .../workbench-view/run-panel/run-panel.tsx | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/web-console/src/druid-models/query-context/query-context.tsx b/web-console/src/druid-models/query-context/query-context.tsx index 302f88049da7..d09fa73868ee 100644 --- a/web-console/src/druid-models/query-context/query-context.tsx +++ b/web-console/src/druid-models/query-context/query-context.tsx @@ -28,6 +28,7 @@ export interface QueryContext { // Multi-stage query maxNumTasks?: number; finalizeAggregations?: boolean; + selectDestination?: string; durableShuffleStorage?: boolean; maxParseExceptions?: number; groupByEnableMultiValueUnnesting?: boolean; @@ -161,7 +162,7 @@ export function changeFinalizeAggregations( : deepDelete(context, 'finalizeAggregations'); } -// finalizeAggregations +// groupByEnableMultiValueUnnesting export function getGroupByEnableMultiValueUnnesting(context: QueryContext): boolean | undefined { const { groupByEnableMultiValueUnnesting } = context; diff --git a/web-console/src/views/workbench-view/run-panel/run-panel.tsx b/web-console/src/views/workbench-view/run-panel/run-panel.tsx index e5bc24b62be8..fe7a6a796926 100644 --- a/web-console/src/views/workbench-view/run-panel/run-panel.tsx +++ b/web-console/src/views/workbench-view/run-panel/run-panel.tsx @@ -109,6 +109,7 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) { const finalizeAggregations = getFinalizeAggregations(queryContext); const groupByEnableMultiValueUnnesting = getGroupByEnableMultiValueUnnesting(queryContext); const sqlJoinAlgorithm = queryContext.sqlJoinAlgorithm ?? 'broadcast'; + const selectDestination = queryContext.selectDestination ?? 'TASK_REPORT'; const durableShuffleStorage = getDurableShuffleStorage(queryContext); const indexSpec: IndexSpec | undefined = deepGet(queryContext, 'indexSpec'); const useApproximateCountDistinct = getUseApproximateCountDistinct(queryContext); @@ -321,6 +322,23 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) { /> ))} + + {['TASK_REPORT', 'DURABLE_STORAGE'].map(o => ( + + changeQueryContext(deepSet(queryContext, 'selectDestination', o)) + } + /> + ))} + Date: Wed, 26 Jul 2023 14:05:22 -0700 Subject: [PATCH 3/4] fix spelling --- web-console/src/views/workbench-view/run-panel/run-panel.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web-console/src/views/workbench-view/run-panel/run-panel.tsx b/web-console/src/views/workbench-view/run-panel/run-panel.tsx index fe7a6a796926..5354f0f75315 100644 --- a/web-console/src/views/workbench-view/run-panel/run-panel.tsx +++ b/web-console/src/views/workbench-view/run-panel/run-panel.tsx @@ -109,7 +109,7 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) { const finalizeAggregations = getFinalizeAggregations(queryContext); const groupByEnableMultiValueUnnesting = getGroupByEnableMultiValueUnnesting(queryContext); const sqlJoinAlgorithm = queryContext.sqlJoinAlgorithm ?? 'broadcast'; - const selectDestination = queryContext.selectDestination ?? 'TASK_REPORT'; + const selectDestination = queryContext.selectDestination ?? 'taskReport'; const durableShuffleStorage = getDurableShuffleStorage(queryContext); const indexSpec: IndexSpec | undefined = deepGet(queryContext, 'indexSpec'); const useApproximateCountDistinct = getUseApproximateCountDistinct(queryContext); @@ -327,7 +327,7 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) { text="SELECT destination" label={selectDestination} > - {['TASK_REPORT', 'DURABLE_STORAGE'].map(o => ( + {['taskReport', 'durableStorage'].map(o => ( Date: Fri, 28 Jul 2023 12:52:32 -0700 Subject: [PATCH 4/4] feedback fixes --- .../menu-checkbox/menu-checkbox.tsx | 5 +- .../workbench-query/workbench-query.ts | 2 +- web-console/src/utils/druid-query.ts | 2 +- .../workbench-view/run-panel/run-panel.tsx | 64 +++++++++++++------ 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/web-console/src/components/menu-checkbox/menu-checkbox.tsx b/web-console/src/components/menu-checkbox/menu-checkbox.tsx index d305249bdb16..a22dff58e074 100644 --- a/web-console/src/components/menu-checkbox/menu-checkbox.tsx +++ b/web-console/src/components/menu-checkbox/menu-checkbox.tsx @@ -18,13 +18,14 @@ import type { MenuItemProps } from '@blueprintjs/core'; import { MenuItem } from '@blueprintjs/core'; +import { IconNames } from '@blueprintjs/icons'; import classNames from 'classnames'; import React from 'react'; import { checkedCircleIcon } from '../../utils'; export interface MenuCheckboxProps extends Omit { - checked: boolean; + checked: boolean | undefined; onChange: () => void; } @@ -34,7 +35,7 @@ export function MenuCheckbox(props: MenuCheckboxProps) { return ( @@ -326,6 +332,7 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) { icon={IconNames.MANUALLY_ENTERED_DATA} text="SELECT destination" label={selectDestination} + intent={intent} > {['taskReport', 'durableStorage'].map(o => ( ))} + + : undefined + } + onChange={() => { + onQueryChange(query.toggleUnlimited()); + }} + /> - { - setIndexSpecDialogSpec(indexSpec || {}); - }} - /> + { + setIndexSpecDialogSpec(indexSpec || {}); + }} + /> ) : ( <> @@ -390,24 +410,26 @@ export const RunPanel = React.memo(function RunPanel(props: RunPanelProps) { } /> )} - : undefined - } - onChange={() => { - onQueryChange(query.toggleUnlimited()); - }} - /> + {effectiveEngine === 'sql-native' && ( + : undefined + } + onChange={() => { + onQueryChange(query.toggleUnlimited()); + }} + /> + )} } >