-
Notifications
You must be signed in to change notification settings - Fork 280
perf(android): move state persistence off UI thread (AN-1) + test hardening #602
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
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
dea9493
improvement 2
sunnylqm c080264
perf(android): move state persistence off the UI thread (AN-1)
sunnylqm 0763c29
Delete CODE_AUDIT.md
sunnylqm c56ab4d
fix: apply CodeRabbit auto-fixes
coderabbitai[bot] 0d6ec3e
refactor(android): name the state-serial executor thread (AN-1 review)
sunnylqm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
android/src/main/java/cn/reactnative/modules/update/StateSerialRunner.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| package cn.reactnative.modules.update; | ||
|
|
||
| import android.util.Log; | ||
| import androidx.annotation.Nullable; | ||
| import com.facebook.react.bridge.Promise; | ||
|
|
||
| import java.util.concurrent.Executor; | ||
| import java.util.concurrent.Executors; | ||
| import java.util.concurrent.ThreadFactory; | ||
|
|
||
| /** | ||
| * Runs state-persistence operations (switchVersion / markSuccess / setUuid / | ||
| * setLocalHashInfo) on a dedicated single background thread. | ||
| * | ||
| * These operations only read/modify SharedPreferences via a synchronous | ||
| * commit(); they were previously dispatched to the UI thread purely to | ||
| * serialize them. markSuccess in particular runs on every cold start, so doing | ||
| * its blocking disk write on the main thread caused jank/ANR on low-end | ||
| * devices. A single-thread executor preserves the same serialization guarantee | ||
| * while keeping the disk I/O off the UI thread. | ||
| * | ||
| * Note: reload/restart operations must still run on the UI thread and therefore | ||
| * keep using {@link UiThreadRunner}. | ||
| */ | ||
| final class StateSerialRunner { | ||
| interface Operation { | ||
| void run() throws Throwable; | ||
| } | ||
|
|
||
| // Single worker thread -> operations stay serialized in submission order, | ||
| // matching the previous UI-thread behavior. The thread is named so it is | ||
| // identifiable in thread dumps / ANR traces when diagnosing persistence. | ||
| private static final Executor EXECUTOR = Executors.newSingleThreadExecutor( | ||
| new ThreadFactory() { | ||
| @Override | ||
| public Thread newThread(Runnable r) { | ||
| return new Thread(r, "pushy-state-serial"); | ||
| } | ||
| }); | ||
|
|
||
| private StateSerialRunner() { | ||
| } | ||
|
|
||
| static void run( | ||
| @Nullable final Promise promise, | ||
| final String operationName, | ||
| final Operation operation | ||
| ) { | ||
| EXECUTOR.execute(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| try { | ||
| operation.run(); | ||
| } catch (Throwable error) { | ||
| if (promise != null) { | ||
| promise.reject(operationName + " failed", error); | ||
| } else { | ||
| Log.e(UpdateContext.TAG, operationName + " failed", error); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.