mirror of https://github.com/apache/druid.git
Web console: expose handoff API (#16586)
* don't start completions on numbers... it makes numbers hard to enter * add handoff dialog * fix placeholder * Update web-console/src/dialogs/supervisor-handoff-dialog/supervisor-handoff-dialog.tsx Co-authored-by: Katya Macedo <38017980+ektravel@users.noreply.github.com> * Update web-console/src/dialogs/supervisor-handoff-dialog/supervisor-handoff-dialog.tsx Co-authored-by: Katya Macedo <38017980+ektravel@users.noreply.github.com> * Update web-console/src/dialogs/supervisor-handoff-dialog/supervisor-handoff-dialog.tsx Co-authored-by: Katya Macedo <38017980+ektravel@users.noreply.github.com> * feedback fixes * update snapshot --------- Co-authored-by: Katya Macedo <38017980+ektravel@users.noreply.github.com>
This commit is contained in:
parent
c968e73171
commit
422183ee70
|
@ -186,7 +186,10 @@ ace.define(
|
|||
this.$id = 'ace/mode/dsql';
|
||||
|
||||
this.lineCommentStart = '--';
|
||||
this.getCompletions = () => completions;
|
||||
this.getCompletions = (_state: any, _session: any, _pos: any, prefix: string) => {
|
||||
if (/^\d+$/.test(prefix)) return; // Don't start completing if the user is typing a number
|
||||
return completions;
|
||||
};
|
||||
};
|
||||
oop.inherits(Mode, TextMode);
|
||||
|
||||
|
|
|
@ -37,4 +37,5 @@ export * from './string-input-dialog/string-input-dialog';
|
|||
export * from './supervisor-reset-offsets-dialog/supervisor-reset-offsets-dialog';
|
||||
export * from './supervisor-table-action-dialog/supervisor-table-action-dialog';
|
||||
export * from './table-action-dialog/table-action-dialog';
|
||||
export * from './task-group-handoff-dialog/task-group-handoff-dialog';
|
||||
export * from './task-table-action-dialog/task-table-action-dialog';
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 { FormGroup, Intent, Tag } from '@blueprintjs/core';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { ArrayInput } from '../../components';
|
||||
import { Api } from '../../singletons';
|
||||
import { AsyncActionDialog } from '../async-action-dialog/async-action-dialog';
|
||||
|
||||
export interface TaskGroupHandoffDialogProps {
|
||||
supervisorId: string;
|
||||
onSuccess(): void;
|
||||
onClose(): void;
|
||||
}
|
||||
|
||||
export function TaskGroupHandoffDialog(props: TaskGroupHandoffDialogProps) {
|
||||
const { supervisorId, onSuccess, onClose } = props;
|
||||
const [groupIds, setGroupIds] = useState<string[]>([]);
|
||||
|
||||
return (
|
||||
<AsyncActionDialog
|
||||
action={async () => {
|
||||
const resp = await Api.instance.post(
|
||||
`/druid/indexer/v1/supervisor/${Api.encodePath(supervisorId)}/taskGroups/handoff`,
|
||||
{ taskGroupIds: groupIds.map(x => parseInt(x, 10)) },
|
||||
);
|
||||
return resp.data;
|
||||
}}
|
||||
confirmButtonText="Handoff task groups"
|
||||
successText="Task group handoff has been initiated"
|
||||
failText="Could not initiate handoff for the selected task groups"
|
||||
intent={Intent.PRIMARY}
|
||||
onClose={onClose}
|
||||
onSuccess={onSuccess}
|
||||
>
|
||||
<p>
|
||||
Are you sure you want to initiate early handoff for the given task groups belonging to
|
||||
supervisor <Tag minimal>{supervisorId}</Tag>?
|
||||
</p>
|
||||
<FormGroup label="Task group IDs">
|
||||
<ArrayInput
|
||||
values={groupIds}
|
||||
onChange={v => setGroupIds(v || [])}
|
||||
placeholder="0, 1, 2, ..."
|
||||
/>
|
||||
</FormGroup>
|
||||
</AsyncActionDialog>
|
||||
);
|
||||
}
|
|
@ -397,7 +397,7 @@ exports[`SupervisorsView matches snapshot 1`] = `
|
|||
rowsText="rows"
|
||||
showPageJump={false}
|
||||
showPageSizeOptions={true}
|
||||
showPagination={true}
|
||||
showPagination={false}
|
||||
showPaginationBottom={true}
|
||||
showPaginationTop={false}
|
||||
sortable={true}
|
||||
|
|
|
@ -45,6 +45,7 @@ import {
|
|||
SupervisorTableActionDialog,
|
||||
} from '../../dialogs';
|
||||
import { SupervisorResetOffsetsDialog } from '../../dialogs/supervisor-reset-offsets-dialog/supervisor-reset-offsets-dialog';
|
||||
import { TaskGroupHandoffDialog } from '../../dialogs/task-group-handoff-dialog/task-group-handoff-dialog';
|
||||
import type {
|
||||
IngestionSpec,
|
||||
QueryWithContext,
|
||||
|
@ -144,6 +145,7 @@ export interface SupervisorsViewState {
|
|||
|
||||
resumeSupervisorId?: string;
|
||||
suspendSupervisorId?: string;
|
||||
handoffSupervisorId?: string;
|
||||
resetOffsetsSupervisorInfo?: { id: string; type: string };
|
||||
resetSupervisorId?: string;
|
||||
terminateSupervisorId?: string;
|
||||
|
@ -425,15 +427,25 @@ export class SupervisorsView extends React.PureComponent<
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
actions.push({
|
||||
icon: supervisorSuspended ? IconNames.PLAY : IconNames.PAUSE,
|
||||
title: supervisorSuspended ? 'Resume' : 'Suspend',
|
||||
onAction: () =>
|
||||
supervisorSuspended
|
||||
? this.setState({ resumeSupervisorId: id })
|
||||
: this.setState({ suspendSupervisorId: id }),
|
||||
});
|
||||
|
||||
if (!supervisorSuspended) {
|
||||
actions.push({
|
||||
icon: IconNames.AUTOMATIC_UPDATES,
|
||||
title: 'Handoff early',
|
||||
onAction: () => this.setState({ handoffSupervisorId: id }),
|
||||
});
|
||||
}
|
||||
|
||||
actions.push(
|
||||
{
|
||||
icon: supervisorSuspended ? IconNames.PLAY : IconNames.PAUSE,
|
||||
title: supervisorSuspended ? 'Resume' : 'Suspend',
|
||||
onAction: () =>
|
||||
supervisorSuspended
|
||||
? this.setState({ resumeSupervisorId: id })
|
||||
: this.setState({ suspendSupervisorId: id }),
|
||||
},
|
||||
{
|
||||
icon: IconNames.STEP_BACKWARD,
|
||||
title: `Set ${type === 'kinesis' ? 'sequence numbers' : 'offsets'}`,
|
||||
|
@ -519,6 +531,23 @@ export class SupervisorsView extends React.PureComponent<
|
|||
);
|
||||
}
|
||||
|
||||
renderTaskGroupHandoffAction() {
|
||||
const { handoffSupervisorId } = this.state;
|
||||
if (!handoffSupervisorId) return;
|
||||
|
||||
return (
|
||||
<TaskGroupHandoffDialog
|
||||
supervisorId={handoffSupervisorId}
|
||||
onClose={() => {
|
||||
this.setState({ handoffSupervisorId: undefined });
|
||||
}}
|
||||
onSuccess={() => {
|
||||
this.supervisorQueryManager.rerunLastQuery();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderResetOffsetsSupervisorAction() {
|
||||
const { resetOffsetsSupervisorInfo } = this.state;
|
||||
if (!resetOffsetsSupervisorInfo) return;
|
||||
|
@ -659,7 +688,7 @@ export class SupervisorsView extends React.PureComponent<
|
|||
ofText=""
|
||||
defaultPageSize={SMALL_TABLE_PAGE_SIZE}
|
||||
pageSizeOptions={SMALL_TABLE_PAGE_SIZE_OPTIONS}
|
||||
showPagination
|
||||
showPagination={supervisors.length > SMALL_TABLE_PAGE_SIZE}
|
||||
columns={[
|
||||
{
|
||||
Header: twoLines('Supervisor ID', <i>(datasource)</i>),
|
||||
|
@ -1061,6 +1090,7 @@ export class SupervisorsView extends React.PureComponent<
|
|||
{this.renderSupervisorTable()}
|
||||
{this.renderResumeSupervisorAction()}
|
||||
{this.renderSuspendSupervisorAction()}
|
||||
{this.renderTaskGroupHandoffAction()}
|
||||
{this.renderResetOffsetsSupervisorAction()}
|
||||
{this.renderResetSupervisorAction()}
|
||||
{this.renderTerminateSupervisorAction()}
|
||||
|
|
|
@ -81,6 +81,10 @@ export class FlexibleQueryInput extends React.PureComponent<
|
|||
// Local completions
|
||||
{
|
||||
getCompletions: (_state, session, pos, prefix, callback) => {
|
||||
if (/^\d+$/.test(prefix)) {
|
||||
callback(null, []); // Don't start completing if the user is typing a number
|
||||
return;
|
||||
}
|
||||
const charBeforePrefix = session.getLine(pos.row)[pos.column - prefix.length - 1];
|
||||
callback(
|
||||
null,
|
||||
|
|
Loading…
Reference in New Issue