-
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
[HOLD #34289] [$2000] The app crashes when the user is logged into multiple tabs and logs out of one of the tabs #15321
Comments
Triggered auto assignment to @johncschuster ( |
Bug0 Triage Checklist (Main S/O)
|
Triggered auto assignment to @roryabraham ( |
Hm... I may have jumped the gun here. I just tried reproducing the behavior in an incognito window, and was not able to reproduce it. @techievivek, what am I doing wrong here? 2023-02-22_15-57-10.mp4 |
@johncschuster The problem is probably that you were using an incognito window, so the other site is not sharing the same IndexedDB database. When we have the site running in multiple non-incognito tabs, those tabs are both sharing the same data. The same is not true when the site is running in a normal window and in an incognito window. That's why if you're signed in in a normal window and open the site in a new tab, it will pop right up. But if you open it in an incognito window, you'll have to log in again. |
Job added to Upwork: https://www.upwork.com/jobs/~016764b6d950f13143 |
Current assignee @johncschuster is eligible for the External assigner, not assigning anyone new. |
Triggered auto assignment to Contributor-plus team member for initial proposal review - @sobitneupane ( |
Current assignee @roryabraham is eligible for the External assigner, not assigning anyone new. |
ProposalPlease re-state the problem that we are trying to solve in this issue.When we log into 2 tabs in normal browser (not cognito) and log out in 1 tab, the other tab will crash. What is the root cause of that problem?When we logout, we clear the What changes do you think we should make in order to solve the problem?In App/src/components/createOnyxContext.js Line 33 in 33408b8
We can set add a new defaultValue for createOnyxContext , if the value of the OnyxKey is undefined then we'll fallback to that defaultValue .
For example we can do:
And we can set What alternative solutions did you explore? (Optional)NA |
I managed to dig deeper and found the actual root cause which is in Proposal 2Please re-state the problem that we are trying to solve in this issue.When we log into 2 tabs in normal browser (not cognito) and log out in 1 tab, the other tab will crash. What is the root cause of that problem?The root cause is in We have the The things that are happening is:
What changes do you think we should make in order to solve the problem?To fix this, we need to change how we clear the values:
As we can see the required keys like What alternative solutions did you explore? (Optional)NA ResultWorking well after the fix: Screen.Recording.2023-02-23.at.18.40.15.mov |
ProposalPlease re-state the problem that we are trying to solve in this issue.The problem we are trying to solve is that the app is crashing instead of logging out the user in another tab, as expected. What is the root cause of that problem?
The bug : Storage.getItem(onyxKey)
.then(value => onStorageKeyChanged(onyxKey, value)); What changes do you think we should make in order to solve the problem?The bug can be fixed by ensuring that step 4 is called after resetting the key-value pairs in step 5. We can pass a callback to In Onyx.jsOnyx.clear = () => {
// Onyx clear logic
return Storage.clear(() => Storage.multiSet([...defaultKeyValuePairs, ...keyValuesToPreserve]));
}; In this.clear = (callback) => {
let allKeys;
// They keys must be retreived before storage is cleared or else the list of keys would be empty
return Storage.getAllKeys()
.then((keys) => {
allKeys = keys;
})
.then(() => Storage.clear())
.then(() = callback()) // add this line
.then(() => {
// Now that storage is cleared, the storage sync event can happen which is a more atomic action
// for other browser tabs
_.each(allKeys, raiseStorageSyncEvent);
});
}; What alternative solutions did you explore? (Optional)Solution 2 we can pass the keys to preserve to the In Onyx.js const keysToPreserve = _.union(keysToPreserve, defaultKeys); // add this line
return Storage.clear(keysToPreserve) // update this line
.then(() => Storage.multiSet([...defaultKeyValuePairs, ...keyValuesToPreserve])); In WebStorage.js this.clear = (keysToPreserve) => { // update this line
let allKeys;
// They keys must be retreived before storage is cleared or else the list of keys would be empty
return Storage.getAllKeys()
.then((keys) => {
allKeys = keys;
})
.then(() => Storage.clear())
.then(() => {
const keysToSync = _.difference(allKeys, keysToPreserve); // add this line
// Now that storage is cleared, the storage sync event can happen which is a more atomic action
// for other browser tabs
_.each(keysToSync, raiseStorageSyncEvent); // update this line
});
}; |
📣 @fedirjh! 📣 Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork.
Format:
|
✅ Contributor details stored successfully. Thank you for contributing to Expensify! |
@sobitneupane thanks for the review! Both approaches are quite similar and the difference is only in the implementation detail. I agree the sequence
|
@fedirjh Thanks for the proposal. Your proposal looks good. @roryabraham The proposed change should be made in 🎀👀🎀 C+ reviewed |
@tienifr Thanks for your response. The first issue you mentioned doesn't look probable. |
I think part of the reason why this bug happens is because we're commenting |
Not really - I've applied these changes in Onyx I'm a bit confused with the onClear method - we should apply this one in the app, but in the Onyx code we're subscribe to the ON_CLEAR type of data, but we're never sending this kind of message to the Broadcast. I think it should be sent here https://github.com/BeeMargarida/react-native-onyx/blob/c72152c7f894474b01655e09fc8a8ff1c5c99b9b/lib/Onyx.js#L1395 instead of sending CLEAR message again. For the 3rd change - the changes have been already applied, for the 4th - I wonder if this point is still valid. I've already tested the changes in the app - they were working but for HT accounts signing out was really slow. I'll test it once again with the app changes. If everything works fine I will create a PR to Onyx and a PR to App. |
Unfortunately, the more I test this solution the less I'm convinced to apply it - when signing out the Leader tab correctly redirects to sign-in page but the other tabs are "frozen" for a long time (especially for HT accounts). When changing For now we can safely merge Chris PR with bumping the version. |
We are also starting to look more closely at using SQLite's wasm build on the web, and there are probably some SQLite features we could use to synchronize writes across tabs. The SQLite wasm build also depends on OPFS, which they told us operates much more predictably across multiple parallel instances than IndexedDB |
@roryabraham I've came up with a few possible solutions so far, tested them, but none of them seem to be working decently. I'm still thinking of any new solution and tweaking the code. I saw that bumping Onyx caused a few other issues: #33554 (comment) What are the next steps then until I find a working solution? Should we revert the PR with the Broadcast + moving AtiveClientManager to Onyx? |
hey @roryabraham and @koko57. I'm currently working on bumping Onyx in E/App again after the revert and was therefore working on fixing the regressions that the previous bump caused. As mentioned here, this feature/PR caused at least 1-2 regressions. I've started working on fixes for these regressions in Expensify/react-native-onyx#455 (comment), though i'm thinking it might be better, to revert Expensify/react-native-onyx#382 and exclude it from the bump and just bump Onyx with my changes from Expensify/react-native-onyx#437 and all the other prettier PRs and small fixes. cc @mountiny |
One issue with Expensify/react-native-onyx#382 was definitely, that the wrong parameters were passed to The other changes i made to fix #34575, as when the other (non-leader) tabs weren't updated e.g. on In general, do we need to call functions like Also, i experienced issues with Onyx in other (non-leader) tabs, because the cache is stale in non-leader tabs... We'll also have to think about a solution for this i guess |
I'm also going to be working on this feature. Should we prioritize the SQLite wasm build, before putting more work into fixing Expensify/react-native-onyx#382? cc @roryabraham |
@chrispader thanks for taking care of this one! I also think it would be better to revert Expensify/react-native-onyx#382, apply only your changes and bump the version. |
Created a PR to revert these changes here: Expensify/react-native-onyx#458 |
@roryabraham @chrispader I'm waiting on your decision on what should be prioritized |
SQLite sounds more important to me |
I apologize for the lackluster communication on my part. I think that since Expensify/react-native-onyx#382 caused multiple regressions, we should revert it. @chrispader, you should focus on SQLite-wasm over the the cross-tab synchronized writes. It's not 100% clear to me if SQLite-wasm will fix the multi-tab concurrency issues, but it feels like maybe it could. Do multiple tabs share the same database? This seems like something we can discuss further with SQLite and try to get a solid plan for. So let's revert Expensify/react-native-onyx#382 then put this on HOLD for SQLite-wasm |
Got it. Going to start research and implementation tmrw and keep you guys updated in #34289
Revert PR already in the works 👍 |
Putting this on HOLD for #34289. One idea that's maybe crazy or maybe just makes sense is to use bedrock to synchronize SQLite across tabs. I'm really not too sure how the data is shared between tabs in SQLite or how it might need to be replicated. I think using leader election to ensure that only one tab is doing writes makes sense at a high level, not sure what went wrong with out implementation because it was pretty thoroughly tested. Maybe when adding it to E/App we left the old ActiveClientManager in place and the two were conflicting with eachother? |
For keeping the database synchronised, we could create a single instance of it in separate context (e.g. Worker) as a single source of truth and then access it from multiple tabs. I am not sure if It would be cool to have the sync layer OOTB with SQLite.wasm, but let me know what you think of above as kind of an alternative 👍 |
No, unfortunately it wasn't that. Even with applying ActiveClientManager from Onyx the issues are still reproducible. |
I gave an update on the SQLite WASM idea in #34289 (comment). I'm currently also investigating if the extra worker thread could be directly used to sync multiple tabs, or if we need an extra worker or some other logic to keep tabs in sync... |
This issue has not been updated in over 15 days. @trjExpensify, @sobitneupane, @koko57, @roryabraham, @tienifr eroding to Monthly issue. P.S. Is everyone reading this sure this is really a near-term priority? Be brave: if you disagree, go ahead and close it out. If someone disagrees, they'll reopen it, and if they don't: one less thing to do! |
Still held, Melv. |
@trjExpensify, @sobitneupane, @koko57, @roryabraham, @tienifr, this Monthly task hasn't been acted upon in 6 weeks; closing. If you disagree, feel encouraged to reopen it -- but pick your least important issue to close instead. |
This issue this was on HOLD for was closed as not planned for now. Not sure if multi-tab support is worth fixing now or if we should just leave this as closed |
If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!
Action Performed:
Screen.Recording.2023-02-21.at.9.54.21.PM.mov
Expected Result:
The user should have been logged out in the other tab
Actual Result:
The app actually crashes.
Workaround:
No workaround and this needs to be fixed ASAP.
Platforms:
Which of our officially supported platforms is this issue occurring on?
Version Number: v1.2.74-0
Reproducible in staging?: Y
Reproducible in production?: Y
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos: Any additional supporting documentation
Expensify/Expensify Issue URL:
Issue reported by: @hungvu193
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1674651616948819, https://expensify.slack.com/archives/C9YU7BX5M/p1676990369948349
View all open jobs on GitHub
Upwork Automation - Do Not Edit
The text was updated successfully, but these errors were encountered: