From f386ff0171c48b62f22fba501fd2b07ed4a5621f Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Fri, 14 Mar 2025 09:27:00 -0700 Subject: [PATCH 01/11] use new compaction API --- .../compaction-dynamic-config-dialog.tsx | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx b/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx index 1b6bb587aab2..f9c8579eddec 100644 --- a/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx +++ b/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx @@ -25,16 +25,33 @@ import { AutoForm, ExternalLink, Loader } from '../../components'; import { useQueryManager } from '../../hooks'; import { getLink } from '../../links'; import { Api, AppToaster } from '../../singletons'; -import { getDruidErrorMessage } from '../../utils'; +import { deleteKeys, getDruidErrorMessage } from '../../utils'; interface CompactionDynamicConfig { compactionTaskSlotRatio: number; maxCompactionTaskSlots: number; + compactionPolicy: { type: 'newestSegmentFirst'; priorityDatasource?: string | null }; + useSupervisors: boolean; + engine: 'native' | 'msq'; } const DEFAULT_RATIO = 0.1; const DEFAULT_MAX = 2147483647; const COMPACTION_DYNAMIC_CONFIG_FIELDS: Field[] = [ + { + name: 'useSupervisors', + type: 'boolean', + defaultValue: false, + info: 'Whether compaction should be run on Overlord using supervisors instead of Coordinator duties.', + }, + { + name: 'engine', + type: 'string', + defined: config => Boolean(config.useSupervisors), + defaultValue: 'native', + suggestions: ['native', 'msq'], + info: 'Engine to use for running compaction tasks, native or MSQ.', + }, { name: 'compactionTaskSlotRatio', type: 'ratio', @@ -69,10 +86,7 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam const c = ( await Api.instance.get('/druid/coordinator/v1/config/compaction', { cancelToken }) ).data; - setDynamicConfig({ - compactionTaskSlotRatio: c.compactionTaskSlotRatio ?? DEFAULT_RATIO, - maxCompactionTaskSlots: c.maxCompactionTaskSlots ?? DEFAULT_MAX, - }); + setDynamicConfig(deleteKeys(c, ['compactionConfigs'])); } catch (e) { AppToaster.show({ icon: IconNames.ERROR, @@ -88,13 +102,7 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam async function saveConfig() { if (!dynamicConfig) return; try { - // This API is terrible. https://druid.apache.org/docs/latest/operations/api-reference#automatic-compaction-configuration - await Api.instance.post( - `/druid/coordinator/v1/config/compaction/taskslots?ratio=${ - dynamicConfig.compactionTaskSlotRatio ?? DEFAULT_RATIO - }&max=${dynamicConfig.maxCompactionTaskSlots ?? DEFAULT_MAX}`, - {}, - ); + await Api.instance.post(`/druid/coordinator/v1/config/compaction/cluster`, dynamicConfig); } catch (e) { AppToaster.show({ icon: IconNames.ERROR, From cdcbe79cb797405def42953a2550839bfcba1b6a Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Wed, 26 Mar 2025 10:39:54 -0700 Subject: [PATCH 02/11] proper dialog --- .../compaction-dynamic-config-dialog.tsx | 94 ++++++++----------- .../compaction-dynamic-config.tsx | 85 +++++++++++++++++ web-console/src/druid-models/index.ts | 1 + 3 files changed, 126 insertions(+), 54 deletions(-) create mode 100644 web-console/src/druid-models/compaction-dynamic-config/compaction-dynamic-config.tsx diff --git a/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx b/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx index f9c8579eddec..5780161db240 100644 --- a/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx +++ b/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx @@ -20,52 +20,18 @@ import { Button, Classes, Code, Dialog, Intent } from '@blueprintjs/core'; import { IconNames } from '@blueprintjs/icons'; import React, { useState } from 'react'; -import type { Field } from '../../components'; -import { AutoForm, ExternalLink, Loader } from '../../components'; +import type { FormJsonTabs } from '../../components'; +import { AutoForm, ExternalLink, FormJsonSelector, JsonInput, Loader } from '../../components'; +import type { CompactionDynamicConfig } from '../../druid-models'; +import { + COMPACTION_DYNAMIC_CONFIG_DEFAULT_MAX, + COMPACTION_DYNAMIC_CONFIG_DEFAULT_RATIO, + COMPACTION_DYNAMIC_CONFIG_FIELDS, +} from '../../druid-models'; import { useQueryManager } from '../../hooks'; import { getLink } from '../../links'; import { Api, AppToaster } from '../../singletons'; -import { deleteKeys, getDruidErrorMessage } from '../../utils'; - -interface CompactionDynamicConfig { - compactionTaskSlotRatio: number; - maxCompactionTaskSlots: number; - compactionPolicy: { type: 'newestSegmentFirst'; priorityDatasource?: string | null }; - useSupervisors: boolean; - engine: 'native' | 'msq'; -} - -const DEFAULT_RATIO = 0.1; -const DEFAULT_MAX = 2147483647; -const COMPACTION_DYNAMIC_CONFIG_FIELDS: Field[] = [ - { - name: 'useSupervisors', - type: 'boolean', - defaultValue: false, - info: 'Whether compaction should be run on Overlord using supervisors instead of Coordinator duties.', - }, - { - name: 'engine', - type: 'string', - defined: config => Boolean(config.useSupervisors), - defaultValue: 'native', - suggestions: ['native', 'msq'], - info: 'Engine to use for running compaction tasks, native or MSQ.', - }, - { - name: 'compactionTaskSlotRatio', - type: 'ratio', - defaultValue: DEFAULT_RATIO, - info: <>The ratio of the total task slots to the compaction task slots., - }, - { - name: 'maxCompactionTaskSlots', - type: 'number', - defaultValue: DEFAULT_MAX, - info: <>The maximum number of task slots for compaction tasks, - min: 0, - }, -]; +import { getDruidErrorMessage } from '../../utils'; export interface CompactionDynamicConfigDialogProps { onClose(): void; @@ -75,18 +41,21 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam props: CompactionDynamicConfigDialogProps, ) { const { onClose } = props; + const [currentTab, setCurrentTab] = useState('form'); const [dynamicConfig, setDynamicConfig] = useState< Partial | undefined >(); + const [jsonError, setJsonError] = useState(); useQueryManager>({ initQuery: null, processQuery: async (_, cancelToken) => { try { - const c = ( - await Api.instance.get('/druid/coordinator/v1/config/compaction', { cancelToken }) - ).data; - setDynamicConfig(deleteKeys(c, ['compactionConfigs'])); + const configResp = await Api.instance.get( + '/druid/coordinator/v1/config/compaction/cluster', + { cancelToken }, + ); + setDynamicConfig(configResp.data || {}); } catch (e) { AppToaster.show({ icon: IconNames.ERROR, @@ -143,17 +112,33 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam

The maximum number of task slots used for compaction will be{' '} {`clamp(floor(${ - dynamicConfig.compactionTaskSlotRatio ?? DEFAULT_RATIO - } * total_task_slots), 1, ${ - dynamicConfig.maxCompactionTaskSlots ?? DEFAULT_MAX + dynamicConfig.compactionTaskSlotRatio ?? COMPACTION_DYNAMIC_CONFIG_DEFAULT_RATIO + } * total_task_slots), ${dynamicConfig.engine === 'msq' ? 2 : 1}, ${ + dynamicConfig.maxCompactionTaskSlots ?? COMPACTION_DYNAMIC_CONFIG_DEFAULT_MAX })`} .

- { + setJsonError(undefined); + setCurrentTab(t); + }} /> + {currentTab === 'form' ? ( + + ) : ( + + )}
@@ -162,6 +147,7 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam onClick={() => void saveConfig()} intent={Intent.PRIMARY} rightIcon={IconNames.TICK} + disabled={Boolean(jsonError)} />
diff --git a/web-console/src/druid-models/compaction-dynamic-config/compaction-dynamic-config.tsx b/web-console/src/druid-models/compaction-dynamic-config/compaction-dynamic-config.tsx new file mode 100644 index 000000000000..e1df86f13551 --- /dev/null +++ b/web-console/src/druid-models/compaction-dynamic-config/compaction-dynamic-config.tsx @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Code } from '@blueprintjs/core'; + +import type { Field } from '../../components'; +import { deepGet } from '../../utils'; + +export interface CompactionDynamicConfig { + compactionTaskSlotRatio: number; + maxCompactionTaskSlots: number; + compactionPolicy: { type: 'newestSegmentFirst'; priorityDatasource?: string | null }; + useSupervisors: boolean; + engine: 'native' | 'msq'; +} + +export const COMPACTION_DYNAMIC_CONFIG_DEFAULT_RATIO = 0.1; +export const COMPACTION_DYNAMIC_CONFIG_DEFAULT_MAX = 2147483647; +export const COMPACTION_DYNAMIC_CONFIG_FIELDS: Field[] = [ + { + name: 'useSupervisors', + type: 'boolean', + defaultValue: false, + info: 'Whether compaction should be run on Overlord using supervisors instead of Coordinator duties.', + }, + { + name: 'engine', + type: 'string', + defined: config => Boolean(config.useSupervisors), + defaultValue: 'native', + suggestions: ['native', 'msq'], + info: 'Engine to use for running compaction tasks, native or MSQ.', + }, + { + name: 'compactionTaskSlotRatio', + type: 'ratio', + defaultValue: COMPACTION_DYNAMIC_CONFIG_DEFAULT_RATIO, + info: <>The ratio of the total task slots to the compaction task slots., + }, + { + name: 'maxCompactionTaskSlots', + type: 'number', + defaultValue: COMPACTION_DYNAMIC_CONFIG_DEFAULT_MAX, + info: <>The maximum number of task slots for compaction tasks, + min: 0, + }, + { + name: 'compactionPolicy.type', + type: 'string', + suggestions: ['newestSegmentFirst'], + info: ( + <> + This must always be newestSegmentFirst + + ), + }, + { + name: 'compactionPolicy.priorityDatasource', + type: 'string', + defined: config => deepGet(config, 'compactionPolicy.type') === 'newestSegmentFirst', + placeholder: '(none)', + info: ( + <> + Datasource to prioritize for compaction. The intervals of this datasource are chosen for + compaction before the intervals of any other datasource. Within this datasource, the + intervals are prioritized based on the chosen compaction policy. + + ), + }, +]; diff --git a/web-console/src/druid-models/index.ts b/web-console/src/druid-models/index.ts index e31eedeea738..2e23cf7ee2c2 100644 --- a/web-console/src/druid-models/index.ts +++ b/web-console/src/druid-models/index.ts @@ -18,6 +18,7 @@ export * from './async-query/async-query'; export * from './compaction-config/compaction-config'; +export * from './compaction-dynamic-config/compaction-dynamic-config'; export * from './compaction-status/compaction-status'; export * from './coordinator-dynamic-config/coordinator-dynamic-config'; export * from './dart/dart-query-entry'; From 1d80bfdf06d322eed5c37564dcb963a62546aed0 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Wed, 26 Mar 2025 11:10:01 -0700 Subject: [PATCH 03/11] minor cleanup --- .../compaction-config/compaction-config.tsx | 5 +++++ .../src/views/datasources-view/datasources-view.tsx | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/web-console/src/druid-models/compaction-config/compaction-config.tsx b/web-console/src/druid-models/compaction-config/compaction-config.tsx index 54f16adbfdcf..1f2832b56b72 100644 --- a/web-console/src/druid-models/compaction-config/compaction-config.tsx +++ b/web-console/src/druid-models/compaction-config/compaction-config.tsx @@ -20,6 +20,7 @@ import { Code } from '@blueprintjs/core'; import type { Field } from '../../components'; import { deepGet, deepSet, oneOfKnown } from '../../utils'; +import type { CompactionDynamicConfig } from '../compaction-dynamic-config/compaction-dynamic-config'; export interface CompactionConfig { dataSource: string; @@ -31,6 +32,10 @@ export interface CompactionConfig { inputSegmentSizeBytes?: number; } +export interface CompactionConfigsAndMore extends CompactionDynamicConfig { + compactionConfigs: CompactionConfig[]; +} + export const NOOP_INPUT_SEGMENT_SIZE_BYTES = 100000000000000; export function compactionConfigHasLegacyInputSegmentSizeBytesSet( diff --git a/web-console/src/views/datasources-view/datasources-view.tsx b/web-console/src/views/datasources-view/datasources-view.tsx index ea0df40bb0a4..234da146fa32 100644 --- a/web-console/src/views/datasources-view/datasources-view.tsx +++ b/web-console/src/views/datasources-view/datasources-view.tsx @@ -48,6 +48,7 @@ import { import { DatasourceTableActionDialog } from '../../dialogs/datasource-table-action-dialog/datasource-table-action-dialog'; import type { CompactionConfig, + CompactionConfigsAndMore, CompactionInfo, CompactionStatus, QueryWithContext, @@ -614,11 +615,14 @@ GROUP BY 1, 2`; // Compaction auxiliaryQueries.push(async (datasourcesAndDefaultRules, cancelToken) => { try { - const compactionConfigsResp = await Api.instance.get<{ - compactionConfigs: CompactionConfig[]; - }>('/druid/coordinator/v1/config/compaction', { cancelToken }); + const compactionConfigsAndMore = ( + await Api.instance.get( + '/druid/coordinator/v1/config/compaction', + { cancelToken }, + ) + ).data; const compactionConfigs = lookupBy( - compactionConfigsResp.data.compactionConfigs || [], + compactionConfigsAndMore.compactionConfigs || [], c => c.dataSource, ); From 675917819756931745606efe1293453ea34857bc Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Thu, 27 Mar 2025 15:29:19 -0700 Subject: [PATCH 04/11] try new APIs part 1 --- .../src/views/datasources-view/datasources-view.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/web-console/src/views/datasources-view/datasources-view.tsx b/web-console/src/views/datasources-view/datasources-view.tsx index 234da146fa32..b2f822d28801 100644 --- a/web-console/src/views/datasources-view/datasources-view.tsx +++ b/web-console/src/views/datasources-view/datasources-view.tsx @@ -948,7 +948,12 @@ GROUP BY 1, 2`; private readonly saveCompaction = async (compactionConfig: CompactionConfig) => { if (!compactionConfig) return; try { - await Api.instance.post(`/druid/coordinator/v1/config/compaction`, compactionConfig); + await Api.instance.post( + `/druid/indexer/v1/compaction/config/datasources/${Api.encodePath( + compactionConfig.dataSource, + )}`, + compactionConfig, + ); this.setState({ compactionDialogOpenOn: undefined }); this.fetchData(); } catch (e) { @@ -972,7 +977,7 @@ GROUP BY 1, 2`; onClick: async () => { try { await Api.instance.delete( - `/druid/coordinator/v1/config/compaction/${Api.encodePath(datasource)}`, + `/druid/indexer/v1/compaction/config/datasources/${Api.encodePath(datasource)}`, ); this.setState({ compactionDialogOpenOn: undefined }, () => this.fetchData()); } catch (e) { From 67ad9c715f3c5368f5a7c2f0dcb084e23bc3c56d Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Fri, 28 Mar 2025 13:57:02 -0700 Subject: [PATCH 05/11] updated more APIs --- web-console/src/dialogs/doctor-dialog/doctor-checks.tsx | 8 +++++--- .../druid-models/compaction-config/compaction-config.tsx | 3 +-- .../src/views/datasources-view/datasources-view.tsx | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/web-console/src/dialogs/doctor-dialog/doctor-checks.tsx b/web-console/src/dialogs/doctor-dialog/doctor-checks.tsx index 2104c046b884..17cd8acd1a46 100644 --- a/web-console/src/dialogs/doctor-dialog/doctor-checks.tsx +++ b/web-console/src/dialogs/doctor-dialog/doctor-checks.tsx @@ -16,6 +16,7 @@ * limitations under the License. */ +import type { CompactionConfigs } from '../../druid-models'; import { Api } from '../../singletons'; import { deepGet, pluralIfNeeded, queryDruidSql } from '../../utils'; import { postToSampler } from '../../utils/sampler'; @@ -373,10 +374,11 @@ ORDER BY "num_bad_time_chunks"`, if (sqlResult.length) { // Grab the auto-compaction definitions and ignore dataSources that already have auto-compaction - let compactionResult: any; + let compactionResult: CompactionConfigs; try { - compactionResult = (await Api.instance.get('/druid/coordinator/v1/config/compaction')) - .data; + compactionResult = ( + await Api.instance.get('/druid/indexer/v1/compaction/config/datasources') + ).data; } catch (e) { controls.addIssue(`Could not get compaction config. Something is wrong.`); return; diff --git a/web-console/src/druid-models/compaction-config/compaction-config.tsx b/web-console/src/druid-models/compaction-config/compaction-config.tsx index 1f2832b56b72..de4a2f47a843 100644 --- a/web-console/src/druid-models/compaction-config/compaction-config.tsx +++ b/web-console/src/druid-models/compaction-config/compaction-config.tsx @@ -20,7 +20,6 @@ import { Code } from '@blueprintjs/core'; import type { Field } from '../../components'; import { deepGet, deepSet, oneOfKnown } from '../../utils'; -import type { CompactionDynamicConfig } from '../compaction-dynamic-config/compaction-dynamic-config'; export interface CompactionConfig { dataSource: string; @@ -32,7 +31,7 @@ export interface CompactionConfig { inputSegmentSizeBytes?: number; } -export interface CompactionConfigsAndMore extends CompactionDynamicConfig { +export interface CompactionConfigs { compactionConfigs: CompactionConfig[]; } diff --git a/web-console/src/views/datasources-view/datasources-view.tsx b/web-console/src/views/datasources-view/datasources-view.tsx index b2f822d28801..8ff4ec9f4239 100644 --- a/web-console/src/views/datasources-view/datasources-view.tsx +++ b/web-console/src/views/datasources-view/datasources-view.tsx @@ -48,7 +48,7 @@ import { import { DatasourceTableActionDialog } from '../../dialogs/datasource-table-action-dialog/datasource-table-action-dialog'; import type { CompactionConfig, - CompactionConfigsAndMore, + CompactionConfigs, CompactionInfo, CompactionStatus, QueryWithContext, @@ -616,8 +616,8 @@ GROUP BY 1, 2`; auxiliaryQueries.push(async (datasourcesAndDefaultRules, cancelToken) => { try { const compactionConfigsAndMore = ( - await Api.instance.get( - '/druid/coordinator/v1/config/compaction', + await Api.instance.get( + '/druid/indexer/v1/compaction/config/datasources', { cancelToken }, ) ).data; @@ -628,7 +628,7 @@ GROUP BY 1, 2`; const compactionStatusesResp = await Api.instance.get<{ latestStatus: CompactionStatus[]; - }>('/druid/coordinator/v1/compaction/status', { cancelToken }); + }>('/druid/indexer/v1/compaction/status/datasources', { cancelToken }); const compactionStatuses = lookupBy( compactionStatusesResp.data.latestStatus || [], c => c.dataSource, From 3040636d7486f0f5e7a044defe49da8f6b907c84 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Mon, 31 Mar 2025 15:26:46 -0700 Subject: [PATCH 06/11] new APIs --- .../compaction-dynamic-config-dialog.tsx | 9 ++++----- .../compaction-history-dialog.tsx | 4 +++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx b/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx index 5780161db240..cc6c1597c71c 100644 --- a/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx +++ b/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx @@ -51,10 +51,9 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam initQuery: null, processQuery: async (_, cancelToken) => { try { - const configResp = await Api.instance.get( - '/druid/coordinator/v1/config/compaction/cluster', - { cancelToken }, - ); + const configResp = await Api.instance.get('/druid/v1/indexer/compaction/config/cluster', { + cancelToken, + }); setDynamicConfig(configResp.data || {}); } catch (e) { AppToaster.show({ @@ -71,7 +70,7 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam async function saveConfig() { if (!dynamicConfig) return; try { - await Api.instance.post(`/druid/coordinator/v1/config/compaction/cluster`, dynamicConfig); + await Api.instance.post('/druid/v1/indexer/compaction/config/cluster', dynamicConfig); } catch (e) { AppToaster.show({ icon: IconNames.ERROR, diff --git a/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.tsx b/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.tsx index 8ee0ffdbfbc3..26a1d044e47e 100644 --- a/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.tsx +++ b/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.tsx @@ -66,7 +66,9 @@ export const CompactionHistoryDialog = React.memo(function CompactionHistoryDial processQuery: async (datasource, cancelToken) => { try { return await getApiArray( - `/druid/coordinator/v1/config/compaction/${Api.encodePath(datasource)}/history?count=20`, + `/druid/v1/indexer/compaction/config/datasources/${Api.encodePath( + datasource, + )}/history?count=20`, cancelToken, ); } catch (e) { From c80545f022ed8e79f4dff342c145e2b39fd154ce Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Tue, 1 Apr 2025 21:37:48 -0700 Subject: [PATCH 07/11] final API fixes --- .../compaction-dynamic-config-dialog.tsx | 14 +++++++--- .../compaction-history-dialog.scss | 6 +---- .../compaction-history-dialog.tsx | 27 ++++++++++++------- .../compaction-dynamic-config.tsx | 11 +++++++- web-console/src/utils/druid-query.ts | 10 +++++++ 5 files changed, 50 insertions(+), 18 deletions(-) diff --git a/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx b/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx index cc6c1597c71c..0e352784f625 100644 --- a/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx +++ b/web-console/src/dialogs/compaction-dynamic-config-dialog/compaction-dynamic-config-dialog.tsx @@ -31,7 +31,7 @@ import { import { useQueryManager } from '../../hooks'; import { getLink } from '../../links'; import { Api, AppToaster } from '../../singletons'; -import { getDruidErrorMessage } from '../../utils'; +import { getDruidErrorMessage, wait } from '../../utils'; export interface CompactionDynamicConfigDialogProps { onClose(): void; @@ -51,7 +51,7 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam initQuery: null, processQuery: async (_, cancelToken) => { try { - const configResp = await Api.instance.get('/druid/v1/indexer/compaction/config/cluster', { + const configResp = await Api.instance.get('/druid/indexer/v1/compaction/config/cluster', { cancelToken, }); setDynamicConfig(configResp.data || {}); @@ -70,20 +70,28 @@ export const CompactionDynamicConfigDialog = React.memo(function CompactionDynam async function saveConfig() { if (!dynamicConfig) return; try { - await Api.instance.post('/druid/v1/indexer/compaction/config/cluster', dynamicConfig); + await Api.instance.post('/druid/indexer/v1/compaction/config/cluster', dynamicConfig); } catch (e) { AppToaster.show({ icon: IconNames.ERROR, intent: Intent.DANGER, message: `Could not save compaction dynamic config: ${getDruidErrorMessage(e)}`, }); + return; } AppToaster.show({ message: 'Saved compaction dynamic config', intent: Intent.SUCCESS, }); + onClose(); + + // Reload the page also because the datasources page pulls from different APIs depending on the setting of supervisor based compaction + if (location.hash.includes('#datasources')) { + await wait(1000); // Wait for a second to give the user time to read the toast + location.reload(); + } } return ( diff --git a/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.scss b/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.scss index 620e7f6ff227..e6da0a9f3431 100644 --- a/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.scss +++ b/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.scss @@ -36,11 +36,7 @@ .global-info { position: absolute; bottom: 10px; - left: 30px; - right: 10px; - width: auto; - white-space: pre; - background: $gray1; + right: 20px; } } diff --git a/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.tsx b/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.tsx index 26a1d044e47e..b77fc3d3dda2 100644 --- a/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.tsx +++ b/web-console/src/dialogs/compaction-history-dialog/compaction-history-dialog.tsx @@ -16,15 +16,16 @@ * limitations under the License. */ -import { Button, Callout, Classes, Dialog, Tab, Tabs, TabsExpander, Tag } from '@blueprintjs/core'; +import { Button, Classes, Dialog, Popover, Tab, Tabs, TabsExpander, Tag } from '@blueprintjs/core'; +import { IconNames } from '@blueprintjs/icons'; import * as JSONBig from 'json-bigint-native'; import React, { useState } from 'react'; -import { Loader, ShowValue } from '../../components'; +import { Loader, PopoverText, ShowValue } from '../../components'; import type { CompactionConfig } from '../../druid-models'; import { useQueryManager } from '../../hooks'; import { Api } from '../../singletons'; -import { formatInteger, formatPercent, getApiArray } from '../../utils'; +import { formatInteger, formatPercent, getApiArrayFromKey } from '../../utils'; import { DiffDialog } from '../diff-dialog/diff-dialog'; import './compaction-history-dialog.scss'; @@ -46,7 +47,7 @@ function formatGlobalConfig(globalConfig: GlobalConfig): string { return [ `compactionTaskSlotRatio: ${formatPercent(globalConfig.compactionTaskSlotRatio)}`, `maxCompactionTaskSlots: ${formatInteger(globalConfig.maxCompactionTaskSlots)}`, - `useAutoScaleSlots: ${globalConfig.useAutoScaleSlots}`, + `useAutoScaleSlots: ${Boolean(globalConfig.useAutoScaleSlots)}`, ].join('\n'); } @@ -65,10 +66,11 @@ export const CompactionHistoryDialog = React.memo(function CompactionHistoryDial initQuery: datasource, processQuery: async (datasource, cancelToken) => { try { - return await getApiArray( - `/druid/v1/indexer/compaction/config/datasources/${Api.encodePath( + return await getApiArrayFromKey( + `/druid/indexer/v1/compaction/config/datasources/${Api.encodePath( datasource, )}/history?count=20`, + 'entries', cancelToken, ); } catch (e) { @@ -107,9 +109,16 @@ export const CompactionHistoryDialog = React.memo(function CompactionHistoryDial downloadFilename={`compaction-history-${datasource}-version-${historyEntry.auditTime}.json`} /> {historyEntry.globalConfig && ( - - {formatGlobalConfig(historyEntry.globalConfig)} - + +
{formatGlobalConfig(historyEntry.globalConfig)}
+ + } + > +