Skip to content

Conversation

@andimarek
Copy link
Member

@andimarek andimarek commented Sep 23, 2025

This PR fundamentally refactors the PerLevelDataLoaderDispatchStrategy

first it simplifies a lot what is actually tracked and then it get rids of synchronized/locks and uses a CAS mechanism instead.

First Pr that implemented a lock free chained data loader tracking: #4123

@github-actions
Copy link
Contributor

github-actions bot commented Sep 23, 2025

Test Results

  326 files    326 suites   3m 30s ⏱️
5 022 tests 5 016 ✅ 6 💤 0 ❌
5 111 runs  5 105 ✅ 6 💤 0 ❌

Results for commit 2eecad7.

♻️ This comment has been updated with latest results.

@andimarek andimarek changed the title Per level tracking refactor Per level tracking simplification and performance improvements Sep 24, 2025
@andimarek andimarek requested a review from Copilot September 24, 2025 20:23
Copy link
Contributor

Copilot AI left a comment

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 refactors the PerLevelDataLoaderDispatchStrategy to simplify level tracking and improve performance by replacing synchronized blocks with lock-free compare-and-swap (CAS) operations. The refactoring reduces the complexity of tracking mechanisms and introduces atomic operations for thread safety.

  • Simplified per-level tracking by consolidating multiple tracking maps into a single state object
  • Replaced synchronized blocks with CAS-based atomic operations for better performance
  • Restructured subscription execution flow with separate callback methods

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
PerLevelDataLoaderDispatchStrategy.java Core refactoring with new StateForLevel class and CAS-based updates
LevelMap.java Updated toString format with additional brackets
DataLoaderDispatchStrategy.java Split subscription callback into separate methods
SubscriptionExecutionStrategy.java Updated to use new subscription callback methods
ExecutionStrategy.java Reordered executeObject call timing
LevelMapTest.groovy Updated test assertions for new toString format
DataLoaderPerformance.java Removed benchmark annotations and added main method for testing

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

return true;
private boolean isLevelReady(int level, CallStack callStack) {
// we expect that parent has been dispatched and that all parents fields are completed
// all parent fields completed means all parent parent on completions finished calls must have happened
Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

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

This line can cause an IndexOutOfBoundsException when level is less than 2. The method isLevelReady should validate that level >= 2 before accessing level - 2.

Suggested change
// all parent fields completed means all parent parent on completions finished calls must have happened
// all parent fields completed means all parent parent on completions finished calls must have happened
if (level < 2) {
return false;
}

Copilot uses AI. Check for mistakes.
if (callStack.tryUpdateLevel(curLevel, currentState, currentState.increaseHappenedExecuteObjectCalls())) {
return;
}

Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

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

This infinite loop without backoff or yield could cause excessive CPU usage under high contention. Consider adding a short pause or using exponential backoff between CAS retry attempts.

Suggested change
// Avoid excessive CPU usage under contention
Thread.onSpinWait();

Copilot uses AI. Check for mistakes.
CallStack.StateForLevel currentState = callStack.get(level);
if (callStack.tryUpdateLevel(level, currentState, currentState.increaseHappenedCompletionFinishedCount())) {
break;
}
Copy link

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

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

Another infinite CAS retry loop without backoff. This could lead to high CPU usage under contention. Consider adding yield or backoff strategy.

Suggested change
}
}
Thread.yield();

Copilot uses AI. Check for mistakes.
@andimarek andimarek merged commit bf37527 into master Sep 24, 2025
2 checks passed
@andimarek andimarek added this to the 25.x breaking changes milestone Sep 25, 2025
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.

1 participant