Skip to content

Add nodeActivity#1016

Open
ayolab wants to merge 2 commits into
mainfrom
ayolab/add-node-activity
Open

Add nodeActivity#1016
ayolab wants to merge 2 commits into
mainfrom
ayolab/add-node-activity

Conversation

@ayolab

@ayolab ayolab commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Signed-off-by: Ayoub LABIDI <ayoub.labidi@protonmail.com>
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR replaces boolean blocked-node tracking with persisted NodeActivityStatus values, guarded activity acquisition and release, idle-tree validation, activity notifications, updated study/rebuild/controller/consumer flows, and a Liquibase migration.

Changes

Node activity state and persistence

Layer / File(s) Summary
Activity contracts, DTOs, entities, and migration
src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/*, src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/*, src/main/java/org/gridsuite/study/server/dto/*, src/main/resources/db/changelog/*
Adds activity enums and DTO fields, replaces blockedNode persistence with nodeActivityStatus, removes obsolete build/blocking fields, and updates the database schema.
Repository and notification support
src/main/java/org/gridsuite/study/server/repository/rootnetwork/*, src/main/java/org/gridsuite/study/server/notification/*, src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java
Adds idle checks, bulk activity transitions, activity notifications, and service methods for setting and clearing activity.

Guarded service workflows

Layer / File(s) Summary
Activity guard and tree resolution
src/main/java/org/gridsuite/study/server/service/NodeActivityGuardService.java, src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java
Adds scoped synchronous/asynchronous activity guards, updates branch UUID calculation, and removes block/unblock service APIs.
Study and rebuild operations
src/main/java/org/gridsuite/study/server/service/StudyService.java, src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java
Uses activity states for root-network updates, computations, builds, unbuilds, modification insertion, and rebuild operations with guarded cleanup.

Entry points and asynchronous cleanup

Layer / File(s) Summary
Controller endpoint integration
src/main/java/org/gridsuite/study/server/controller/StudyController.java
Replaces blocked-node checks with tree-idle assertions or guarded activity execution across node, modification, build, and computation endpoints.
Consumer and supervision cleanup
src/main/java/org/gridsuite/study/server/service/ConsumerService.java, src/main/java/org/gridsuite/study/server/service/SupervisionService.java
Clears activity and resets build state in build, import, computation-result, failure, and stopped workflows, while removing obsolete unblock cleanup.

Suggested reviewers: flomillot, etiennehomer, abdelhedhili

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No author description was provided, so there is no meaningful description to evaluate. Add a brief description of the node activity tracking and guard changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and matches the main change: adding node activity tracking and guards.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch ayolab/add-node-activity

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.44.1)
src/main/java/org/gridsuite/study/server/controller/StudyController.java

ast-grep timed out on this file

src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NodeActivityCheckScope.java

ast-grep retry budget exhausted before isolating this batch

src/main/java/org/gridsuite/study/server/service/ConsumerService.java

ast-grep retry budget exhausted before isolating this batch

  • 4 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ayolab ayolab added the WIP label Jul 9, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/main/java/org/gridsuite/study/server/service/StudyService.java (1)

1770-1782: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

getBuildInfos/setModificationReports run after BUILDING is set but outside the try.

If getBuildInfos or setModificationReports throws, clearNodeActivity is not invoked. DB state reverts via the caller's transaction, but the BUILDING activity-status notification emitted by setNodeActivity is not rolled back, so clients can be left seeing a stuck BUILDING state. Consider extending the try to cover these steps.

♻️ Suggested scope widening
         setNodeActivity(studyUuid, rootNetworkUuid, nodeUuid, NodeActivityStatus.BUILDING);
-        BuildInfos buildInfos = networkModificationTreeService.getBuildInfos(nodeUuid, rootNetworkUuid);
-
-        // Store all reports (inherited + new) for this node
-        networkModificationTreeService.setModificationReports(nodeUuid, rootNetworkUuid, buildInfos.getAllReportsAsMap());
         try {
+            BuildInfos buildInfos = networkModificationTreeService.getBuildInfos(nodeUuid, rootNetworkUuid);
+            // Store all reports (inherited + new) for this node
+            networkModificationTreeService.setModificationReports(nodeUuid, rootNetworkUuid, buildInfos.getAllReportsAsMap());
             networkModificationService.buildNode(nodeUuid, rootNetworkUuid, buildInfos, workflowInfos);
         } catch (Exception e) {
             clearNodeActivity(studyUuid, rootNetworkUuid, nodeUuid);
             throw e;
         }
🤖 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/main/java/org/gridsuite/study/server/service/StudyService.java` around
lines 1770 - 1782, The node activity can get stuck in BUILDING because
getBuildInfos and setModificationReports run after setNodeActivity but outside
the guarded failure path. Move the build-info retrieval and modification-report
update into the same try/catch used around networkModificationService.buildNode
in StudyService so any exception triggers clearNodeActivity. Keep the existing
cleanup logic in the catch and make sure the BUILDING status is only emitted
once the whole build preparation and execution flow is safely covered.
src/main/java/org/gridsuite/study/server/dto/InvalidateNodeTreeParameters.java (1)

21-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Declare these shared presets as final.

These are public shared constant instances but are only static, so they can be accidentally reassigned by any caller, silently corrupting invalidation behavior everywhere. Mark them final.

♻️ Proposed change
-    public static InvalidateNodeTreeParameters ALL = new InvalidateNodeTreeParameters(InvalidationMode.ALL, ComputationsInvalidationMode.ALL);
+    public static final InvalidateNodeTreeParameters ALL = new InvalidateNodeTreeParameters(InvalidationMode.ALL, ComputationsInvalidationMode.ALL);
     `@SuppressWarnings`("checkstyle:AbbreviationAsWordInName")
-    public static InvalidateNodeTreeParameters ONLY_CHILDREN = new InvalidateNodeTreeParameters(InvalidationMode.ONLY_CHILDREN, ComputationsInvalidationMode.ALL);
+    public static final InvalidateNodeTreeParameters ONLY_CHILDREN = new InvalidateNodeTreeParameters(InvalidationMode.ONLY_CHILDREN, ComputationsInvalidationMode.ALL);
     `@SuppressWarnings`("checkstyle:AbbreviationAsWordInName")
-    public static InvalidateNodeTreeParameters ONLY_CHILDREN_BUILD_STATUS = new InvalidateNodeTreeParameters(InvalidationMode.ONLY_CHILDREN_BUILD_STATUS, ComputationsInvalidationMode.ALL);
+    public static final InvalidateNodeTreeParameters ONLY_CHILDREN_BUILD_STATUS = new InvalidateNodeTreeParameters(InvalidationMode.ONLY_CHILDREN_BUILD_STATUS, ComputationsInvalidationMode.ALL);
🤖 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/main/java/org/gridsuite/study/server/dto/InvalidateNodeTreeParameters.java`
around lines 21 - 25, The shared preset instances in
InvalidateNodeTreeParameters are mutable static fields, so they can be
reassigned by callers; make ALL, ONLY_CHILDREN, and ONLY_CHILDREN_BUILD_STATUS
final to treat them as true constants. Update the field declarations in
InvalidateNodeTreeParameters so these public presets cannot be reassigned,
keeping the existing initialization with InvalidationMode and
ComputationsInvalidationMode unchanged.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@src/main/java/org/gridsuite/study/server/service/StudyService.java`:
- Around line 3244-3246: The modification notification flow in StudyService is
unbalanced because setNodeActivity(...) can throw after
emitStartModificationEquipmentNotification() but before the try/finally block
starts, leaving the UI stuck in MODIFICATIONS_UPDATING_IN_PROGRESS. Reorder the
logic in the same method so the UPDATING state is set before emitting the start
notification, then keep the existing try/finally cleanup with
emitEndModificationEquipmentNotification() and clearNodeActivity() to guarantee
the start/end pair always matches.

---

Nitpick comments:
In
`@src/main/java/org/gridsuite/study/server/dto/InvalidateNodeTreeParameters.java`:
- Around line 21-25: The shared preset instances in InvalidateNodeTreeParameters
are mutable static fields, so they can be reassigned by callers; make ALL,
ONLY_CHILDREN, and ONLY_CHILDREN_BUILD_STATUS final to treat them as true
constants. Update the field declarations in InvalidateNodeTreeParameters so
these public presets cannot be reassigned, keeping the existing initialization
with InvalidationMode and ComputationsInvalidationMode unchanged.

In `@src/main/java/org/gridsuite/study/server/service/StudyService.java`:
- Around line 1770-1782: The node activity can get stuck in BUILDING because
getBuildInfos and setModificationReports run after setNodeActivity but outside
the guarded failure path. Move the build-info retrieval and modification-report
update into the same try/catch used around networkModificationService.buildNode
in StudyService so any exception triggers clearNodeActivity. Keep the existing
cleanup logic in the catch and make sure the BUILDING status is only emitted
once the whole build preparation and execution flow is safely covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e65c8fcc-dcc3-45b9-b0e4-0dbf2f83a195

📥 Commits

Reviewing files that changed from the base of the PR and between a76a79c and 525254e.

📒 Files selected for processing (18)
  • src/main/java/org/gridsuite/study/server/controller/StudyController.java
  • src/main/java/org/gridsuite/study/server/dto/InvalidateNodeTreeParameters.java
  • src/main/java/org/gridsuite/study/server/dto/RootNetworkNodeInfo.java
  • src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/BuildStatus.java
  • src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NetworkModificationNode.java
  • src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NodeActivityStatus.java
  • src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NodeBuildStatus.java
  • src/main/java/org/gridsuite/study/server/networkmodificationtree/entities/RootNetworkNodeInfoEntity.java
  • src/main/java/org/gridsuite/study/server/notification/NotificationService.java
  • src/main/java/org/gridsuite/study/server/repository/rootnetwork/RootNetworkNodeInfoRepository.java
  • src/main/java/org/gridsuite/study/server/service/ConsumerService.java
  • src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java
  • src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java
  • src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
  • src/main/java/org/gridsuite/study/server/service/SupervisionService.java
  • src/main/resources/db/changelog/changesets/changelog_20260703T120000Z.xml
  • src/main/resources/db/changelog/db.changelog-master.yaml
💤 Files with no reviewable changes (2)
  • src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NodeBuildStatus.java
  • src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/BuildStatus.java

Comment thread src/main/java/org/gridsuite/study/server/service/StudyService.java
Signed-off-by: Ayoub LABIDI <ayoub.labidi@protonmail.com>

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/java/org/gridsuite/study/server/controller/StudyController.java (1)

1706-1715: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

TOCTOU between the build-status check and the guarded unbuild.

getNodeBuildStatus(...).isBuilt() is read outside the activity guard, and the guard is only acquired if that read was true. A concurrent build/unbuild between the check and the guard acquisition can make this decision stale — either skipping an unbuild that should now happen, or acquiring the guard for a node that's already been unbuilt.

🐛 Proposed fix: move the check inside the guarded action
-        if (networkModificationTreeService.getNodeBuildStatus(nodeUuid, rootNetworkUuid).isBuilt()) {
-            nodeActivityGuardService.runGuarded(studyUuid, List.of(rootNetworkUuid), List.of(nodeUuid), NodeActivityCheckScope.SELF, NodeActivityStatus.UPDATING,
-                () -> studyService.unbuildStudyNode(studyUuid, nodeUuid, rootNetworkUuid, userId));
-        }
+        nodeActivityGuardService.runGuarded(studyUuid, List.of(rootNetworkUuid), List.of(nodeUuid), NodeActivityCheckScope.SELF, NodeActivityStatus.UPDATING,
+            () -> {
+                if (networkModificationTreeService.getNodeBuildStatus(nodeUuid, rootNetworkUuid).isBuilt()) {
+                    studyService.unbuildStudyNode(studyUuid, nodeUuid, rootNetworkUuid, userId);
+                }
+                return null;
+            });
🤖 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/main/java/org/gridsuite/study/server/controller/StudyController.java`
around lines 1706 - 1715, Move the getNodeBuildStatus(nodeUuid,
rootNetworkUuid).isBuilt() check into the action passed to
nodeActivityGuardService.runGuarded in unbuildNode, and invoke unbuildStudyNode
only when the status is built. Always acquire the guard before evaluating the
status, preserving the existing response behavior.
src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java (1)

186-203: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep UPDATING held through the rebuild trigger The runGuarded scope ends before the buildNode loop starts, so another request can slip in after UPDATING is cleared but before the rebuild call acquires its own BUILDING activity. Move the loop inside the guarded action or wrap it in a second guard.

🤖 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/main/java/org/gridsuite/study/server/service/RebuildNodeService.java`
around lines 186 - 203, Keep the node rebuild trigger within the activity guard
in the method containing runGuarded: move the rootNetworkUuidsByNodeBuilt
buildNode loop into the action executed by nodeActivityGuardService.runGuarded,
or apply a second guard covering that loop. Ensure NodeActivityStatus.UPDATING
remains held until all studyService.buildNode calls have been initiated.
🤖 Prompt for all review comments with 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.

Inline comments:
In
`@src/main/java/org/gridsuite/study/server/service/NodeActivityGuardService.java`:
- Around line 40-56: Update acquireActivity to catch the broader unchecked
failures that can arise from setNodeActivity, while preserving the original
exception for propagation. During rollback over acquired root networks, handle
clearNodeActivity failures without replacing the original error, such as by
suppressing them on the caught exception.

---

Outside diff comments:
In `@src/main/java/org/gridsuite/study/server/controller/StudyController.java`:
- Around line 1706-1715: Move the getNodeBuildStatus(nodeUuid,
rootNetworkUuid).isBuilt() check into the action passed to
nodeActivityGuardService.runGuarded in unbuildNode, and invoke unbuildStudyNode
only when the status is built. Always acquire the guard before evaluating the
status, preserving the existing response behavior.

In `@src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java`:
- Around line 186-203: Keep the node rebuild trigger within the activity guard
in the method containing runGuarded: move the rootNetworkUuidsByNodeBuilt
buildNode loop into the action executed by nodeActivityGuardService.runGuarded,
or apply a second guard covering that loop. Ensure NodeActivityStatus.UPDATING
remains held until all studyService.buildNode calls have been initiated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 14f15bed-eda9-4c90-b28b-5a30a79693a4

📥 Commits

Reviewing files that changed from the base of the PR and between 525254e and b2fcdf6.

📒 Files selected for processing (7)
  • src/main/java/org/gridsuite/study/server/controller/StudyController.java
  • src/main/java/org/gridsuite/study/server/networkmodificationtree/dto/NodeActivityCheckScope.java
  • src/main/java/org/gridsuite/study/server/service/ConsumerService.java
  • src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java
  • src/main/java/org/gridsuite/study/server/service/NodeActivityGuardService.java
  • src/main/java/org/gridsuite/study/server/service/RebuildNodeService.java
  • src/main/java/org/gridsuite/study/server/service/StudyService.java
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java
  • src/main/java/org/gridsuite/study/server/service/StudyService.java

Comment on lines +40 to +56
public List<UUID> acquireActivity(UUID studyUuid, List<UUID> rootNetworkUuids, List<UUID> nodeUuids, NodeActivityCheckScope checkScope, NodeActivityStatus activity) {
if (nodeUuids.isEmpty()) {
return List.of();
}
List<UUID> checkSetUuids = resolveCheckSet(nodeUuids, checkScope);
List<UUID> acquired = new ArrayList<>();
try {
for (UUID rootNetworkUuid : rootNetworkUuids) {
rootNetworkNodeInfoService.setNodeActivity(studyUuid, rootNetworkUuid, nodeUuids, checkSetUuids, activity);
acquired.add(rootNetworkUuid);
}
return acquired;
} catch (StudyException e) {
acquired.forEach(rootNetworkUuid -> rootNetworkNodeInfoService.clearNodeActivity(studyUuid, rootNetworkUuid, nodeUuids));
throw e;
}
}

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Inspect setNodeActivity implementation to verify exception types.

# First map the file structure
ast-grep outline src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java --match 'setNodeActivity' --view expanded

# Then read the method body
rg -n -A 30 'void setNodeActivity' src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java

Repository: gridsuite/study-server

Length of output: 2261


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the service class around the activity methods and the repository method they call.
sed -n '1,260p' src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java | nl -ba | sed -n '470,560p'

echo
echo "---- repository ----"
rg -n -A 20 -B 10 'setNodeActivity|clearNodeActivity' src/main/java/org/gridsuite/study/server/repository/RootNetworkNodeInfoRepository.java

echo
echo "---- any exception handling around acquireActivity callers ----"
rg -n -A 8 -B 8 'acquireActivity\(' src/main/java

Repository: gridsuite/study-server

Length of output: 200


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== RootNetworkNodeInfoService activity methods =="
sed -n '495,520p' src/main/java/org/gridsuite/study/server/service/RootNetworkNodeInfoService.java | cat -n

echo
echo "== RootNetworkNodeInfoRepository methods =="
rg -n -A 20 -B 8 'setNodeActivity|clearNodeActivity' src/main/java/org/gridsuite/study/server/repository/RootNetworkNodeInfoRepository.java

echo
echo "== acquireActivity callers =="
rg -n -A 8 -B 8 'acquireActivity\(' src/main/java

Repository: gridsuite/study-server

Length of output: 2178


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate repository file =="
fd -a 'RootNetworkNodeInfoRepository.java' src/main/java

echo
echo "== locate notification service =="
fd -a 'NotificationService.java' src/main/java

echo
echo "== inspect repository methods =="
repo_file="$(fd -a 'RootNetworkNodeInfoRepository.java' src/main/java | head -n 1)"
if [ -n "$repo_file" ]; then
  rg -n -A 20 -B 8 'setNodeActivity|clearNodeActivity' "$repo_file"
fi

echo
echo "== inspect notification emission method =="
notif_file="$(fd -a 'NotificationService.java' src/main/java | head -n 1)"
if [ -n "$notif_file" ]; then
  rg -n -A 20 -B 8 'emitNodeActivityStatusUpdated' "$notif_file"
fi

Repository: gridsuite/study-server

Length of output: 4941


Broaden the rollback to cover repository and notification failures

setNodeActivity(...) can fail with unchecked Spring/Data or notification exceptions, not just StudyException, so a partial acquire can skip cleanup and leave some root networks non-IDLE. Also, a clearNodeActivity(...) failure during rollback can mask the original error. Catch the broader failure set and suppress rollback errors.

🤖 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/main/java/org/gridsuite/study/server/service/NodeActivityGuardService.java`
around lines 40 - 56, Update acquireActivity to catch the broader unchecked
failures that can arise from setNodeActivity, while preserving the original
exception for propagation. During rollback over acquired root networks, handle
clearNodeActivity failures without replacing the original error, such as by
suppressing them on the caught exception.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant