ADFA-4331: Decode opened plugin tabs off the main thread#1416
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 Walkthrough
Walkthrough
ChangesAsync plugin tab restore with threading regression test
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Sentry APPDEVFORALL-1J. Move Gson decode in restoreOpenedPluginTabs to Dispatchers.Default; keep UI updates on main. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…in thread Failing-first repro that invokes the real private restoreOpenedPluginTabs() under Robolectric and captures the thread on which the cached-tabs preference write executes (via the EventBus PreferenceChangeEvent posted by PreferenceManager.putString). UI tab-selection is skipped by pre-seeding the private pluginTabIndices map. Pre-fix: read + Gson decode + clearing write run synchronously on the main thread -> write thread == main thread -> test FAILS. Fixed: read/decode/write are wrapped in withContext(Dispatchers.IO/Default) -> write runs on a background worker -> test PASSES. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add KDoc to restoreOpenedPluginTabs() and the repro @test; remove a leftover println("PROBE: ...") debug line in RestorePluginTabsThreadTest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9d4f64c to
99467d1
Compare
|
Please be careful about possible collisions with PR #1426 |
Jira Ticket: https://appdevforall.atlassian.net/browse/ADFA-4331
Sentry Issue: https://appdevforall-inc-9p.sentry.io/issues/APPDEVFORALL-1J
Question
Looks like this file is part of AndroidIDE -- do we make changes here or upstream?
Reproduction Details
A main-thread / ANR-risk performance issue (not a crash).
EditorHandlerActivity.restoreOpenedPluginTabs()read the cached-tabs JSON from SharedPreferences and ranGson().fromJson(...)synchronously on the main thread during startup, stalling the UI.Stack Trace
No exception (profiling issue). Suspect function:
(issue type: profile_json_decode_main_thread · device.class: low)
User Steps
User steps leading up to crash, based on Sentry breadcrumbs:
onStart, blocking the first frames. (Profiling aggregate; tagged to the startup transaction.)Was able to reproduce in a unit test?
Yes.
RestorePluginTabsThreadTest(:app, Robolectric) pinsDispatchers.Main, invokes the real privaterestoreOpenedPluginTabs(), and captures the thread on which its pref write executes (via the EventBusPreferenceChangeEvent). Baseline: write thread == main (FAIL); branch: write thread ==DefaultDispatcher-worker(off main). Mutation-sensitive: flipping the prod file flips red/green.What Was Fixed
Move the pref read +
Gsondecode + clearing write intowithContext(Dispatchers.IO/Default)insidelifecycleScope.launch; UI updates stay on Main.Testing
:app:testV8DebugUnitTest --tests …RestorePluginTabsThreadTest→ green (red on baseline). Local CodeRabbit review: no findings. Reviewer notes (local): remove the leftoverprintln("PROBE: …")debug line in the test; the restore now races the siblingonStartreopen-files coroutine (serialized on Main, theoretical only).Fixes APPDEVFORALL-1J