From 2330feb4cba0ca9eb7c6e785c123bdc295f530a3 Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:01:07 -0400 Subject: [PATCH 1/7] HPCC-32603 prevent Grid network races adds AbortController signals to the Grid's queries, so that subsequent requests will properly abort any pending request Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/package-lock.json | 9 ++++----- esp/src/package.json | 2 +- esp/src/src-react/components/controls/Grid.tsx | 11 ++++++++++- esp/src/src/ESPWorkunit.ts | 4 ++-- esp/src/src/store/Deferred.ts | 2 +- esp/src/src/store/Paged.ts | 6 +++--- esp/src/src/store/Store.ts | 11 ++++++++--- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/esp/src/package-lock.json b/esp/src/package-lock.json index 3391efbb526..d38e8aecddd 100644 --- a/esp/src/package-lock.json +++ b/esp/src/package-lock.json @@ -18,7 +18,7 @@ "@hpcc-js/chart": "2.84.1", "@hpcc-js/codemirror": "2.63.0", "@hpcc-js/common": "2.72.0", - "@hpcc-js/comms": "2.95.0", + "@hpcc-js/comms": "2.96.0", "@hpcc-js/dataflow": "8.1.7", "@hpcc-js/eclwatch": "2.75.3", "@hpcc-js/graph": "2.86.0", @@ -2082,10 +2082,9 @@ } }, "node_modules/@hpcc-js/comms": { - "version": "2.95.0", - "resolved": "https://registry.npmjs.org/@hpcc-js/comms/-/comms-2.95.0.tgz", - "integrity": "sha512-kzEyDxf1Msus5rhU0yO826JxgIl2kh/bI7yNTxHAlCfLKp4SU//zrj/MK5SuEDs2lUHvmTkfx1jbfGUAK3RGFg==", - "license": "Apache-2.0", + "version": "2.96.0", + "resolved": "https://registry.npmjs.org/@hpcc-js/comms/-/comms-2.96.0.tgz", + "integrity": "sha512-8faDDSBvH22lN1LHhD6xtoT/FSV3YGu7hZahuRtKp4JG27ai73AFcNOJNxyqUZ9SLN7R3oNrujqp04xpyQ6nIA==", "dependencies": { "@hpcc-js/ddl-shim": "^2.21.0", "@hpcc-js/util": "^2.52.0", diff --git a/esp/src/package.json b/esp/src/package.json index de3511485ec..9c023a0d207 100644 --- a/esp/src/package.json +++ b/esp/src/package.json @@ -44,7 +44,7 @@ "@hpcc-js/chart": "2.84.1", "@hpcc-js/codemirror": "2.63.0", "@hpcc-js/common": "2.72.0", - "@hpcc-js/comms": "2.95.0", + "@hpcc-js/comms": "2.96.0", "@hpcc-js/dataflow": "8.1.7", "@hpcc-js/eclwatch": "2.75.3", "@hpcc-js/graph": "2.86.0", diff --git a/esp/src/src-react/components/controls/Grid.tsx b/esp/src/src-react/components/controls/Grid.tsx index 129271d47b3..277e1ad261b 100644 --- a/esp/src/src-react/components/controls/Grid.tsx +++ b/esp/src/src-react/components/controls/Grid.tsx @@ -237,12 +237,21 @@ const FluentStoreGrid: React.FunctionComponent = ({ }); }); + const abortController = React.useRef(); + + React.useEffect(() => { + if (abortController.current) { + abortController.current.abort({ message: "Grid aborting stale request" }); + } + abortController.current = new AbortController(); + }, [query]); + const refreshTable = useDeepCallback((clearSelection = false) => { if (isNaN(start) || isNaN(count)) return; if (clearSelection) { selectionHandler.setItems([], true); } - const storeQuery = store.query({ ...query }, { start, count, sort: sorted ? [sorted] : undefined }); + const storeQuery = store.query({ ...query }, { start, count, sort: sorted ? [sorted] : undefined }, abortController.current.signal); storeQuery.total.then(total => { setTotal(total); }); diff --git a/esp/src/src/ESPWorkunit.ts b/esp/src/src/ESPWorkunit.ts index 1efadc5afc1..5cb9b91aeb5 100644 --- a/esp/src/src/ESPWorkunit.ts +++ b/esp/src/src/ESPWorkunit.ts @@ -1082,11 +1082,11 @@ export function CreateWUQueryStore(): BaseStore { + }, "Wuid", (request, abortSignal) => { if (request.Sortby && request.Sortby === "TotalClusterTime") { request.Sortby = "ClusterTime"; } - return service.WUQuery(request).then(response => { + return service.WUQuery(request, abortSignal).then(response => { const page = { start: undefined, end: undefined diff --git a/esp/src/src/store/Deferred.ts b/esp/src/src/store/Deferred.ts index db7c3288666..a0f4d0c65ce 100644 --- a/esp/src/src/store/Deferred.ts +++ b/esp/src/src/store/Deferred.ts @@ -68,7 +68,7 @@ export class Deferred implements Thenable { } } -export class DeferredResponse extends Deferred { +export class DeferredResponse extends Deferred { // --- Legacy Dojo Support (fake QeuryResults) --- forEach(callback) { diff --git a/esp/src/src/store/Paged.ts b/esp/src/src/store/Paged.ts index eb57375376a..b4c1025e8db 100644 --- a/esp/src/src/store/Paged.ts +++ b/esp/src/src/store/Paged.ts @@ -16,7 +16,7 @@ function dataPage(array: T[], start: number, size: number, total: number): Pa return retVal; } -type FetchData = (query: QueryRequest) => Thenable<{ data: T[], total: number }>; +type FetchData = (query: QueryRequest, abortSignal?: AbortSignal) => Thenable<{ data: T[], total: number }>; export interface RequestFields { start: keyof T; @@ -43,7 +43,7 @@ export class Paged ext this._fetchData = fetchData; } - fetchData(request: QueryRequest, options: QueryOptions): ThenableResponse { + fetchData(request: QueryRequest, options: QueryOptions, abortSignal?: AbortSignal): ThenableResponse { if (options.start !== undefined && options.count !== undefined) { request[this._requestFields.start] = options.start as any; request[this._requestFields.count] = options.count as any; @@ -52,7 +52,7 @@ export class Paged ext request[this._requestFields.sortBy] = options.sort[0].attribute as any; request[this._requestFields.descending] = options.sort[0].descending as any; } - return this._fetchData(request).then(response => { + return this._fetchData(request, abortSignal).then(response => { response.data.forEach(row => { this.index[this.getIdentity(row)] = row; }); diff --git a/esp/src/src/store/Store.ts b/esp/src/src/store/Store.ts index d41d24e893c..9e8aab02b15 100644 --- a/esp/src/src/store/Store.ts +++ b/esp/src/src/store/Store.ts @@ -1,5 +1,8 @@ import * as QueryResults from "dojo/store/util/QueryResults"; import { DeferredResponse, Thenable } from "./Deferred"; +import { scopedLogger } from "@hpcc-js/util"; + +const logger = scopedLogger("src/store/Store.ts"); // Query --- export type Key = string | number | symbol; @@ -32,7 +35,7 @@ export abstract class BaseStore { this.responseIDField = responseIDField; } - protected abstract fetchData(request: QueryRequest, options: QueryOptions): ThenableResponse; + protected abstract fetchData(request: QueryRequest, options: QueryOptions, abortSignal?: AbortSignal): ThenableResponse; abstract get(id: string | number): T; @@ -40,11 +43,13 @@ export abstract class BaseStore { return object[this.responseIDField]; } - protected query(request: QueryRequest, options: QueryOptions): DeferredResponse { + protected query(request: QueryRequest, options: QueryOptions, abortSignal?: AbortSignal): DeferredResponse { const retVal = new DeferredResponse(); - this.fetchData(request, options).then((data: QueryResponse) => { + this.fetchData(request, options, abortSignal).then((data: QueryResponse) => { retVal.total.resolve(data.total); retVal.resolve(data); + }, (err) => { + logger.debug(err); }); return QueryResults(retVal); } From 3b27444f99b7d2a21d835750ead11bf9d977facf Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Fri, 13 Sep 2024 15:44:48 +0100 Subject: [PATCH 2/7] Split off 9.2.122 Signed-off-by: Jake Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- version.cmake | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index ebfbe3c60c4..bbf494b7028 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 9.2.121-closedown0 +version: 9.2.123-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 9.2.121-closedown0 +appVersion: 9.2.123-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index a59efa7c3dd..496bda4e36f 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1361,7 +1361,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.2.121-closedown0 +helmVersion: 9.2.123-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index 1fa7a287d76..7095875c96e 100644 --- a/version.cmake +++ b/version.cmake @@ -5,8 +5,8 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 9 ) set ( HPCC_MINOR 2 ) -set ( HPCC_POINT 121 ) +set ( HPCC_POINT 123 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-09-05T16:41:58Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-09-13T14:44:48Z" ) ### From 81e878937a28c110480cc3b4ec8532233bd0c427 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Mon, 16 Sep 2024 14:39:37 +0100 Subject: [PATCH 3/7] HPCC-32641 Metrics occasionally shows a blank page Removed lazy loading of metrics page. Signed-off-by: Gordon Smith --- esp/src/src-react/components/WorkunitDetails.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/esp/src/src-react/components/WorkunitDetails.tsx b/esp/src/src-react/components/WorkunitDetails.tsx index 8e595bf7b16..f30bbf974ae 100644 --- a/esp/src/src-react/components/WorkunitDetails.tsx +++ b/esp/src/src-react/components/WorkunitDetails.tsx @@ -27,8 +27,7 @@ import { Workflows } from "./Workflows"; import { WorkunitSummary } from "./WorkunitSummary"; import { TabInfo, DelayLoadedPanel, OverflowTabList } from "./controls/TabbedPanes/index"; import { ECLArchive } from "./ECLArchive"; - -const Metrics = React.lazy(() => import("./Metrics").then(mod => ({ default: mod.Metrics }))); +import { Metrics } from "./Metrics"; const logger = scopedLogger("src-react/components/WorkunitDetails.tsx"); From 2e65a77954391f51af2dc232b68d25f4ee144c57 Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Mon, 16 Sep 2024 10:30:46 -0400 Subject: [PATCH 4/7] HPCC-32669 ECL Watch v9 fix grids missing command bars fixes an issue where the CommandBar components for some WU and File details tabs were hidden by the contents of the grid contents Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/src-react/components/Helpers.tsx | 31 +++++++-------- esp/src/src-react/components/InfoGrid.tsx | 2 +- esp/src/src-react/components/LogViewer.tsx | 18 ++++----- .../src-react/components/MetricsOptions.tsx | 22 ++++++----- esp/src/src-react/components/Resources.tsx | 37 +++++++++--------- esp/src/src-react/components/Results.tsx | 33 ++++++++-------- esp/src/src-react/components/SourceFiles.tsx | 37 +++++++++--------- esp/src/src-react/components/SubFiles.tsx | 37 +++++++++--------- esp/src/src-react/components/SuperFiles.tsx | 31 +++++++-------- esp/src/src-react/components/Variables.tsx | 33 ++++++++-------- esp/src/src-react/components/Workflows.tsx | 33 ++++++++-------- .../src-react/components/controls/Grid.tsx | 38 ++++++++++--------- 12 files changed, 182 insertions(+), 170 deletions(-) diff --git a/esp/src/src-react/components/Helpers.tsx b/esp/src/src-react/components/Helpers.tsx index 458308debd8..73fed185eca 100644 --- a/esp/src/src-react/components/Helpers.tsx +++ b/esp/src/src-react/components/Helpers.tsx @@ -1,8 +1,9 @@ import * as React from "react"; -import { CommandBar, ContextualMenuItemType, ICommandBarItemProps, Link, ScrollablePane, Sticky } from "@fluentui/react"; +import { CommandBar, ContextualMenuItemType, ICommandBarItemProps, Link } from "@fluentui/react"; import * as ESPRequest from "src/ESPRequest"; import nlsHPCC from "src/nlsHPCC"; import { HelperRow, useWorkunitHelpers } from "../hooks/workunit"; +import { HolyGrail } from "../layouts/HolyGrail"; import { FluentGrid, useCopyButtons, useFluentStoreState, FluentColumns } from "./controls/Grid"; import { ShortVerticalDivider } from "./Common"; @@ -223,18 +224,18 @@ export const Helpers: React.FunctionComponent = ({ setData(helpers); }, [helpers]); - return - - - - - ; + return } + main={ + + } + />; }; diff --git a/esp/src/src-react/components/InfoGrid.tsx b/esp/src/src-react/components/InfoGrid.tsx index ec028305d8b..5860ef755bc 100644 --- a/esp/src/src-react/components/InfoGrid.tsx +++ b/esp/src/src-react/components/InfoGrid.tsx @@ -236,7 +236,7 @@ export const InfoGrid: React.FunctionComponent = ({ } }, [data.length]); - return
+ return
{({ size }) => = ({ return } main={ -
- -
+ } />; }; diff --git a/esp/src/src-react/components/MetricsOptions.tsx b/esp/src/src-react/components/MetricsOptions.tsx index ce48f07513e..aa0d20a108f 100644 --- a/esp/src/src-react/components/MetricsOptions.tsx +++ b/esp/src/src-react/components/MetricsOptions.tsx @@ -67,16 +67,18 @@ const GridOptions: React.FunctionComponent = ({ } }, [selectionHandler, strSelection]); - return ; + return
+ +
; }; interface AddLabelProps { diff --git a/esp/src/src-react/components/Resources.tsx b/esp/src/src-react/components/Resources.tsx index d3cb0a73a53..ccae64dfa5e 100644 --- a/esp/src/src-react/components/Resources.tsx +++ b/esp/src/src-react/components/Resources.tsx @@ -1,9 +1,10 @@ import * as React from "react"; -import { CommandBar, ContextualMenuItemType, ICommandBarItemProps, Link, ScrollablePane, Sticky } from "@fluentui/react"; +import { CommandBar, ContextualMenuItemType, ICommandBarItemProps, Link } from "@fluentui/react"; import nlsHPCC from "src/nlsHPCC"; import { QuerySortItem } from "src/store/Store"; import { useWorkunitResources } from "../hooks/workunit"; import { updateParam } from "../util/history"; +import { HolyGrail } from "../layouts/HolyGrail"; import { FluentGrid, useCopyButtons, useFluentStoreState, FluentColumns } from "./controls/Grid"; import { ShortVerticalDivider } from "./Common"; import { IFrame } from "./IFrame"; @@ -108,21 +109,21 @@ export const Resources: React.FunctionComponent = ({ })); }, [resources, wuid]); - return - - - - {preview && webUrl ? -