-
-
Notifications
You must be signed in to change notification settings - Fork 638
Fix component registration race condition with defer loading strategy #1972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Changes the default loading strategy from :async to :defer to prevent race conditions where React hydration starts before component registrations complete. Root cause: With async script loading, both client-bundle and generated component packs can execute in any order. When client-bundle executes first, React attempts to hydrate components that haven't been registered yet, causing "Could not find component registered with name X" errors. Solution: - Default generated_component_packs_loading_strategy to :defer (was :async) - Use defer: true for client-bundle in dummy app layout - Update comments to reflect new strategy With defer, scripts execute in DOM order after parsing, ensuring: 1. Generated component packs load first 2. Components register before main bundle executes 3. React hydration finds all registered components Fixes CI failures in: - spec/system/integration_spec.rb[1:1:6:1:2] - spec/system/integration_spec.rb[1:1:6:2:2]
|
Warning Rate limit exceeded@justin808 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 15 minutes and 57 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThis PR changes the default component bundle loading strategy from potentially asynchronous to consistently deferred, ensuring component registrations complete before hydration. Removes automatic async-enabling logic and simplifies script tag behavior in the dummy app configuration. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
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. Comment |
Code Review - PR #1972SummaryThis PR addresses an intermittent race condition in CI tests by changing the default loading strategy for generated component packs from ✅ Strengths
🔍 Potential Issues & Questions1. Missing Test Coverage (Medium Priority)The configuration validation logic is changed but I don't see corresponding unit tests added/updated. Consider adding tests to describe '.generated_component_packs_loading_strategy' do
context 'when not explicitly set' do
it 'defaults to :defer' do
ReactOnRails.configure do |config|
config.auto_load_bundle = true
end
expect(ReactOnRails.configuration.generated_component_packs_loading_strategy).to eq(:defer)
end
end
context 'when explicitly set to :async' do
context 'with Shakapacker < 8.2.0' do
it 'raises an error' do
allow(ReactOnRails::PackerUtils).to receive(:supports_async_loading?).and_return(false)
expect do
ReactOnRails.configure do |config|
config.generated_component_packs_loading_strategy = :async
end
end.to raise_error(ReactOnRails::Error, /does not support async script loading/)
end
end
end
end2. Breaking Change Consideration (Low Priority)While this is the right default, existing users who explicitly configured their apps for
3. Removed
|
Updates configuration_spec.rb to reflect the new default behavior where generated_component_packs_loading_strategy defaults to :defer instead of :async (Shakapacker >= 8.2.0) or :sync (Shakapacker < 8.2.0). This change aligns with the race condition fix that makes :defer the universal default to ensure component registrations complete before React hydration.
Code Review - PR #1972: Fix component registration race condition with defer loading strategySummaryThis PR addresses an important race condition issue with component registration when using the defer loading strategy. The fix is well-reasoned and properly addresses the root cause. ✅ Strengths1. Clear Problem IdentificationThe PR correctly identifies the race condition with
2. Appropriate SolutionChanging the default to
3. Comprehensive Test UpdatesThe test changes correctly reflect the new default behavior across different Shakapacker versions. 4. Code SimplificationThe refactoring in
|
Added entries for: - PR #1976: Polished error messages in configuration validation - PR #1972: Fixed component registration race condition with defer loading 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
| # Use defer as the default to ensure generated component packs load and register | ||
| # components before main bundle executes, avoiding race conditions with async loading | ||
| self.generated_component_packs_loading_strategy = :defer | ||
| elsif generated_component_packs_loading_strategy == :async && !PackerUtils.supports_async_loading? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AbanoubGhadban This requires careful review before we release 16.2.0
Creates detailed analysis of the component registration race condition that PR #1972 attempted to fix by changing the default loading strategy from :async to :defer. Key findings: - PR #1972 treats symptom (execution order) not root cause (timing) - Defer forces sequential execution, hurting performance - React on Rails already has component_registry_timeout feature - Race condition suggests timeout isn't working correctly - Need to investigate why hydration doesn't wait for registrations Recommendations: - Keep async as default for performance - Fix component registry timeout mechanism - Use defer only when truly necessary (documented cases) - Add proper synchronization instead of forced execution order This investigation provides foundation for implementing a proper fix that maintains performance while preventing race conditions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## Summary Reverts commit d1a8a1a which changed the default component loading strategy from :sync to :defer. This reverts the fix for the component registration race condition that was introduced in #1972. ## Changes - Reverts the defer loading strategy back to the original behavior - Restores async loading support when available - Updates tests to reflect the original expectations <!-- Reviewable:start --> - - - This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/shakacode/react_on_rails/1981) <!-- Reviewable:end -->
Problem
CI tests were failing intermittently with component registration errors:
This was caused by a race condition where React hydration started before component registrations completed.
Root Cause
With script loading (default on Shakapacker >= 8.2.0):
Solution
Changed default loading strategy to for deterministic execution order:
With :
Testing
Fixes CI failures in:
Files Changed
lib/react_on_rails/configuration.rb- Changed default strategy to :deferspec/dummy/app/views/layouts/application.html.erb- Always use defer for client-bundlespec/dummy/config/initializers/react_on_rails.rb- Updated comments🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com
This change is
Summary by CodeRabbit
Bug Fixes
Refactor