Fix PSI environment thread safety — share single instance#9
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 6 minutes and 0 seconds. ⌛ 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. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe changes introduce a safer PSI environment initialization pattern by adding a Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/main/kotlin/zone/clanker/gradle/srcx/parse/PsiEnvironment.kt`:
- Around line 49-67: The createOrNull() method's fail-once logic is not
thread-safe because initFailed is a plain var; make the check-and-set atomic by
either replacing initFailed:Boolean with an AtomicBoolean and using
compareAndSet(false, true) to short-circuit after a failure, or wrap the read +
runCatching + onFailure write in a synchronized block so only one thread
performs initialization and sets initFailed when an exception occurs; update
references in createOrNull(), PsiEnvironment instantiation, and the onFailure
handler (logger.warn) accordingly so the fail-once behavior is preserved under
concurrent calls.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 22b4babe-9731-4d2f-8e76-6aac12350b7c
📒 Files selected for processing (2)
src/main/kotlin/zone/clanker/gradle/srcx/analysis/SourceFileMetadata.ktsrc/main/kotlin/zone/clanker/gradle/srcx/parse/PsiEnvironment.kt
The IntelliJ platform's ApplicationManager is not thread-safe. Creating multiple PsiEnvironments concurrently (from parallel project analysis) corrupts internal state, leaving lateinit properties uninitialized. Fix: PsiEnvironment.shared() creates exactly one instance with synchronized initialization. All scanSources/parseSourceFile calls reuse it with synchronized access. Closed once at the end of ContextTask.generate(). This fixes "lateinit property module has not been initialized" errors on repos with multiple included builds.
03f7512 to
c8e6688
Compare
|
@coderabbitai Thanks for the thorough review! All addressed. |
|
Great work on the fix — the fail-once pattern for PSI initialization is a clean, pragmatic approach. I'll do a fresh pass to confirm everything looks good! ✅ Actions performedReview triggered.
|
Summary
lateinit property module has not been initialized), it now logs one warning instead of failing every single moduleTest plan
./gradlew buildpassesSummary by CodeRabbit
Bug Fixes
Refactor