-
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
Fix AsyncStorage not resolving its promises #16905
Conversation
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.
@shergin has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
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.
@shergin is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
I tried to merge this pull request into the Facebook internal repo but some checks failed. To unblock yourself please check the following: Does this pull request pass all open source tests on GitHub? If not please fix those. Does the code still apply cleanly on top of GitHub master? If not can please rebase. In all other cases this means some internal test failed, for example a part of a fb app won't work with this pull request. I've added the Import Failed label to this pull request so it is easy for someone at fb to find the pull request and check what failed. If you don't see anyone comment in a few days feel free to comment mentioning one of the core contributors to the project so they get a notification. |
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.
@shergin is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
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.
@shergin is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
The same thing happened with other PRs of mine, that have been accepted as well. If I can do something to fix / improve this, let me know! |
Hey @jsdario is there any chance for you to update your PR ? Do you need help or anything ? |
I believe it's ready to merge, I am using this fork on production, no surprises so far > 5000 devices |
Per facebook#16905, AsyncStorage can fail to resolve its promises, causing our app to hang indefinitely at loading screen. This commit takes the changes from that pull (without cherry-picking, just eye-balling), and commits it to our forked version of 0.51.
Is it possible to do a release, 0.51.1, with this in there? AsyncStorage being broken likely is blocking a lot of apps, like mine, that assume the promise will always resolve. |
How does this compile? Did you mean executeOnExecutor? This seems to pass AsyncTask.THREAD_POOL_EXECUTOR into a bunch of stuff that doesn't actually accept an executor (ex SQLiteStatement or AsyncTask#execute). |
@esprehn that is why the CircleCI tests are failing. It should be However, AsyncStorage does have potential deadlocks with other uses of AsyncTasks in the app. In my app, we were able to change to parallel tasks to avoid the deadlock. Ideally, AsyncStorage's use of AsyncTasks would place the work on it's own serial Executor instead of the default one. I'm not familiar enough with Java to competently implement this or I'd jump in :/ (I just wrote my first copy-pasta Java code about a month ago, when I ran across this issue) |
@RickDT I did that by copying the SerialExecutor [1] into a forked version of AsyncStorageModule (and friends). It's alarming that something is blocking the shared SERIAL_EXECUTOR though. It doesn't seem like it's been identified in the bug, does anyone know what it is? |
I believe this happens due to other Java code in the app, outside of React Native, behaving badly and blocking the shared SERIAL_EXECUTOR. The OP claims "Projects with other background activities...", which is certainly where we saw it in our codebase. The test case in the OP may be failing due to a bug in the test case. I created a new RN app and pasted the test code and indeed did not get the inner log. However, that's because nothing had been saved in AsyncStorage. The updated test case does work as expected with AsyncStorage:
This will run successfully over many iterations, and if you set I think that putting AsyncStorage on a non-shared serial executor will solve the problem for most cases. Other cases may be another bug altogether. If not, we need a true failing test case. If needed, I can whip up a test project that demonstrates blocking from outside of RN in a misbehaving AsyncTask. |
i believe it is fixed in v51 |
What is the status of this PR now? @shergin |
With your code snippet, @RickDT, and remote debugging running, if I refresh the default react-native app example app fast enough and often enough, eventually the first call to AsyncStorage will hang indefinitely and never resolve. If I turn off remote debugging, the call will never hang. Are others experiencing this problem with remote debugging turned off? |
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.
@shergin is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
As far as I can tell, the change in this commit does not actually work. We've been using the following change in production for the past 4 months and it works: |
The solution from @dannycochran has two advantages: staying with Sync execution and not relying on shared system executors. I would much prefer it get merged. I think the root of the problem is that the shared system executors are getting out of whack when restarting the React Native application without restarting the underlying Android Main Activity. And (sorry to repeat myself), arbitrarily swapping to parallel execution could definitely result in unanticipated knock-on effects for some app developers. |
This comment has been minimized.
This comment has been minimized.
I figured a sort of reason why this is happening. If You click CTRL + S or CMD + S to save the file twice this will trigere, Live Reload. Sometimes if you click ctrl + s or cmd + s once Live Reload doesn't work, and if you click it second time almost immediately after first attempt, I'm able to replicate the issue. Workaround that works for me for now is to close the app, go to Simulator/ Real device menu and open it again. Then AsyncStorage works again. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I still have this problem in 0.55.4 |
This comment has been minimized.
This comment has been minimized.
I think I have found a possible solution to this problem. I hope it helps: Component: storageClass: |
Hi, same for me here and very frustrating because asyncstorage is as major dep of Apollo Client when we want to cache the app. Please we need a fix for this ... opened since May 2K17 ! Thanks everyone |
As @slegaitis said, it is something related to Live Reload option. Fortunately, it also works with "Reload" option and the VSCode Extension called React Native Tools has a shortcut to use this option using |
It does not work with remote debugging enabled though, no matter if Live Reload is enabled. |
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 facebook#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. facebook#16905 [Android] [BUGFIX] [AsyncStorage] - Fix AsyncStorage causing remote debugger to hang indefinitely. Closes facebook#18522 Differential Revision: D8624088 fbshipit-source-id: 2a599fbca270a4826063cd93be8eaf796f34f57a
Any news on this? It looks to me like the CI test was failing for reasons unrelated to the PR; maybe it just needs to re-run? It would be great to see this in the next RN release… |
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
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 facebook#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. facebook#16905 [Android] [BUGFIX] [AsyncStorage] - Fix AsyncStorage causing remote debugger to hang indefinitely. Pull Request resolved: facebook#18522 Differential Revision: D8624088 Pulled By: hramos fbshipit-source-id: a1d2e3458d98467845cb34ac73f2aafaaa15ace2
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 facebook#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. facebook#16905 [Android] [BUGFIX] [AsyncStorage] - Fix AsyncStorage causing remote debugger to hang indefinitely. Pull Request resolved: facebook#18522 Differential Revision: D8624088 Pulled By: hramos fbshipit-source-id: a1d2e3458d98467845cb34ac73f2aafaaa15ace2
Hello. I placed an loader till the promise resolves but loader is not rendered and seems like the app refused to render anymore. Please help anyone. |
Closing as the bug is solved and this PR is over a year old |
i have the same issue .. asynstroage not working on Android version 24+(7+).. any one has solutaion?? |
@Waqas-Jani Can you tell us what version of React Native you are running? Are you using the older built-in AsyncStorage or the newer community one ( Either way, this bug has been solved and you might be seeing a different one. I would recommend opening a new issue on https://github.com/react-native-community/async-storage |
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. facebook/react-native#16905 [Android] [BUGFIX] [AsyncStorage] - Fix AsyncStorage causing remote debugger to hang indefinitely. Pull Request resolved: facebook/react-native#18522 Differential Revision: D8624088 Pulled By: hramos fbshipit-source-id: a1d2e3458d98467845cb34ac73f2aafaaa15ace2
Motivation
Projects with other background activities may seen its AsyncStorage problems delayed or never resolved. Here it is an old issue explaining the bug conditions for devices with Android 7+
#14101 (comment)
Test Plan
We can reproduce the error following the steps in issues, which I copy paste here:
The following code executes inside React Native component lifecycle's
Code after 'Inside setInterval' is never called. It only runs once if outside the setInterval. If I call once the code outside the setInterval it appears to run just fine. I also tried callback format vs async / await version but it does not seem to matter.
Release Notes
[ANDROID] [BUGFIX] [ReactAndroid/src/main/java/com/facebook/react/modules/storage/AsyncStorageModule.java] - Fixed AsyncStorage when not resolving its promises for Android 7+