-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
execute calls to AsyncStorageModule serially #20386
Conversation
@hramos @gengjiawen I have no experience of writing android tests, could you please help update tests for AsyncStorageModule? |
@@ -1,4 +1,4 @@ | |||
/** | |||
/* |
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.
why touch this line ?
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.
Android Studio was showing warning, so fixed it 😄
I have little test experience on android test. Do you test your code in some way , like tested it on real device. |
I was thinking that example for AsyncStorage in RNTester app would be
useful, but I develop in TypeScript and have no experience of Flow. The
example must be trivial, enter a key and value to store and enter key to
retrieve its value.
|
I find flow difficulty to write too. I want it in plain js. And also current project has to many #FlowFixme. |
@@ -83,9 +85,9 @@ public void multiGet(final ReadableArray keys, final Callback callback) { | |||
return; | |||
} | |||
|
|||
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) { | |||
execute(new Runnable() { |
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.
What happens if an exception is thrown when executing the Runnable?
GuardedAsyncTask provided error management, see: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/GuardedAsyncTask.java#L34
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.
Could we use executeOnExecutor
(https://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor,%20Params...)) instead of execute
and keep using GuardedAsyncTask instead?
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.
@janicduplessis got it and ready to push the change, but waiting for CI to become green again.
@@ -42,6 +43,7 @@ | |||
|
|||
private ReactDatabaseSupplier mReactDatabaseSupplier; | |||
private boolean mShuttingDown = false; | |||
private Executor executor = Executors.newSingleThreadExecutor(); |
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.
I'm not sure if adding a new executor is the best approach here, but If you are adding this you should override the onCatalystInstanceDestroy method and then shutdown the executor.
See:
react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModule.java
Line 51 in 26684cf
void onCatalystInstanceDestroy(); |
Thank you @mdvacca for review and suggestions.
Could you please suggest other options to make serially execute calls than
executor.
I intentionally wrapped in private execute method so we can easily change
execution method in the future. I'll change it to handle runtime exception,
and shutdown executor.
|
@mdvacca made changes as you suggested 😉 |
ExecutorService in AsyncStorageModule is customizable, and test is passing. It'll fix many issues on Android, including me. @mdvacca please review and merge |
Summary: This patch is a bit of a hack job, but I'd argue it's necessary to dramatically improve the dev UX on Android devices. Somewhere in react-native, there's a shared SerialExecutor which AsyncStorage uses that is getting blocked, causing remote debugging to occasionally hang indefinitely for folks making AsyncStorage requests. This is frustrating from a dev UX perspective, and has persisted across several versions as far back as RN 0.44, and still remains on RN 0.54. The issue seems to only happen on Android > 7+, which is likely because the ThreadPoolExecutor behavior changed in this version: https://stackoverflow.com/questions/9654148/android-asynctask-threads-limits Fixes #14101 We've been using this patch in production for the past 4 months on our team by overriding the AsyncStorage native module. We use AsyncStorage extensively for offline data and caching. You can test by compiling this commit version into a test react native repository that is set to build from source: ```sh git clone https://github.com/dannycochran/react-native rnAsyncStorage cd rnAsyncStorage git checkout asyncStorage cd .. git clone https://github.com/dannycochran/asyncStorageTest yarn install cp -r ../rnAsyncStorage node_modules/react-native react-native run-android ``` No documentation change is required. #16905 [Android] [BUGFIX] [AsyncStorage] - Fix AsyncStorage causing remote debugger to hang indefinitely. Pull Request resolved: #18522 Differential Revision: D8624088 Pulled By: hramos fbshipit-source-id: a1d2e3458d98467845cb34ac73f2aafaaa15ace2
Maybe add RNTester showcase too. Can we just add plain js in RNTester ? @hramos @janicduplessis |
I'll wait for @mdvacca to provide feedback here. Also, looks like we have some conflicts. |
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.
Fix conflicts.
@hramos @janicduplessis please review and merge. CI fails on E2E due to timeout. Thank you |
CI looks good, still waiting on review from @mdvacca or other. I'm not the best person to review this. |
@mdvacca could you please review ASAP. I would like it to land in 0.57 if possible, because I'm planning to use it for my projects. Thank you |
Would be great to have it in 0.57! |
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.
hramos has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
Hey @dulmandakh. We moved AsyncStorage to its own repo, it would be great if you could re-send your PR to that one: https://github.com/react-native-community/react-native-async-storage |
This PR creates single threaded executor in AsyncStorageModule and use it to execute calls serially, so that below code works as expected
Previously, it was using AsyncTask that executes tasks in its own thread pool, which may execute calls in parallel.
Since it uses its own executor, it don't need to wrap the executions in the AsyncTask.
Fixes #18372 #14101
Test Plan:
Before (it's inconsistent)
After
Release Notes:
Help reviewers and the release process by writing your own release notes. See below for an example.
[ANDROID] [BUGFIX] [AsyncStorage] - Execute calls serially