-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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 connection drop is not detected #7825
Fix connection drop is not detected #7825
Conversation
ddea1cb
to
ca7cc09
Compare
libs/NetInfo served to provide shim for Electron due to an issue The issue is now resolved and this is no longer needed
Regarding the breaking change - we're not using SSID information - it doesn't affect us v8 Includes the following fixes: 8.0.0 (2022-02-10) BREAKING CHANGES it's possible this is a breaking change, depending on your app use case. If you relied on iOS SSID information and met Apple's strict criteria for accessing SSID, you need to set the new config value shouldFetchWiFiSSID to true. If you set it to true and do not meet the criteria your app may crash due to a memory leak. All versions prior to 7.1.12 would attempt to fetch the information regardless of permission, leak memory, and possibly crash. This change avoids that crash. Bug Fixes ios: avoid memory leak from ssid APIs by adding explicit config (Expensify#560) (fbf7c15), closes Expensify#420 7.1.11 (2022-02-08) Bug Fixes windows: fix race condition in WiFi connection details feature (Expensify#568) (0cd8132) 7.1.10 (2022-02-07) Bug Fixes android: use registerDefaultNetworkCallback so toggling airplane mode works (Expensify#571) (e8af2de) 7.1.9 (2022-01-26) Bug Fixes android: count native listeners / correctly disable listener if count == 0 (Expensify#569) (5ae16f6) 7.1.8 (2022-01-25) Bug Fixes windows: refactor implementation to avoid crashes (Expensify#564) (cc4bfa3) 7.1.7 (2021-12-20) Bug Fixes android: populate network value during initial module startup (Expensify#553) (c05080f) 7.1.6 (2021-12-13) Bug Fixes android: avoid send event when has no listener (Expensify#548) (cad47d8) 7.1.5 (2021-12-09) Bug Fixes android: use method-local ref to instance var for multi-thread safety Expensify#549 (Expensify#550) (81bbc87) 7.1.4 (2021-12-07) Bug Fixes android: try async state fetch as stale state workaround (Expensify#547) (937cf48), closes Expensify#542
This is primarily to help local development and desktop By default on web (desktop) the url for checking is `/` And for local testing you'll always hit it matching localhost:8080 For Desktop since the app is served from electron - requesting `/` would respond with OK even if there's no internet
a8b85a3
to
f5a0171
Compare
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.
Can I ask what's the problem with defining duration as 10 * 1000
is it against code conventions?
`trailing: false` causes duplicate calls removing it makes just one recheck request (as intended)
Ready for review |
It is very clear that 10000 is 10 sec. It is just an extra calculation. Why do you think 10 * 1000 is better? |
Maybe for you. I have hard time distinguishing thousands without some kind of visual separator:
It's common to use this pattern even for seconds: https://github.com/react-native-netinfo/react-native-netinfo/blob/6b01fee211df160d0afce70c5955681c75b24a5a/src/internal/defaultConfiguration.web.ts#L3-L12 And we used as well: https://github.com/Expensify/App/search?q=expiration+%3D+1000+*+60 |
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 don't mind 10 * 1000. I just thinking that we use 5000 ,3000 and not 5 * 1000 in other places of our app.
it makes more sense to use when you have to show the different parts of calculations.
e.g.
Secs in day = 24 * 60 * 60
src/libs/NetworkConnection.js
Outdated
// whether a user has internet connectivity or not. | ||
unsubscribeFromNetInfo = NetInfo.addEventListener((state) => { | ||
Log.info('[NetworkConnection] NetInfo state', false, state); | ||
setOfflineStatus(!state.isInternetReachable); |
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.
Here we set the offline/online status based on isInternetReachable
prop. I didn't find many details about it but I think this flag is set based on the result of the HTTP request.
So when the user is online it seems right to check the flag but when the user is offline it will take some time to be set.
I think we should do this.
if state.isConnected
then offline status = !state.isInternetReachable
Else if !state.isConnected
then offline status = false.
When a user is not connected then we don't have to wait for this flag state.isInternetReachable
. If it behaves the same then It's OK.
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.
isInternetReachable
is not always set from the result of a request
When state.isConnected
is false
- state.isInternetReachable
is also false
isInternetReachable
is set from true
to false
when the check request fails or takes longer than 5sec.
✔️ Ready for review |
Ok, I see. I will test it shortly. |
Thanks for the clarification and changes. Looks better now.
Do you think we can improve this by adding a global listener for NetInfo? // whether a user has internet connectivity or not.
unsubscribeFromNetInfo = NetInfo.addEventListener((state) => {
Log.info('[NetworkConnection] NetInfo state', false, state);
setOfflineStatus(!state.isInternetReachable); |
How would that help? |
Oh, So we always have an active listener Didn't notice it earlier. At this point, I say we are good. |
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.
@pecanoro can you review this PR, it's been waiting for some time |
Sure, sorry for the delay, I was at a college career fair during the week so I wasn't on my computer. |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
Thank you 👍 |
Just a heads up that this is causing CORS errors on dev where most internal engineers are using ngrok to tunnel to the local API. Is there any solution around this? |
Use a different URL here: App/src/libs/NetworkConnection.js Lines 57 to 60 in d05c56e
Or disable the internet reachability test if ENV is DEV |
Shouldn't const expensifyURLRoot = useNgrok && ngrokURL ? ngrokURL : expensifyComWithProxy;
...
URL_API_ROOT: expensifyURLRoot, |
Yes, but it seems there's some kind of CORS issue with doing that |
Throwing a deploy blocker on here temporarily while we try to figure out what is happening. I have a feeling these changes may be contributing to the instability brought up in this thread |
Ok, seems like it is only affecting dev 😄 |
🚀 Deployed to production by @chiragsalian in version: 1.1.42-6 🚀
|
|
||
Log.info('[NetworkConnection] recheck NetInfo'); | ||
hasPendingNetworkCheck = true; | ||
unsubscribeFromNetInfo(); |
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.
@kidroca Do you recall why you chose to unsubscribe and resubscribe to NetInfo rather than using NetInfo.fetch to recheck the network connection?
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.
Oh, looks like NetInfo will only trigger the recheck if you call NetInfo.fetch
with a specific interface: https://github.com/react-native-netinfo/react-native-netinfo/blob/f05f7dd6e829135d907506e9270e729066b6e5d1/src/internal/state.ts#L100-L106
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.
Oh, looks like NetInfo will only trigger the recheck if you call
NetInfo.fetch
with a specific interface
Yes, there isn't an exposed way to force a recheck, it might not be necessary, though we decided to do it if any request is taking unusually long time (more than 10-15 sec)
What triggers the recheck is actually the call to NetInfo.configure
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.
Yes, there isn't an exposed way to force a recheck
Yep, I created a PR for react-native-netinfo to add this and clean up this implementation a bit: react-native-netinfo/react-native-netinfo#594
Details
Update NetInfo usage to test for internet connectivity rather than active network connection
Desktop specific NetInfo shim is removed - the external issue in the comment has been resolved and offline state is detected in Desktop
Remains the same:
New:
running for +7 seconds we trigger connection recheck that takes about 5 sec. (or less if it fails immediately)
Fixed Issues
$ #6059
Tests
Web / Desktop
iOS / Android
QA Steps
Try to simulate very poor or no network conditions
Web / Desktop
iOS / Android
Tested On
Screenshots
Web
New.Expensify.-.Google.Chrome.2022-02-19.05-37-48.mp4
Mobile Web
mobile.internet.mp4
Desktop
Desktop.Internet.mp4
iOS
RPReplay_Final1645250899.mp4
Android
Android.Internet.mp4