Skip to content

bugfix/node result-view actively updates with latest snapshot#216

Open
kleinwave wants to merge 13 commits into
mainfrom
bugfix/node-result-view-updates-with-latest-snapshot
Open

bugfix/node result-view actively updates with latest snapshot#216
kleinwave wants to merge 13 commits into
mainfrom
bugfix/node-result-view-updates-with-latest-snapshot

Conversation

@kleinwave

Copy link
Copy Markdown
Collaborator

@kleinwave kleinwave self-assigned this Jul 14, 2025
@kleinwave kleinwave requested review from nulinspiratie and removed request for nulinspiratie July 14, 2025 12:43
@kleinwave kleinwave requested a review from Copilot July 14, 2025 13:03

This comment was marked as outdated.

@kleinwave kleinwave requested a review from Copilot July 14, 2025 13:23

This comment was marked as outdated.

export const MeasurementHistory: React.FC<IMeasurementHistoryListProps> = ({ title = "Execution history" }) => {
const { allMeasurements, trackLatest, setTrackLatest } = useGraphStatusContext();
const { trackLatestSidePanel, fetchOneSnapshot, setLatestSnapshotId, setResult, setDiffData } = useSnapshotsContext();
const { fetchOneSnapshot, setLatestSnapshotId } = useSnapshotsContext();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trackLatestSidePanel was dead code
setResult and setDiffData were removed because now we rely on fetchOneSnapshot to manage state resets internally

if (allMeasurements) {
const element = allMeasurements[0];
// if (element) {
if (trackLatest && allMeasurements && allMeasurements.length > 0) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simplifying code readability combining if statements

Comment on lines +31 to +35
setLatestId(current.id);
setLatestName(current.metadata?.name);
setSelectedItemName(current.metadata?.name);
setSelectedNodeNameInWorkflow(current.metadata?.name);
setLatestSnapshotId(current.id);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines make sure that the selected node in the UI is synced with the latest measurement

Comment on lines +36 to +40
if (current.id !== undefined) {
if (prev && prev.id !== undefined && current.id !== prev.id) {
fetchOneSnapshot(current.id, prev.id, true, true);
} else {
setResult({});
setDiffData({});
fetchOneSnapshot(current.id, undefined, true, true);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there’s a previous snapshot and it’s different from the current, perform a diff fetch
else just fetch the current snapshot only

Comment on lines +28 to +29
fetchingSnapshotId: number | undefined;
setFetchingSnapshotId: Dispatch<SetStateAction<number | undefined>>;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't have this, fetchOneSnapshot could get called multiple times for the same snapshot in rapid succession, and can cause duplicate API calls or race conditions

// -----------------------------------------------------------

const fetchOneSnapshot = (snapshotId: number, snapshotId2?: number, updateResult = true, fetchUpdate = false) => {
if (fetchingSnapshotId === snapshotId) return;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prevents duplicate in-flight requests for the same snapshot

Comment on lines +198 to +199
let id2 = snapshotId2 ? snapshotId2.toString() : snapshotId - 1 >= 0 ? (snapshotId - 1).toString() : "0";
if (id1 === id2) id2 = "0";

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prevents self-comparison bugs in the diff-fetch API

@kleinwave kleinwave requested a review from nulinspiratie July 14, 2025 14:11
@nulinspiratie nulinspiratie requested a review from Copilot July 16, 2025 07:05

This comment was marked as outdated.

@kleinwave kleinwave requested a review from Copilot July 16, 2025 09:16

This comment was marked as outdated.

@kleinwave

kleinwave commented Jul 16, 2025

Copy link
Copy Markdown
Collaborator Author

In addition to co-pilot I asked chatgpt to varrify the correctness of my code and do an analysis to make sure it doesn't disrupt anything else in SnapshotsContext
Screenshot 2025-07-16 at 12 24 31 PM

@kleinwave kleinwave force-pushed the bugfix/node-result-view-updates-with-latest-snapshot branch from 843b955 to bddea46 Compare July 16, 2025 13:14
Comment on lines -37 to -38
if (element.id) {
setLatestSnapshotId(element.id);

@kleinwave kleinwave Jul 17, 2025

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current.id is is guaranteed to exist at this point in the code
So in the diff you dont need the conditional anymore

@kleinwave kleinwave requested a review from Copilot July 21, 2025 08:54

This comment was marked as outdated.

@kleinwave kleinwave requested a review from Copilot July 21, 2025 09:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a bugfix to ensure that the node result view actively updates with the latest snapshot during graph execution. The changes add state management for tracking graph execution status and prevent snapshot fetches from interfering with active node results.

Key changes:

  • Added graph execution state tracking with graphIsRunning and related state variables
  • Implemented logic to prevent snapshot context resets during active graph execution
  • Enhanced the measurement history component to properly handle live updates during execution

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
frontend/src/modules/Snapshots/context/SnapshotsContext.tsx Adds graph execution state management, prevents snapshot fetches during execution, and improves fetch deduplication logic
frontend/src/modules/GraphLibrary/components/GraphStatus/components/MeasurementHistory/MeasurementHistory.tsx Updates measurement history to respect graph execution state and freeze mechanisms for consistent node result display

console.log(`Max snapshot ID - previous=${odlMaxId}, latest=${newMaxId}`);
if (newMaxId !== odlMaxId! && allSnapshots.length !== 0) {
const oldMaxId = allSnapshots[0]?.id;
// console.log(`Max snapshot ID - previous=${odlMaxId}, latest=${newMaxId}`);

Copilot AI Jul 21, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable name 'oldMaxId' appears to be a typo fix for 'odlMaxId' in the commented line above, but the variable naming is inconsistent with the comment on line 186 which still references 'odlMaxId'.

Suggested change
// console.log(`Max snapshot ID - previous=${odlMaxId}, latest=${newMaxId}`);
// console.log(`Max snapshot ID - previous=${oldMaxId}, latest=${newMaxId}`);

Copilot uses AI. Check for mistakes.
console.log("Graph execution likely completed. Stopping tracking after debounce.");
setGraphIsRunning(false);
setFreezeLatestSnapshot(true); // Prevent snapshot context reset
}, 3000);

Copilot AI Jul 21, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded 3000ms timeout (line 224) should be extracted as a named constant to improve maintainability and make the debounce timing more explicit.

Suggested change
}, 3000);
}, DEBOUNCE_TIMEOUT_MS);

Copilot uses AI. Check for mistakes.
}
}
}, [trackLatest, allMeasurements, latestId, latestName]);
}, [trackLatest, allMeasurements, graphIsRunning, latestId, latestName, freezeLatestSnapshot]);

