Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/components/computing-status/use-all-computing-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from '../utils/running-status';

import type { UUID } from 'node:crypto';
import { ComputingType } from '@gridsuite/commons-ui';
import { BuildStatus, ComputingType } from '@gridsuite/commons-ui';
import { fetchSensitivityAnalysisStatus } from '../../services/study/sensitivity-analysis';
import { fetchSecurityAnalysisStatus } from '../../services/study/security-analysis';
import { fetchDynamicSimulationStatus } from '../../services/study/dynamic-simulation';
Expand Down Expand Up @@ -126,7 +126,12 @@ export const stateEstimationResultInvalidations = [NotificationType.STATE_ESTIMA
export const pccMinResultInvalidations = [NotificationType.PCC_MIN_RESULT];

// this hook loads all current computation status into redux then keeps them up to date according to notifications
export const useAllComputingStatus = (studyUuid: UUID, currentNodeUuid: UUID, currentRootNetworkUuid: UUID): void => {
export const useAllComputingStatus = (
studyUuid: UUID,
currentNodeUuid: UUID,
currentRootNetworkUuid: UUID,
currentNodeStatusBuildStatus: BuildStatus
): void => {
Comment on lines +129 to +134

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="$(fd -i 'use-computing-status.ts' src/components/computing-status | head -n1)"
echo "Inspecting: $file"

ast-grep outline "$file" --view expanded
echo
rg -n -C3 'BuildStatus|NOT_BUILT|useNotificationsListener|setComputingStatus|fetch.*Status' "$file"
echo
sed -n '1,260p' "$file"

Repository: gridsuite/gridstudy-app

Length of output: 13338


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="src/components/computing-status/use-all-computing-status.ts"
echo "Inspecting: $file"

ast-grep outline "$file" --view expanded
echo
rg -n -C4 'useComputingStatus|useAllComputingStatusAtOnce|currentNodeStatusBuildStatus|BuildStatus|NOT_BUILT' "$file"
echo
sed -n '1,260p' "$file"

Repository: gridsuite/gridstudy-app

Length of output: 18556


Thread currentNodeStatusBuildStatus into the per-type hooks toouseAllComputingStatusAtOnce(...) is the only place that sees the BuildStatus, but useComputingStatus(...) is still mounted for every computation type and still fetches/listens on its own. If NOT_BUILT should stay IDLE, those hooks can repopulate status after the batch reset.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/computing-status/use-all-computing-status.ts` around lines 129
- 134, The BuildStatus is only handled in useAllComputingStatusAtOnce, while
useComputingStatus still runs independently for each computation type and can
repopulate status after a batch reset. Thread currentNodeStatusBuildStatus
through useAllComputingStatus into the per-type hook path, and update
useComputingStatus to accept and honor that status so NOT_BUILT continues to map
to IDLE instead of being overwritten by its own fetch/listen logic.

const securityAnalysisAvailability = useOptionalServiceStatus(OptionalServicesNames.SecurityAnalysis);
const sensitivityAnalysisAvailability = useOptionalServiceStatus(OptionalServicesNames.SensitivityAnalysis);
const dynamicSimulationAvailability = useOptionalServiceStatus(OptionalServicesNames.DynamicSimulation);
Expand Down Expand Up @@ -294,6 +299,7 @@ export const useAllComputingStatus = (studyUuid: UUID, currentNodeUuid: UUID, cu
studyUuid,
currentNodeUuid,
currentRootNetworkUuid,
currentNodeStatusBuildStatus,
fetchAllComputationStatus,
fetchLoadFlowComputationInfosMap
);
Expand Down
26 changes: 22 additions & 4 deletions src/components/computing-status/use-computing-status-at-once.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { getComputationRunningStatus, RunningStatus } from 'components/utils/run
import type { UUID } from 'node:crypto';
import { RefObject, useCallback, useEffect, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { ComputingType, NotificationsUrlKeys, useNotificationsListener } from '@gridsuite/commons-ui';
import { BuildStatus, ComputingType, NotificationsUrlKeys, useNotificationsListener } from '@gridsuite/commons-ui';
import { setComputingStatus, setComputingStatusParameters, setLastCompletedComputation } from '../../redux/actions';
import { AppDispatch } from '../../redux/store';
import { parseEventData, StudyUpdatedEventData } from '../../types/notification-types';
Expand All @@ -20,6 +20,7 @@ interface UseComputingStatusProps {
studyUuid: UUID,
nodeUuid: UUID,
currentRootNetworkUuid: UUID,
currentNodeBuildStatus: BuildStatus,
computingStatusFetcher: (
studyUuid: UUID,
nodeUuid: UUID,
Expand All @@ -37,11 +38,16 @@ function isWorthUpdate(
nodeUuidRef: RefObject<UUID | null>,
rootNetworkUuidRef: RefObject<UUID | null>,
nodeUuid: UUID,
currentRootNetworkUuid: UUID
currentRootNetworkUuid: UUID,
notificationNode: UUID | undefined
): boolean {
if (rootNetworkUuidRef.current !== currentRootNetworkUuid) {
return true;
}
// if notification is about a node that is not current node, no need to update current node computation status
if (notificationNode && notificationNode !== nodeUuid) {
return false;
}
if (nodeUuidRef.current !== nodeUuid) {
return true;
}
Expand All @@ -67,6 +73,7 @@ const shouldRequestBeCanceled = (
* this hook loads all <computingType> state into redux at once, then updates it according to notifications for all computation
* @param studyUuid current study uuid
* @param nodeUuid current node uuid
* @param currentNodeBuildStatus
* @param allComputingStatusFetcher method fetching all <computingType> state
* @param currentRootNetworkUuid
* @param computingStatusParametersFetcherMap
Expand All @@ -75,6 +82,7 @@ export const useAllComputingStatusAtOnce: UseComputingStatusProps = (
studyUuid,
nodeUuid,
currentRootNetworkUuid,
currentNodeBuildStatus,
allComputingStatusFetcher,
computingStatusParametersFetcherMap
) => {
Expand Down Expand Up @@ -202,18 +210,28 @@ export const useAllComputingStatusAtOnce: UseComputingStatusProps = (
const eventData = parseEventData<StudyUpdatedEventData>(event ?? null);
const headers = eventData?.headers;
const updateType = headers?.updateType;
const notificationNode = headers?.node;
// no need to request the back if node is not built
if (currentNodeBuildStatus === BuildStatus.NOT_BUILT) {
Object.values(ComputingType).forEach((computingType: ComputingType) => {
dispatch(setComputingStatus(computingType, RunningStatus.IDLE));
});
nodeUuidRef.current = nodeUuid;
return;
Comment on lines +214 to +220

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Invalidate outstanding updates before returning for NOT_BUILT.

This branch forces IDLE and exits, but it does not invalidate an updateAll() request that was already in flight for the same node/root. When that response lands, shouldRequestBeCanceled(...) still passes and can repopulate stale statuses, undoing this reset. It also skips the setLastCompletedComputation() reset that updateAll() performs for node changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/computing-status/use-computing-status-at-once.ts` around lines
214 - 220, The NOT_BUILT branch in useComputingStatusAtOnce is only resetting
statuses and nodeUuidRef, but it does not cancel any in-flight updateAll request
or clear its completion marker. Update this branch to also invalidate the
pending request state used by shouldRequestBeCanceled and reset the
last-completed computation tracking the same way updateAll does when the node
changes, so stale responses cannot overwrite the forced IDLE state.

}
const isUpdateForUs = isWorthUpdate(
updateType,
nodeUuidRef,
rootNetworkUuidRef,
nodeUuid,
currentRootNetworkUuid
currentRootNetworkUuid,
notificationNode
);
if (isUpdateForUs) {
updateAll(updateType);
}
},
[currentRootNetworkUuid, nodeUuid, studyUuid, updateAll]
[currentNodeBuildStatus, currentRootNetworkUuid, dispatch, nodeUuid, studyUuid, updateAll]
);

// evaluate at each notification
Expand Down
3 changes: 1 addition & 2 deletions src/components/study-container.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,7 @@ export function StudyContainer() {

const currentNodeRef = useRef();
const currentRootNetworkUuidRef = useRef();

useAllComputingStatus(studyUuid, currentNode?.id, currentRootNetworkUuid);
useAllComputingStatus(studyUuid, currentNode?.id, currentRootNetworkUuid, currentNode?.data.globalBuildStatus);

const { snackError, snackWarning, snackInfo } = useSnackMessage();

Expand Down
Loading