Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/candidate-9.2.x' into candidate-…
Browse files Browse the repository at this point in the history
…9.4.x

Signed-off-by: Jake Smith <jake.smith@lexisnexisrisk.com>
  • Loading branch information
jakesmith committed Nov 23, 2023
2 parents 8757da1 + 4e87310 commit 78756ac
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 47 deletions.
10 changes: 10 additions & 0 deletions esp/src/eclwatch/css/hpcc.css
Original file line number Diff line number Diff line change
Expand Up @@ -1278,19 +1278,29 @@ table.miniSelect span {
}

.ErrorCell {
padding-left: 4px;
background: red;
color: white;
}

.AlertCell {
padding-left: 4px;
background: #febe47;
}

.CostCell {
padding-left: 4px;
background: #fe4747;
color: white;
}

.WarningCell {
padding-left: 4px;
background: yellow;
}

.NormalCell {
padding-left: 4px;
background: rgba(0, 181, 0, 1);
}

Expand Down
48 changes: 41 additions & 7 deletions esp/src/src-react/components/InfoGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import nlsHPCC from "src/nlsHPCC";
import { useWorkunitExceptions } from "../hooks/workunit";
import { FluentGrid, useCopyButtons, useFluentStoreState, FluentColumns } from "./controls/Grid";
import { pivotItemStyle } from "../layouts/pivot";
import { formatCost } from "src/Session";

