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

cwylie 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 8181ef627a2 add useConcurrentLocks toggle (#16899)
8181ef627a2 is described below

commit 8181ef627a2ddbba347a30b2eee66fdb9c0535cc
Author: Vadim Ogievetsky <[email protected]>
AuthorDate: Wed Aug 14 13:44:53 2024 -0700

    add useConcurrentLocks toggle (#16899)
---
 .../druid-models/query-context/query-context.tsx   |   2 +
 .../__snapshots__/run-panel.spec.tsx.snap          | 176 +++++++++++++++++++++
 .../workbench-view/run-panel/run-panel.spec.tsx    |  60 +++++++
 .../views/workbench-view/run-panel/run-panel.tsx   |  86 +++++-----
 4 files changed, 286 insertions(+), 38 deletions(-)

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 a25d268d845..4b0367c25a6 100644
--- a/web-console/src/druid-models/query-context/query-context.tsx
+++ b/web-console/src/druid-models/query-context/query-context.tsx
@@ -40,6 +40,7 @@ export interface QueryContext {
   sqlJoinAlgorithm?: SqlJoinAlgorithm;
   failOnEmptyInsert?: boolean;
   waitUntilSegmentsLoad?: boolean;
+  useConcurrentLocks?: boolean;
 
   [key: string]: any;
 }
@@ -61,6 +62,7 @@ export const DEFAULT_SERVER_QUERY_CONTEXT: QueryContext = {
   sqlJoinAlgorithm: 'broadcast',
   failOnEmptyInsert: false,
   waitUntilSegmentsLoad: false,
+  useConcurrentLocks: false,
 };
 
 export interface QueryWithContext {
diff --git 
a/web-console/src/views/workbench-view/run-panel/__snapshots__/run-panel.spec.tsx.snap
 
b/web-console/src/views/workbench-view/run-panel/__snapshots__/run-panel.spec.tsx.snap
new file mode 100644
index 00000000000..8c7f4ec7a70
--- /dev/null
+++ 
b/web-console/src/views/workbench-view/run-panel/__snapshots__/run-panel.spec.tsx.snap
@@ -0,0 +1,176 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`RunPanel matches snapshot on msq (auto) query 1`] = `
+<div
+  class="run-panel"
+>
+  <button
+    class="bp5-button bp5-intent-primary"
+    type="button"
+  >
+    <span
+      aria-hidden="true"
+      class="bp5-icon bp5-icon-caret-right"
+    >
+      <svg
+        data-icon="caret-right"
+        height="16"
+        role="img"
+        viewBox="0 0 16 16"
+        width="16"
+      >
+        <path
+          d="M11 8c0-.15-.07-.28-.17-.37l-4-3.5A.495.495 0 006 4.5v7a.495.495 
0 00.83.37l4-3.5c.1-.09.17-.22.17-.37z"
+          fill-rule="evenodd"
+        />
+      </svg>
+    </span>
+    <span
+      class="bp5-button-text"
+    >
+      Run
+    </span>
+  </button>
+  <div
+    class="bp5-button-group"
+  >
+    <span
+      class="bp5-popover-target"
+    >
+      <button
+        aria-expanded="false"
+        aria-haspopup="menu"
+        class="bp5-button"
+        type="button"
+      >
+        <span
+          class="bp5-button-text"
+        >
+          Engine: sql-msq-task
+        </span>
+        <span
+          aria-hidden="true"
+          class="bp5-icon bp5-icon-caret-down"
+        >
+          <svg
+            data-icon="caret-down"
+            height="16"
+            role="img"
+            viewBox="0 0 16 16"
+            width="16"
+          >
+            <path
+              d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 
4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
+              fill-rule="evenodd"
+            />
+          </svg>
+        </span>
+      </button>
+    </span>
+    <span
+      class="max-tasks-button bp5-popover-target"
+    >
+      <button
+        aria-expanded="false"
+        aria-haspopup="menu"
+        class="bp5-button"
+        type="button"
+      >
+        <span
+          class="bp5-button-text"
+        >
+          Max tasks: 9 (full cluster capacity)
+        </span>
+        <span
+          aria-hidden="true"
+          class="bp5-icon bp5-icon-caret-down"
+        >
+          <svg
+            data-icon="caret-down"
+            height="16"
+            role="img"
+            viewBox="0 0 16 16"
+            width="16"
+          >
+            <path
+              d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 
4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
+              fill-rule="evenodd"
+            />
+          </svg>
+        </span>
+      </button>
+    </span>
+  </div>
+</div>
+`;
+
+exports[`RunPanel matches snapshot on native (auto) query 1`] = `
+<div
+  class="run-panel"
+>
+  <button
+    class="bp5-button bp5-intent-primary"
+    type="button"
+  >
+    <span
+      aria-hidden="true"
+      class="bp5-icon bp5-icon-caret-right"
+    >
+      <svg
+        data-icon="caret-right"
+        height="16"
+        role="img"
+        viewBox="0 0 16 16"
+        width="16"
+      >
+        <path
+          d="M11 8c0-.15-.07-.28-.17-.37l-4-3.5A.495.495 0 006 4.5v7a.495.495 
0 00.83.37l4-3.5c.1-.09.17-.22.17-.37z"
+          fill-rule="evenodd"
+        />
+      </svg>
+    </span>
+    <span
+      class="bp5-button-text"
+    >
+      Run
+    </span>
+  </button>
+  <div
+    class="bp5-button-group"
+  >
+    <span
+      class="bp5-popover-target"
+    >
+      <button
+        aria-expanded="false"
+        aria-haspopup="menu"
+        class="bp5-button"
+        type="button"
+      >
+        <span
+          class="bp5-button-text"
+        >
+          Engine: auto (sql-native)
+        </span>
+        <span
+          aria-hidden="true"
+          class="bp5-icon bp5-icon-caret-down"
+        >
+          <svg
+            data-icon="caret-down"
+            height="16"
+            role="img"
+            viewBox="0 0 16 16"
+            width="16"
+          >
+            <path
+              d="M12 6.5c0-.28-.22-.5-.5-.5h-7a.495.495 0 00-.37.83l3.5 
4c.09.1.22.17.37.17s.28-.07.37-.17l3.5-4c.08-.09.13-.2.13-.33z"
+              fill-rule="evenodd"
+            />
+          </svg>
+        </span>
+      </button>
+    </span>
+  </div>
+</div>
+`;
diff --git a/web-console/src/views/workbench-view/run-panel/run-panel.spec.tsx 
b/web-console/src/views/workbench-view/run-panel/run-panel.spec.tsx
new file mode 100644
index 00000000000..5416984c3db
--- /dev/null
+++ b/web-console/src/views/workbench-view/run-panel/run-panel.spec.tsx
@@ -0,0 +1,60 @@
+/*
+ * 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 { render } from '@testing-library/react';
+import React from 'react';
+
+import { DEFAULT_SERVER_QUERY_CONTEXT, DRUID_ENGINES, WorkbenchQuery } from 
'../../../druid-models';
+
+import { RunPanel } from './run-panel';
+
+describe('RunPanel', () => {
+  it('matches snapshot on native (auto) query', () => {
+    const runPanel = (
+      <RunPanel
+        query={WorkbenchQuery.blank().changeQueryString(`SELECT * FROM 
wikipedia`)}
+        onQueryChange={() => {}}
+        running={false}
+        onRun={() => {}}
+        queryEngines={DRUID_ENGINES}
+        clusterCapacity={9}
+        defaultQueryContext={DEFAULT_SERVER_QUERY_CONTEXT}
+      />
+    );
+    const { container } = render(runPanel);
+    expect(container.firstChild).toMatchSnapshot();
+  });
+
+  it('matches snapshot on msq (auto) query', () => {
+    const runPanel = (
+      <RunPanel
+        query={WorkbenchQuery.blank()
+          .changeQueryString(`SELECT * FROM wikipedia`)
+          .changeEngine('sql-msq-task')}
+        onQueryChange={() => {}}
+        running={false}
+        onRun={() => {}}
+        queryEngines={DRUID_ENGINES}
+        clusterCapacity={9}
+        defaultQueryContext={DEFAULT_SERVER_QUERY_CONTEXT}
+      />
+    );
+    const { container } = render(runPanel);
+    expect(container.firstChild).toMatchSnapshot();
+  });
+});
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 9ed135da354..e329f9d383b 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
@@ -103,7 +103,6 @@ export interface RunPanelProps
   query: WorkbenchQuery;
   onQueryChange(query: WorkbenchQuery): void;
   running: boolean;
-  small?: boolean;
   onRun(preview: boolean): void | Promise<void>;
   queryEngines: DruidEngine[];
   clusterCapacity: number | undefined;
@@ -120,7 +119,6 @@ export const RunPanel = React.memo(function RunPanel(props: 
RunPanelProps) {
     onRun,
     moreMenu,
     running,
-    small,
     queryEngines,
     clusterCapacity,
     defaultQueryContext,
@@ -166,6 +164,11 @@ export const RunPanel = React.memo(function 
RunPanel(props: RunPanelProps) {
     queryContext,
     defaultQueryContext,
   );
+  const useConcurrentLocks = getQueryContextKey(
+    'useConcurrentLocks',
+    queryContext,
+    defaultQueryContext,
+  );
   const finalizeAggregations = queryContext.finalizeAggregations;
   const waitUntilSegmentsLoad = queryContext.waitUntilSegmentsLoad;
   const groupByEnableMultiValueUnnesting = 
queryContext.groupByEnableMultiValueUnnesting;
@@ -198,7 +201,6 @@ export const RunPanel = React.memo(function RunPanel(props: 
RunPanelProps) {
   }, [onRun]);
 
   const hotkeys = useMemo(() => {
-    if (small) return [];
     return [
       {
         allowInInput: true,
@@ -217,7 +219,7 @@ export const RunPanel = React.memo(function RunPanel(props: 
RunPanelProps) {
         onKeyDown: handlePreview,
       },
     ];
-  }, [small, handleRun, handlePreview]);
+  }, [handleRun, handlePreview]);
 
   useHotkeys(hotkeys);
 
@@ -264,9 +266,7 @@ export const RunPanel = React.memo(function RunPanel(props: 
RunPanelProps) {
         icon={IconNames.CARET_RIGHT}
         onClick={() => void onRun(false)}
         text="Run"
-        intent={!emptyQuery && !small ? Intent.PRIMARY : undefined}
-        small={small}
-        minimal={small}
+        intent={!emptyQuery ? Intent.PRIMARY : undefined}
       />
       {ingestMode && (
         <Button
@@ -274,11 +274,9 @@ export const RunPanel = React.memo(function 
RunPanel(props: RunPanelProps) {
           icon={IconNames.EYE_OPEN}
           onClick={() => void onRun(true)}
           text="Preview"
-          small={small}
-          minimal={small}
         />
       )}
-      {!small && onQueryChange && (
+      {onQueryChange && (
         <ButtonGroup>
           <Popover
             position={Position.BOTTOM_LEFT}
@@ -366,6 +364,45 @@ export const RunPanel = React.memo(function 
RunPanel(props: RunPanelProps) {
                 )}
                 {effectiveEngine === 'sql-msq-task' ? (
                   <>
+                    <MenuItem icon={IconNames.BRING_DATA} text="INSERT / 
REPLACE specific context">
+                      <MenuCheckbox
+                        checked={useConcurrentLocks}
+                        text="Use concurrent locks"
+                        onChange={() =>
+                          changeQueryContext({
+                            ...queryContext,
+                            useConcurrentLocks: !useConcurrentLocks,
+                          })
+                        }
+                      />
+                      <MenuTristate
+                        icon={IconNames.DISABLE}
+                        text="Fail on empty insert"
+                        value={failOnEmptyInsert}
+                        undefinedEffectiveValue={false}
+                        onValueChange={failOnEmptyInsert =>
+                          changeQueryContext({ ...queryContext, 
failOnEmptyInsert })
+                        }
+                      />
+                      <MenuTristate
+                        icon={IconNames.STOPWATCH}
+                        text="Wait until segments have loaded"
+                        value={waitUntilSegmentsLoad}
+                        undefinedEffectiveValue={ingestMode}
+                        onValueChange={waitUntilSegmentsLoad =>
+                          changeQueryContext({ ...queryContext, 
waitUntilSegmentsLoad })
+                        }
+                      />
+                      <MenuItem
+                        icon={IconNames.TH_DERIVED}
+                        text="Edit index spec"
+                        label={summarizeIndexSpec(indexSpec)}
+                        shouldDismissPopover={false}
+                        onClick={() => {
+                          setIndexSpecDialogSpec(indexSpec || {});
+                        }}
+                      />
+                    </MenuItem>
                     <MenuItem
                       icon={IconNames.ERROR}
                       text="Max parse exceptions"
@@ -383,15 +420,6 @@ export const RunPanel = React.memo(function 
RunPanel(props: RunPanelProps) {
                         />
                       ))}
                     </MenuItem>
-                    <MenuTristate
-                      icon={IconNames.DISABLE}
-                      text="Fail on empty insert"
-                      value={failOnEmptyInsert}
-                      undefinedEffectiveValue={false}
-                      onValueChange={failOnEmptyInsert =>
-                        changeQueryContext({ ...queryContext, 
failOnEmptyInsert })
-                      }
-                    />
                     <MenuTristate
                       icon={IconNames.TRANSLATE}
                       text="Finalize aggregations"
@@ -401,15 +429,6 @@ export const RunPanel = React.memo(function 
RunPanel(props: RunPanelProps) {
                         changeQueryContext({ ...queryContext, 
finalizeAggregations })
                       }
                     />
-                    <MenuTristate
-                      icon={IconNames.STOPWATCH}
-                      text="Wait until segments have loaded"
-                      value={waitUntilSegmentsLoad}
-                      undefinedEffectiveValue={ingestMode}
-                      onValueChange={waitUntilSegmentsLoad =>
-                        changeQueryContext({ ...queryContext, 
waitUntilSegmentsLoad })
-                      }
-                    />
                     <MenuTristate
                       icon={IconNames.FORK}
                       text="Enable GroupBy multi-value unnesting"
@@ -477,15 +496,6 @@ export const RunPanel = React.memo(function 
RunPanel(props: RunPanelProps) {
                         })
                       }
                     />
-                    <MenuItem
-                      icon={IconNames.TH_DERIVED}
-                      text="Edit index spec"
-                      label={summarizeIndexSpec(indexSpec)}
-                      shouldDismissPopover={false}
-                      onClick={() => {
-                        setIndexSpecDialogSpec(indexSpec || {});
-                      }}
-                    />
                   </>
                 ) : (
                   <>
@@ -602,7 +612,7 @@ export const RunPanel = React.memo(function RunPanel(props: 
RunPanelProps) {
       )}
       {moreMenu && (
         <Popover position={Position.BOTTOM_LEFT} content={moreMenu}>
-          <Button small={small} minimal={small} rightIcon={IconNames.MORE} />
+          <Button rightIcon={IconNames.MORE} />
         </Popover>
       )}
       {editContextDialogOpen && (


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to