From 2ceb8bf3350f10a09201c0649b9582baa44fcc34 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Fri, 18 Oct 2024 15:38:08 +0100 Subject: [PATCH 01/10] HPCC-32830 Add missing dependencies to WUDetails Fails to render in standalone mode (without the frame), due to missing dependencies Signed-off-by: Gordon Smith --- esp/src/eclwatch/WUDetailsWidget.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp/src/eclwatch/WUDetailsWidget.js b/esp/src/eclwatch/WUDetailsWidget.js index 411bba32c52..a6d214c7697 100644 --- a/esp/src/eclwatch/WUDetailsWidget.js +++ b/esp/src/eclwatch/WUDetailsWidget.js @@ -41,6 +41,8 @@ define([ "dijit/form/TextBox", "dijit/Dialog", "dijit/form/SimpleTextarea", + "dijit/form/DateTextBox", + "dijit/form/TimeTextBox", "hpcc/TableContainer" ], function (declare, lang, nlsHPCCMod, dom, domAttr, domClass, topic, From 9a1e3b9d94a0251ad42435d039dc7eca798120c4 Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Fri, 18 Oct 2024 16:32:52 +0100 Subject: [PATCH 02/10] Split off 9.4.106 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 5574efcd95b..3ec28c099ec 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.4.105-closedown0 +version: 9.4.107-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.4.105-closedown0 +appVersion: 9.4.107-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index f29cbccc8d4..cce63f1e4ee 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1473,7 +1473,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.4.105-closedown0 +helmVersion: 9.4.107-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index 81be0842570..72e0161a682 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 4 ) -set ( HPCC_POINT 105 ) +set ( HPCC_POINT 107 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-10-14T15:47:43Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-10-18T15:32:52Z" ) ### From 4a7afe314548be3384b0752e095bf966e3b99976 Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Fri, 18 Oct 2024 16:33:39 +0100 Subject: [PATCH 03/10] Split off 9.2.132 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 f22b2a933cf..4ce3ab22457 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.131-closedown0 +version: 9.2.133-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.131-closedown0 +appVersion: 9.2.133-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index aec2e179876..ea2cbb8672c 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.131-closedown0 +helmVersion: 9.2.133-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index 322310289e1..6e656f9b5a0 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 131 ) +set ( HPCC_POINT 133 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-10-14T15:48:48Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-10-18T15:33:39Z" ) ### From 75aebafee8caddda6ff79e9d40e575e0d055c78c Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Fri, 18 Oct 2024 17:40:16 +0100 Subject: [PATCH 04/10] HPCC-32834 Persist fullscreen mode in address bar Add fullscreen button to WU Summary Signed-off-by: Gordon Smith --- esp/src/src-react/components/Metrics.tsx | 41 +++-- .../src-react/components/WorkunitDetails.tsx | 6 +- .../src-react/components/WorkunitSummary.tsx | 142 ++++++++++-------- esp/src/src-react/routes.tsx | 2 +- 4 files changed, 109 insertions(+), 82 deletions(-) diff --git a/esp/src/src-react/components/Metrics.tsx b/esp/src/src-react/components/Metrics.tsx index 0cb9a7aff41..3d1f91cc2bd 100644 --- a/esp/src/src-react/components/Metrics.tsx +++ b/esp/src/src-react/components/Metrics.tsx @@ -15,7 +15,7 @@ import { HolyGrail } from "../layouts/HolyGrail"; import { AutosizeComponent, AutosizeHpccJSComponent } from "../layouts/HpccJSAdapter"; import { DockPanel, DockPanelItem, ResetableDockPanel } from "../layouts/DockPanel"; import { LayoutStatus, MetricGraph, MetricGraphWidget, isGraphvizWorkerResponse, layoutCache } from "../util/metricGraph"; -import { pushUrl } from "../util/history"; +import { pushUrl as _pushUrl } from "../util/history"; import { debounce } from "../util/throttle"; import { ErrorBoundary } from "../util/errorBoundary"; import { ShortVerticalDivider } from "./Common"; @@ -45,6 +45,7 @@ interface MetricsProps { queryId?: string; parentUrl?: string; selection?: string; + fullscreen?: boolean; } export const Metrics: React.FunctionComponent = ({ @@ -52,7 +53,8 @@ export const Metrics: React.FunctionComponent = ({ querySet = "", queryId = "", parentUrl = `/workunits/${wuid}/metrics`, - selection + selection, + fullscreen = false }) => { const [_uiState, _setUIState] = React.useState({ ...defaultUIState }); const [selectedMetricsSource, setSelectedMetricsSource] = React.useState(""); @@ -63,7 +65,6 @@ export const Metrics: React.FunctionComponent = ({ const [showMetricOptions, setShowMetricOptions] = React.useState(false); const [dockpanel, setDockpanel] = React.useState(); const [trackSelection, setTrackSelection] = React.useState(true); - const [fullscreen, setFullscreen] = React.useState(false); const [hotspots, setHotspots] = React.useState(""); const [lineage, setLineage] = React.useState([]); const [selectedLineage, setSelectedLineage] = React.useState(); @@ -96,10 +97,24 @@ export const Metrics: React.FunctionComponent = ({ }).catch(err => logger.error(err)); }, [wuid]); + const pushUrl = React.useCallback((selection?: string, fullscreen?: boolean) => { + const selectionStr = selection?.length ? `/${selection}` : ""; + const fullscreenStr = fullscreen ? "?fullscreen" : ""; + _pushUrl(`${parentUrl}${selectionStr}${fullscreenStr}`); + }, [parentUrl]); + + const pushSelectionUrl = React.useCallback((selection: string) => { + pushUrl(selection, fullscreen); + }, [fullscreen, pushUrl]); + + const pushFullscreenUrl = React.useCallback((fullscreen: boolean) => { + pushUrl(selection, fullscreen); + }, [pushUrl, selection]); + const onHotspot = React.useCallback(() => { setSelectedMetricsSource("hotspot"); - pushUrl(`${parentUrl}/${selection}`); - }, [parentUrl, selection]); + pushSelectionUrl(selection); + }, [pushSelectionUrl, selection]); // Timeline --- const timeline = useConst(() => new WUTimelineNoFetch() @@ -114,11 +129,11 @@ export const Metrics: React.FunctionComponent = ({ timeline.selection([]); setSelectedMetricsSource("scopesTable"); setScopeFilter(`name:${row[7].__hpcc_id}`); - pushUrl(`${parentUrl}/${row[7].id}`); + pushSelectionUrl(row[7].id); } }, true) ; - }, [parentUrl, timeline]); + }, [pushSelectionUrl, timeline]); React.useEffect(() => { if (view.showTimeline) { @@ -142,10 +157,10 @@ export const Metrics: React.FunctionComponent = ({ .on("selectionChanged", () => { const selection = metricGraphWidget.selection().filter(id => metricGraph.item(id)).map(id => metricGraph.item(id).id); setSelectedMetricsSource("metricGraphWidget"); - pushUrl(`${parentUrl}/${selection.join(",")}`); + pushSelectionUrl(selection.join(",")); }, true) ; - }, [metricGraph, metricGraphWidget, parentUrl]); + }, [metricGraph, metricGraphWidget, pushSelectionUrl]); React.useEffect(() => { metricGraph.load(metrics); @@ -301,8 +316,8 @@ export const Metrics: React.FunctionComponent = ({ const scopesSelectionChanged = React.useCallback((source: SelectedMetricsSource, selection: IScope[]) => { setSelectedMetricsSource(source); - pushUrl(`${parentUrl}/${selection.map(row => row.__lparam?.id ?? row.id).join(",")}`); - }, [parentUrl]); + pushSelectionUrl(selection.map(row => row.__lparam?.id ?? row.id).join(",")); + }, [pushSelectionUrl]); const scopesTable = useConst(() => new ScopesTable() .multiSelect(true) @@ -520,9 +535,9 @@ export const Metrics: React.FunctionComponent = ({ { key: "divider_2", itemType: ContextualMenuItemType.Divider, onRender: () => }, { key: "fullscreen", title: nlsHPCC.MaximizeRestore, iconProps: { iconName: fullscreen ? "ChromeRestore" : "FullScreen" }, - onClick: () => setFullscreen(!fullscreen) + onClick: () => pushFullscreenUrl(!fullscreen) } - ], [dot, formatColumns, fullscreen, metrics, wuid]); + ], [dot, formatColumns, fullscreen, metrics, pushFullscreenUrl, wuid]); const setShowMetricOptionsHook = React.useCallback((show: boolean) => { setShowMetricOptions(show); diff --git a/esp/src/src-react/components/WorkunitDetails.tsx b/esp/src/src-react/components/WorkunitDetails.tsx index f30bbf974ae..1b890826fce 100644 --- a/esp/src/src-react/components/WorkunitDetails.tsx +++ b/esp/src/src-react/components/WorkunitDetails.tsx @@ -40,7 +40,7 @@ interface WorkunitDetailsProps { parentUrl?: string; tab?: string; state?: { outputs?: string, metrics?: string, resources?: string, helpers?: string, eclsummary?: string }; - queryParams?: { outputs?: StringStringMap, inputs?: StringStringMap, resources?: StringStringMap, helpers?: StringStringMap, logs?: StringStringMap }; + queryParams?: { summary?: StringStringMap, outputs?: StringStringMap, inputs?: StringStringMap, metrics?: StringStringMap, resources?: StringStringMap, helpers?: StringStringMap, logs?: StringStringMap }; } export const WorkunitDetails: React.FunctionComponent = ({ @@ -180,7 +180,7 @@ export const WorkunitDetails: React.FunctionComponent = ({
- + @@ -205,7 +205,7 @@ export const WorkunitDetails: React.FunctionComponent = ({ }> - + diff --git a/esp/src/src-react/components/WorkunitSummary.tsx b/esp/src/src-react/components/WorkunitSummary.tsx index 8e74c0b008c..a519dd1a36c 100644 --- a/esp/src/src-react/components/WorkunitSummary.tsx +++ b/esp/src/src-react/components/WorkunitSummary.tsx @@ -9,6 +9,7 @@ import { useConfirm } from "../hooks/confirm"; import { useWorkunit, useWorkunitExceptions } from "../hooks/workunit"; import { ReflexContainer, ReflexElement, ReflexSplitter } from "../layouts/react-reflex"; import { pushUrl, replaceUrl } from "../util/history"; +import { HolyGrail } from "../layouts/HolyGrail"; import { ShortVerticalDivider } from "./Common"; import { TableGroup } from "./forms/Groups"; import { PublishQueryForm } from "./forms/PublishQuery"; @@ -26,10 +27,12 @@ interface MessageBarContent { interface WorkunitSummaryProps { wuid: string; + fullscreen?: boolean; } export const WorkunitSummary: React.FunctionComponent = ({ - wuid + wuid, + fullscreen = false }) => { const [workunit, , , , refresh] = useWorkunit(wuid, true); @@ -171,6 +174,13 @@ export const WorkunitSummary: React.FunctionComponent = ({ }, ], [_protected, canDelete, canDeschedule, canReschedule, canSave, description, jobname, refresh, refreshSavings, setShowDeleteConfirm, showMessageBar, workunit, wuid]); + const rightButtons = React.useMemo((): ICommandBarItemProps[] => [ + { + key: "fullscreen", title: nlsHPCC.MaximizeRestore, iconProps: { iconName: fullscreen ? "ChromeRestore" : "FullScreen" }, + onClick: () => pushUrl(`/workunits/${wuid}${fullscreen ? "" : "?fullscreen"}`) + } + ], [fullscreen, wuid]); + const serviceNames = React.useMemo(() => { return workunit?.ServiceNames?.Item?.join("\n") || ""; }, [workunit?.ServiceNames?.Item]); @@ -190,68 +200,70 @@ export const WorkunitSummary: React.FunctionComponent = ({ }, 0) || 0; }, [exceptions]); - return <> - - -
- - - - {messageBarContent && - - {messageBarContent.message} - - } - - - -
- -
-
- 0 ? Math.round((potentialSavings / totalCosts) * 10000) / 100 : 0}%)`, readonly: true }, - "compileCost": { label: nlsHPCC.CompileCost, type: "string", value: `${formatCost(workunit?.CompileCost)}`, readonly: true }, - "executeCost": { label: nlsHPCC.ExecuteCost, type: "string", value: `${formatCost(workunit?.ExecuteCost)}`, readonly: true }, - "fileAccessCost": { label: nlsHPCC.FileAccessCost, type: "string", value: `${formatCost(workunit?.FileAccessCost)}`, readonly: true }, - "protected": { label: nlsHPCC.Protected, type: "checkbox", value: _protected }, - "cluster": { label: nlsHPCC.Cluster, type: "string", value: workunit?.Cluster, readonly: true }, - "totalClusterTime": { label: nlsHPCC.TotalClusterTime, type: "string", value: workunit?.TotalClusterTime ? workunit?.TotalClusterTime : "0.00", readonly: true }, - "abortedBy": { label: nlsHPCC.AbortedBy, type: "string", value: workunit?.AbortBy, readonly: true }, - "abortedTime": { label: nlsHPCC.AbortedTime, type: "string", value: workunit?.AbortTime, readonly: true }, - "ServiceNamesCustom": { label: nlsHPCC.Services, type: "string", value: serviceNames, readonly: true, multiline: true }, - }} onChange={(id, value) => { - switch (id) { - case "jobname": - setJobname(value); - break; - case "description": - setDescription(value); - break; - case "protected": - setProtected(value); - break; - default: - logger.debug(`${id}: ${value}`); - } - }} /> -
-
-
- - - - -
- - - - - ; + return + + +
+ + + + {messageBarContent && + + {messageBarContent.message} + + } + + + +
+ +
+
+ 0 ? Math.round((potentialSavings / totalCosts) * 10000) / 100 : 0}%)`, readonly: true }, + "compileCost": { label: nlsHPCC.CompileCost, type: "string", value: `${formatCost(workunit?.CompileCost)}`, readonly: true }, + "executeCost": { label: nlsHPCC.ExecuteCost, type: "string", value: `${formatCost(workunit?.ExecuteCost)}`, readonly: true }, + "fileAccessCost": { label: nlsHPCC.FileAccessCost, type: "string", value: `${formatCost(workunit?.FileAccessCost)}`, readonly: true }, + "protected": { label: nlsHPCC.Protected, type: "checkbox", value: _protected }, + "cluster": { label: nlsHPCC.Cluster, type: "string", value: workunit?.Cluster, readonly: true }, + "totalClusterTime": { label: nlsHPCC.TotalClusterTime, type: "string", value: workunit?.TotalClusterTime ? workunit?.TotalClusterTime : "0.00", readonly: true }, + "abortedBy": { label: nlsHPCC.AbortedBy, type: "string", value: workunit?.AbortBy, readonly: true }, + "abortedTime": { label: nlsHPCC.AbortedTime, type: "string", value: workunit?.AbortTime, readonly: true }, + "ServiceNamesCustom": { label: nlsHPCC.Services, type: "string", value: serviceNames, readonly: true, multiline: true }, + }} onChange={(id, value) => { + switch (id) { + case "jobname": + setJobname(value); + break; + case "description": + setDescription(value); + break; + case "protected": + setProtected(value); + break; + default: + logger.debug(`${id}: ${value}`); + } + }} /> +
+
+
+ + + + +
+ + + + + } + />; }; diff --git a/esp/src/src-react/routes.tsx b/esp/src/src-react/routes.tsx index bee1c306fd9..e73d78d9823 100644 --- a/esp/src/src-react/routes.tsx +++ b/esp/src/src-react/routes.tsx @@ -25,7 +25,7 @@ const workunitsChildren: Route[] = [ }, { path: "/:Wuid", action: (ctx, params) => import("./components/WorkunitDetails").then(_ => { - return <_.WorkunitDetails wuid={params.Wuid as string} parentUrl={params.parentUrl as string} />; + return <_.WorkunitDetails wuid={params.Wuid as string} parentUrl={params.parentUrl as string} queryParams={{ summary: parseSearch(ctx.search) as any }} />; }) }, { From b8a7e92fe0b89aea01e2ebd723ee9e19b0da47db Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Fri, 18 Oct 2024 12:42:33 -0400 Subject: [PATCH 05/10] HPCC-32835 ECL Watch v9 ZAP dialog default relative time fixes an issue where the ZAP dialog could not be submitted without specifiying some kind of time range for logs; now defaulting to a 24 hour window surrounding the WU start time Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/src-react/components/forms/ZAPDialog.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/esp/src/src-react/components/forms/ZAPDialog.tsx b/esp/src/src-react/components/forms/ZAPDialog.tsx index 3fd329604e0..934e794a439 100644 --- a/esp/src/src-react/components/forms/ZAPDialog.tsx +++ b/esp/src/src-react/components/forms/ZAPDialog.tsx @@ -103,7 +103,7 @@ const defaultValues: ZAPDialogValues = { StartDate: "", EndDate: "", }, - RelativeTimeRangeBuffer: "", + RelativeTimeRangeBuffer: "43200", LineLimit: "10000", LineStartFrom: "0", SelectColumnMode: ColumnMode.DEFAULT, @@ -196,8 +196,11 @@ export const ZAPDialog: React.FunctionComponent = ({ if (key === "AbsoluteTimeRange") { const startDate = logFilter.AbsoluteTimeRange.StartDate ? new Date(logFilter.AbsoluteTimeRange.StartDate).toISOString() : ""; const endDate = logFilter.AbsoluteTimeRange.EndDate ? new Date(logFilter.AbsoluteTimeRange.EndDate).toISOString() : ""; - formData.append("LogFilter_AbsoluteTimeRange_StartDate", startDate); - formData.append("LogFilter_AbsoluteTimeRange_EndDate", endDate); + if (startDate && endDate) { + formData.append("LogFilter_AbsoluteTimeRange_StartDate", startDate); + formData.append("LogFilter_AbsoluteTimeRange_EndDate", endDate); + delete logFilter.RelativeTimeRangeBuffer; + } } else { formData.append(`LogFilter_${key}`, logFilter[key]); } From add2ae5bcef603a80a1e2477cec9e44afc8583a0 Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:54:03 -0400 Subject: [PATCH 06/10] HPCC-32841 ECL Watch v9 Log view missing filter fields fixes an issue introduced by HPCC-32751 which incorrectly removed the "Start Date" and "End Date" fields from the Filter dialog Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/src-react/components/Logs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp/src/src-react/components/Logs.tsx b/esp/src/src-react/components/Logs.tsx index 3fcb095bdc2..a6295657dd8 100644 --- a/esp/src/src-react/components/Logs.tsx +++ b/esp/src/src-react/components/Logs.tsx @@ -228,7 +228,7 @@ export const Logs: React.FunctionComponent = ({ } } const colTypes = logColumns?.map(c => c.LogType.toString()) ?? []; - removeAllExcept(retVal, colTypes); + removeAllExcept(retVal, [...colTypes, "LogLineLimit", "StartDate", "EndDate"]); return retVal; }, [filter, logColumns, wuid]); From 316444ebc1411f3a9e4f4e0f4ba6ee9c908cb8b8 Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Mon, 21 Oct 2024 14:47:31 +0100 Subject: [PATCH 07/10] HPCC-32839 Fix Thor aborting race When a Thor workunit was aborted in k8s, there was a race condition which could cause the job to continue and fail with an unrelated spurious/confusing error. Signed-off-by: Jake Smith --- common/workunit/workunit.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/common/workunit/workunit.cpp b/common/workunit/workunit.cpp index e9efd0e0416..fe32bad10aa 100644 --- a/common/workunit/workunit.cpp +++ b/common/workunit/workunit.cpp @@ -3687,7 +3687,8 @@ EnumMapping priorityClasses[] = { const char * getWorkunitStateStr(WUState state) { - dbgassertex(state < WUStateSize); + if (state >= WUStateSize) + return "unknown workunit state"; return states[state].str; // MORE - should be using getEnumText, or need to take steps to ensure values remain contiguous and in order. } @@ -14496,11 +14497,22 @@ void executeThorGraph(const char * graphName, IConstWorkUnit &workunit, const IP } } + // NB: check for expected success state (WUStateWait). If any other state, abort. { Owned w = &workunit.lock(); WUState state = w->getState(); - if (WUStateFailed == state) - throw makeStringException(0, "Workunit failed"); + if (WUStateWait != state) // expected state from successful Thor run from above + { + switch (state) + { + case WUStateAborting: + throw new WorkflowException(0, "Workunit abort requested", 0, WorkflowException::ABORT, MSGAUD_user); + case WUStateFailed: + throw makeStringException(0, "Workunit failed"); + default: + throw makeStringExceptionV(0, "Workunit failed. Unexpected state: %s", getWorkunitStateStr(state)); + } + } w->setState(WUStateRunning); } #else From 058d198d1642e0d4274ba0620401e38c415998de Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:11:35 -0400 Subject: [PATCH 08/10] HPCC-32846 ECL Watch v9 fix JS exception on Queries list page fixes an issue with an uncaught JS exception on the Queries list page, when rows rendered in the list did not contain a "Clusters" property, which was resulting in a white blank page Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/src-react/components/Queries.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp/src/src-react/components/Queries.tsx b/esp/src/src-react/components/Queries.tsx index a64847aff70..2a9d05c228d 100644 --- a/esp/src/src-react/components/Queries.tsx +++ b/esp/src/src-react/components/Queries.tsx @@ -134,7 +134,7 @@ export const Queries: React.FunctionComponent = ({ width: 16, sortable: false, formatter: (mixed, row) => { - const mixedStates = row.Clusters.ClusterQueryState[0]?.MixedNodeStates ?? false; + const mixedStates = row?.Clusters?.ClusterQueryState[0]?.MixedNodeStates ?? false; if (mixedStates === true) { return ; } From 9a094c99858be504fd8ccb050d13a29dca93a1ee Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:03:31 -0400 Subject: [PATCH 09/10] HPCC-32848 ECL Watch v9 display exceptions from /WsLogaccess/GetLogAccessInfo fixes an issue where any exceptions from /WsLogaccess/GetLogAccessInfo were not being displayed in the UI Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/src-react/components/Menu.tsx | 2 -- .../src-react/components/WorkunitDetails.tsx | 3 --- esp/src/src/ESPLog.ts | 20 +++++++++++++++---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/esp/src/src-react/components/Menu.tsx b/esp/src/src-react/components/Menu.tsx index 8d9a4f82387..342cad13d63 100644 --- a/esp/src/src-react/components/Menu.tsx +++ b/esp/src/src-react/components/Menu.tsx @@ -298,8 +298,6 @@ export const SubNavigation: React.FunctionComponent = ({ React.useEffect(() => { hasLogAccess().then(response => { setLogsDisabled(!response); - }).catch(() => { - setLogsDisabled(true); }); }, []); const linkStyle = React.useCallback((disabled) => { diff --git a/esp/src/src-react/components/WorkunitDetails.tsx b/esp/src/src-react/components/WorkunitDetails.tsx index f30bbf974ae..ad344dee9f4 100644 --- a/esp/src/src-react/components/WorkunitDetails.tsx +++ b/esp/src/src-react/components/WorkunitDetails.tsx @@ -115,9 +115,6 @@ export const WorkunitDetails: React.FunctionComponent = ({ hasLogAccess().then(response => { setLogsDisabled(!response); return response; - }).catch(err => { - logger.warning(err); - setLogsDisabled(true); }); }, [wuid], [queryParams]); diff --git a/esp/src/src/ESPLog.ts b/esp/src/src/ESPLog.ts index 32a195cff87..5f0c09ed115 100644 --- a/esp/src/src/ESPLog.ts +++ b/esp/src/src/ESPLog.ts @@ -1,4 +1,4 @@ -import { LogaccessService, LogLine, GetLogsExRequest, WsLogaccess } from "@hpcc-js/comms"; +import { LogaccessService, LogLine, GetLogsExRequest, WsLogaccess, Exceptions } from "@hpcc-js/comms"; import { scopedLogger } from "@hpcc-js/util"; import * as Observable from "dojo/store/Observable"; import { Paged } from "./store/Paged"; @@ -8,8 +8,12 @@ const logger = scopedLogger("src/ESPLog.ts"); export const service = new LogaccessService({ baseUrl: "" }); -let g_logAccessInfo: Promise; -export function GetLogAccessInfo(): Promise { +function isExceptionResponse(response: WsLogaccess.GetLogAccessInfoResponse | { Exceptions?: Exceptions }): response is { Exceptions?: Exceptions } { + return (response as { Exceptions?: Exceptions }).Exceptions !== undefined; +} + +let g_logAccessInfo: Promise; +export function GetLogAccessInfo(): Promise { if (!g_logAccessInfo) { g_logAccessInfo = service.GetLogAccessInfo({}); } @@ -41,8 +45,16 @@ export function CreateLogsQueryStore(): LogsQuerySto export function hasLogAccess(): Promise { return GetLogAccessInfo().then(response => { - return response.RemoteLogManagerConnectionString !== null || response.RemoteLogManagerType !== null; + if (isExceptionResponse(response)) { + const err = response.Exceptions.Exception[0].Message; + logger.error(err); + return false; + } else { + response = response as WsLogaccess.GetLogAccessInfoResponse; + return response?.RemoteLogManagerConnectionString !== null || response?.RemoteLogManagerType !== null; + } }).catch(e => { + logger.error(e); return false; }); } From 966b8d765d04bbe8d81a75ed7b54a6b102729ec7 Mon Sep 17 00:00:00 2001 From: Richard Chapman Date: Wed, 4 Sep 2024 09:48:12 +0100 Subject: [PATCH 10/10] HPCC-32549 Roxie internal error on getSummaryStats Code appears to have been lost somewhere since 7.x Signed-off-by: Richard Chapman --- roxie/ccd/ccdquery.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/roxie/ccd/ccdquery.cpp b/roxie/ccd/ccdquery.cpp index 901810b7834..29c34c9fa2d 100644 --- a/roxie/ccd/ccdquery.cpp +++ b/roxie/ccd/ccdquery.cpp @@ -1850,6 +1850,11 @@ class CRoxieServerQueryFactory : public CQueryFactory else return NULL; } + + virtual IPropertyTree *getQueryStats(time_t from, time_t to) override + { + return queryStats->getStats(from, to); + } }; unsigned checkWorkunitVersionConsistency(const IConstWorkUnit *wu)