function extractGraphInfo(msg) {
const regex = /^([a-zA-Z0-9 :]+: )(graph graph(\d+)\[(\d+)\], )(([a-zA-Z]+)\[(\d+)\]: )?(.*)$/gmi;
Expand All @@ -21,6 +22,14 @@ function extractGraphInfo(msg) {
return retVal;
}

interface FilterCounts {
cost: number,
error: number,
warning: number,
info: number,
other: number
}

interface InfoGridProps {
wuid: string;
}
Expand All @@ -29,11 +38,12 @@ export const InfoGrid: React.FunctionComponent<InfoGridProps> = ({
wuid
}) => {

const [costChecked, setCostChecked] = React.useState(true);
const [errorChecked, setErrorChecked] = React.useState(true);
const [warningChecked, setWarningChecked] = React.useState(true);
const [infoChecked, setInfoChecked] = React.useState(true);
const [otherChecked, setOtherChecked] = React.useState(true);
const [filterCounts, setFilterCounts] = React.useState<any>({});
const [filterCounts, setFilterCounts] = React.useState<FilterCounts>({ cost: 0, error: 0, warning: 0, info: 0, other: 0 });
const [exceptions] = useWorkunitExceptions(wuid);
const [data, setData] = React.useState<any[]>([]);
const {
Expand All @@ -44,10 +54,11 @@ export const InfoGrid: React.FunctionComponent<InfoGridProps> = ({
// Command Bar ---
const buttons = React.useMemo((): ICommandBarItemProps[] => [
{ key: "errors", onRender: () => <Checkbox defaultChecked label={`${filterCounts.error || 0} ${nlsHPCC.Errors}`} onChange={(ev, value) => setErrorChecked(value)} styles={{ root: { paddingTop: 8, paddingRight: 8 } }} /> },
{ key: "costs", onRender: () => <Checkbox defaultChecked label={`${filterCounts.cost || 0} ${nlsHPCC.Costs}`} onChange={(ev, value) => setCostChecked(value)} styles={{ root: { paddingTop: 8, paddingRight: 8 } }} /> },
{ key: "warnings", onRender: () => <Checkbox defaultChecked label={`${filterCounts.warning || 0} ${nlsHPCC.Warnings}`} onChange={(ev, value) => setWarningChecked(value)} styles={{ root: { paddingTop: 8, paddingRight: 8 } }} /> },
{ key: "infos", onRender: () => <Checkbox defaultChecked label={`${filterCounts.info || 0} ${nlsHPCC.Infos}`} onChange={(ev, value) => setInfoChecked(value)} styles={{ root: { paddingTop: 8, paddingRight: 8 } }} /> },
{ key: "others", onRender: () => <Checkbox defaultChecked label={`${filterCounts.other || 0} ${nlsHPCC.Others}`} onChange={(ev, value) => setOtherChecked(value)} styles={{ root: { paddingTop: 8, paddingRight: 8 } }} /> }
], [filterCounts.error, filterCounts.info, filterCounts.other, filterCounts.warning]);
], [filterCounts.cost, filterCounts.error, filterCounts.info, filterCounts.other, filterCounts.warning]);

// Grid ---
const columns = React.useMemo((): FluentColumns => {
Expand All @@ -60,13 +71,23 @@ export const InfoGrid: React.FunctionComponent<InfoGridProps> = ({
return "ErrorCell";
case "Alert":
return "AlertCell";
case "Cost":
return "CostCell";
case "Warning":
return "WarningCell";
}
return "";
}
},
Source: { label: nlsHPCC.Source, field: "", width: 144, sortable: false },
Source: {
label: `${nlsHPCC.Source} / ${nlsHPCC.Cost}`, field: "", width: 144, sortable: false,
formatter: (Source, row) => {
if (Source === "Cost Optimizer") {
return formatCost(+row.Priority);
}
return Source;
}
},
Code: { label: nlsHPCC.Code, field: "", width: 45, sortable: false },
Message: {
label: nlsHPCC.Message, field: "",
Expand Down Expand Up @@ -98,14 +119,21 @@ export const InfoGrid: React.FunctionComponent<InfoGridProps> = ({
const copyButtons = useCopyButtons(columns, selection, "errorwarnings");

React.useEffect(() => {
const filterCounts = {
const filterCounts: FilterCounts = {
cost: 0,
error: 0,
warning: 0,
info: 0,
other: 0
};
const filteredExceptions = exceptions.map((row, idx) => {
if (row.Source === "Cost Optimizer") {
row.Severity = "Cost";
}
switch (row.Severity) {
case "Cost":
filterCounts.cost++;
break;
case "Error":
filterCounts.error++;
break;
Expand All @@ -124,13 +152,15 @@ export const InfoGrid: React.FunctionComponent<InfoGridProps> = ({
...row
};
}).filter(row => {
if (!errorChecked && row.Severity === "Error") {
if (!costChecked && row.Severity === "Cost") {
return false;
} else if (!errorChecked && row.Severity === "Error") {
return false;
} else if (!warningChecked && row.Severity === "Warning") {
return false;
} else if (!infoChecked && row.Severity === "Info") {
return false;
} else if (!otherChecked && row.Severity !== "Error" && row.Severity !== "Warning" && row.Severity !== "Info") {
} else if (!otherChecked && row.Severity !== "Cost" && row.Severity !== "Error" && row.Severity !== "Warning" && row.Severity !== "Info") {
return false;
}
return true;
Expand All @@ -145,6 +175,10 @@ export const InfoGrid: React.FunctionComponent<InfoGridProps> = ({
return -1;
} else if (r.Severity === "Alert") {
return 1;
} else if (l.Severity === "Cost") {
return -1;
} else if (r.Severity === "Cost") {
return 1;
} else if (l.Severity === "Warning") {
return -1;
} else if (r.Severity === "Warning") {
Expand All @@ -154,7 +188,7 @@ export const InfoGrid: React.FunctionComponent<InfoGridProps> = ({
});
setData(filteredExceptions);
setFilterCounts(filterCounts);
}, [errorChecked, exceptions, infoChecked, otherChecked, warningChecked]);
}, [costChecked, errorChecked, exceptions, infoChecked, otherChecked, warningChecked]);

React.useEffect(() => {
if (data.length) {
Expand Down
23 changes: 21 additions & 2 deletions esp/src/src-react/components/WorkunitSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import nlsHPCC from "src/nlsHPCC";
import { WUStatus } from "src/react/index";
import { formatCost } from "src/Session";
import { useConfirm } from "../hooks/confirm";
import { useWorkunit } from "../hooks/workunit";
import { useWorkunit, useWorkunitExceptions } from "../hooks/workunit";
import { ReflexContainer, ReflexElement, ReflexSplitter } from "../layouts/react-reflex";
import { pushUrl, replaceUrl } from "../util/history";
import { ShortVerticalDivider } from "./Common";
Expand All @@ -15,6 +15,7 @@ import { SlaveLogs } from "./forms/SlaveLogs";
import { ZAPDialog } from "./forms/ZAPDialog";
import { InfoGrid } from "./InfoGrid";
import { WorkunitPersona } from "./controls/StateIcon";
import { isNumeric } from "src/Utility";

const logger = scopedLogger("../components/WorkunitDetails.tsx");

Expand All @@ -27,6 +28,7 @@ export const WorkunitSummary: React.FunctionComponent<WorkunitSummaryProps> = ({
}) => {

const [workunit, , , , refresh] = useWorkunit(wuid, true);
const [exceptions, , refreshSavings] = useWorkunitExceptions(wuid);
const [jobname, setJobname] = React.useState("");
const [description, setDescription] = React.useState("");
const [_protected, setProtected] = React.useState(false);
Expand Down Expand Up @@ -72,6 +74,7 @@ export const WorkunitSummary: React.FunctionComponent<WorkunitSummaryProps> = ({
key: "refresh", text: nlsHPCC.Refresh, iconProps: { iconName: "Refresh" },
onClick: () => {
refresh(true);
refreshSavings();
}
},
{
Expand Down Expand Up @@ -160,12 +163,27 @@ export const WorkunitSummary: React.FunctionComponent<WorkunitSummaryProps> = ({
key: "slaveLogs", text: nlsHPCC.SlaveLogs, disabled: !workunit?.ThorLogList,
onClick: () => setShowThorSlaveLogs(true)
},
], [_protected, canDelete, canDeschedule, canReschedule, canSave, description, jobname, refresh, setShowDeleteConfirm, workunit, wuid]);
], [_protected, canDelete, canDeschedule, canReschedule, canSave, description, jobname, refresh, refreshSavings, setShowDeleteConfirm, workunit, wuid]);

const serviceNames = React.useMemo(() => {
return workunit?.ServiceNames?.Item?.join("\n") || "";
}, [workunit?.ServiceNames?.Item]);

const totalCosts = React.useMemo(() => {
return (workunit?.CompileCost ?? 0) +
(workunit?.ExecuteCost ?? 0) +
(workunit?.FileAccessCost ?? 0);
}, [workunit?.CompileCost, workunit?.ExecuteCost, workunit?.FileAccessCost]);

const potentialSavings = React.useMemo(() => {
return exceptions.reduce((prev, cur) => {
if (isNumeric(cur.Priority)) {
prev += cur.Priority;
}
return prev;
}, 0) || 0;
}, [exceptions]);

return <>
<ReflexContainer orientation="horizontal">
<ReflexElement>
Expand Down Expand Up @@ -196,6 +214,7 @@ export const WorkunitSummary: React.FunctionComponent<WorkunitSummaryProps> = ({
"owner": { label: nlsHPCC.Owner, type: "string", value: workunit?.Owner, readonly: true },
"jobname": { label: nlsHPCC.JobName, type: "string", value: jobname },
"description": { label: nlsHPCC.Description, type: "string", value: description },
"potentialSavings": { label: nlsHPCC.PotentialSavings, type: "string", value: `${formatCost(potentialSavings)} (${Math.round((potentialSavings / totalCosts) * 10000) / 100}%)`, 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 },
Expand Down
2 changes: 1 addition & 1 deletion esp/src/src-react/hooks/workunit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function useWorkunit(wuid: string, full: boolean = false): [Workunit, WUS

React.useEffect(() => {
if (wuid === undefined || wuid === null) {
setRetVal({ workunit: undefined, state: WUStateID.NotFound, lastUpdate: Date.now(), isComplete: undefined, refresh: () => Promise.resolve(undefined) });
setRetVal({ workunit: undefined, state: WUStateID.NotFound, lastUpdate: Date.now(), isComplete: undefined, refresh: (full?: boolean) => Promise.resolve(undefined) });
return;
}
const wu = Workunit.attach({ baseUrl: "" }, wuid);
Expand Down
4 changes: 4 additions & 0 deletions esp/src/src/Utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,10 @@ export function formatNums(obj) {
return obj;
}

export function isNumeric(n: string | undefined | null | number) {
return !isNaN(parseFloat(n as string)) && isFinite(n as number);
}

export function formatLine(labelTpl, obj): string {
let retVal = "";
let lpos = labelTpl.indexOf("%");
Expand Down
2 changes: 2 additions & 0 deletions esp/src/src/nls/hpcc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export = {
CopySelectionToClipboard: "Copy selection to clipboard",
Copied: "Copied!",
Cost: "Cost",
Costs: "Cost(s)",
Count: "Count",
CountFailed: "Count Failed",
CountTotal: "Count Total",
Expand Down Expand Up @@ -690,6 +691,7 @@ export = {
Pods: "Pods",
PodsAccessError: "Cannot retrieve list of pods",
Port: "Port",
PotentialSavings: "Potential Savings",
Prefix: "Prefix",
PrefixPlaceholder: "filename{:length}, filesize{:[B|L][1-8]}",
Preflight: "Preflight",
Expand Down
9 changes: 7 additions & 2 deletions system/jlib/jcontainerized.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ bool checkExitCodes(StringBuffer &output, const char *podStatuses)
return false;
}

void waitJob(const char *componentName, const char *resourceType, const char *job, unsigned pendingTimeoutSecs, KeepJobs keepJob)
void waitJob(const char *componentName, const char *resourceType, const char *job, unsigned pendingTimeoutSecs, unsigned totalWaitTimeSecs, KeepJobs keepJob)
{
VStringBuffer jobName("%s-%s-%s", componentName, resourceType, job);
jobName.toLowerCase();
Expand Down Expand Up @@ -160,6 +160,11 @@ void waitJob(const char *componentName, const char *resourceType, const char *jo
runKubectlCommand(componentName, getReason, nullptr, &output.clear());
throw makeStringExceptionV(0, "Failed to run %s - pod not scheduled after %u seconds: %s ", jobName.str(), pendingTimeoutSecs, output.str());
}
if (0 == totalWaitTimeSecs)
break;
if ((INFINITE != totalWaitTimeSecs) && msTick()-start > totalWaitTimeSecs*1000)
throw makeStringExceptionV(0, "Wait job timeout (%u secs) expired, whilst running: %s", totalWaitTimeSecs, jobName.str());

MilliSleep(delay);
if (delay < 10000)
delay = delay * 2;
Expand Down Expand Up @@ -236,7 +241,7 @@ void runJob(const char *componentName, const char *wuid, const char *jobName, co
Owned<IException> exception;
try
{
waitJob(componentName, "job", jobName, pendingTimeoutSecs, keepJob);
waitJob(componentName, "job", jobName, pendingTimeoutSecs, INFINITE, keepJob);
}
catch (IException *e)
{
Expand Down
2 changes: 1 addition & 1 deletion system/jlib/jcontainerized.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jlib_decl KeepJobs translateKeepJobs(const char *keepJobs);

jlib_decl bool isActiveService(const char *serviceName);
jlib_decl void deleteResource(const char *componentName, const char *job, const char *resource);
jlib_decl void waitJob(const char *componentName, const char *job, unsigned pendingTimeoutSecs, KeepJobs keepJob);
jlib_decl void waitJob(const char *componentName, const char *resourceType, const char *job, unsigned pendingTimeoutSecs, unsigned totalWaitTimeSecs, KeepJobs keepJob);
jlib_decl bool applyYaml(const char *componentName, const char *wuid, const char *job, const char *resourceType, const std::list<std::pair<std::string, std::string>> &extraParams, bool optional, bool autoCleanup);
jlib_decl void runJob(const char *componentName, const char *wuid, const char *job, const std::list<std::pair<std::string, std::string>> &extraParams={});

Expand Down
Loading

0 comments on commit 78756ac

Please sign in to comment.