You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by vo...@apache.org on 2024/08/16 21:39:23 UTC

(druid) branch master updated: Web console: expose handoff API (#16586)

This is an automated email from the ASF dual-hosted git repository.

vogievetsky pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new 422183ee70d Web console: expose handoff API (#16586)
422183ee70d is described below

commit 422183ee70d6e14e32213289b926eca68e857fa6
Author: Vadim Ogievetsky <va...@ogievetsky.com>
AuthorDate: Fri Aug 16 14:39:16 2024 -0700

    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  <38...@users.noreply.github.com>
    
    * Update web-console/src/dialogs/supervisor-handoff-dialog/supervisor-handoff-dialog.tsx
    
    Co-authored-by: Katya Macedo  <38...@users.noreply.github.com>
    
    * Update web-console/src/dialogs/supervisor-handoff-dialog/supervisor-handoff-dialog.tsx
    
    Co-authored-by: Katya Macedo  <38...@users.noreply.github.com>
    
    * feedback fixes
    
    * update snapshot
    
    ---------
    
    Co-authored-by: Katya Macedo <38...@users.noreply.github.com>
---
 web-console/src/ace-modes/dsql.ts                  |  5 +-
 web-console/src/dialogs/index.ts                   |  1 +
 .../task-group-handoff-dialog.tsx                  | 65 ++++++++++++++++++++++
 .../__snapshots__/supervisors-view.spec.tsx.snap   |  2 +-
 .../views/supervisors-view/supervisors-view.tsx    | 48 +++++++++++++---
 .../flexible-query-input/flexible-query-input.tsx  |  4 ++
 6 files changed, 114 insertions(+), 11 deletions(-)

diff --git a/web-console/src/ace-modes/dsql.ts b/web-console/src/ace-modes/dsql.ts
index e57d17d51e7..38cc40124e2 100644
--- a/web-console/src/ace-modes/dsql.ts
+++ b/web-console/src/ace-modes/dsql.ts
@@ -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);
 
diff --git a/web-console/src/dialogs/index.ts b/web-console/src/dialogs/index.ts
index f7e239b53f4..6a3c336831b 100644
--- a/web-console/src/dialogs/index.ts
+++ b/web-console/src/dialogs/index.ts
@@ -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';
diff --git a/web-console/src/dialogs/task-group-handoff-dialog/task-group-handoff-dialog.tsx b/web-console/src/dialogs/task-group-handoff-dialog/task-group-handoff-dialog.tsx
new file mode 100644
index 00000000000..02e4b066af9
--- /dev/null
+++ b/web-console/src/dialogs/task-group-handoff-dialog/task-group-handoff-dialog.tsx
@@ -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>
+  );
+}
diff --git a/web-console/src/views/supervisors-view/__snapshots__/supervisors-view.spec.tsx.snap b/web-console/src/views/supervisors-view/__snapshots__/supervisors-view.spec.tsx.snap
index 4dc9526c12c..4b531c0bc44 100644
--- a/web-console/src/views/supervisors-view/__snapshots__/supervisors-view.spec.tsx.snap
+++ b/web-console/src/views/supervisors-view/__snapshots__/supervisors-view.spec.tsx.snap
@@ -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}
diff --git a/web-console/src/views/supervisors-view/supervisors-view.tsx b/web-console/src/views/supervisors-view/supervisors-view.tsx
index 60e340034eb..648186d45bc 100644
--- a/web-console/src/views/supervisors-view/supervisors-view.tsx
+++ b/web-console/src/views/supervisors-view/supervisors-view.tsx
@@ -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()}
diff --git a/web-console/src/views/workbench-view/flexible-query-input/flexible-query-input.tsx b/web-console/src/views/workbench-view/flexible-query-input/flexible-query-input.tsx
index f4be7275944..cb4e9e3b192 100644
--- a/web-console/src/views/workbench-view/flexible-query-input/flexible-query-input.tsx
+++ b/web-console/src/views/workbench-view/flexible-query-input/flexible-query-input.tsx
@@ -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,


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org