Copilot AI Jul 21, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The useEffect dependency array is missing trackLatestSidePanel which is used inside the effect (lines 41, 47). This could cause stale closures and incorrect behavior when trackLatestSidePanel changes.

Suggested change
}, [trackLatest, allMeasurements, graphIsRunning, latestId, latestName, freezeLatestSnapshot]);
}, [trackLatest, allMeasurements, graphIsRunning, latestId, latestName, freezeLatestSnapshot, trackLatestSidePanel]);

Copilot uses AI. Check for mistakes.
}
}
}, [trackLatest, allMeasurements, latestId, latestName]);
}, [trackLatest, allMeasurements, graphIsRunning, latestId, latestName, freezeLatestSnapshot]);

Copilot AI Jul 21, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The useEffect dependency array is missing several functions used within the effect: setSelectedItemName, setSelectedNodeNameInWorkflow, setLatestSnapshotId, and fetchOneSnapshot. These should be included to ensure the effect has access to the latest function references.

Suggested change
}, [trackLatest, allMeasurements, graphIsRunning, latestId, latestName, freezeLatestSnapshot]);
}, [trackLatest, allMeasurements, graphIsRunning, latestId, latestName, freezeLatestSnapshot, setSelectedItemName, setSelectedNodeNameInWorkflow, setLatestSnapshotId, fetchOneSnapshot]);

Copilot uses AI. Check for mistakes.
fetchOneSnapshot(current.id); // Final snapshot without compare
}
} else {
console.log(`Skipping fetch, already displaying snapshot id ${current.id}`);

Copilot AI Jul 21, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple console.log statements throughout this component should be removed or replaced with a proper logging mechanism for production code.

Copilot uses AI. Check for mistakes.
@kleinwave

Copy link
Copy Markdown
Collaborator Author

When a calibration graph runs, snapshots intermittently fail to be fetched and displayed in the results section, because either the same snapshot was requested multiple times, creating race conditions. And jsonData would be cleared or even overwritten because of lack of fetch coordination between them.

fix:

first check in fetchOneSnapshot, do these conditionals:

// avoids duplicate fetching
if (fetchingSnapshotId === snapshotId) return;
// needs to update when nessesary (whenever snapshot is selected AND jsondata is set)
if (selectedSnapshotId === snapshotId && jsonData) return;

The bug with snapshot retreival was that jsonData was being fetched before it was even set
And the solution is that it will now only fetch the snapshot in the first place if it is set (whenever it’s selected)

// const index2 = index - 1 >= 0 ? index - 1 : 0;
// const index2 = selectedSnapshotId ? (selectedSnapshotId - 1 >= 0 ? selectedSnapshotId - 1 : 0) : 0;
if (fetchingSnapshotId === snapshotId) return;
if (selectedSnapshotId === snapshotId && jsonData) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants