-
Notifications
You must be signed in to change notification settings - Fork 3k
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: OnyxUpdateManager
ends up in a recursive endless loop, when previously applied Onyx updates are not chained (caused crashes on web)
#47429
Conversation
OnyxUpdateManager
ends up in a recursive endless loop, when previously applied Onyx updates are not chained (caused crashes on web)OnyxUpdateManager
ends up in a recursive endless loop, when previously applied Onyx updates are not chained (caused crashes on web)
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.
LGTM 👍!
@chrispader Is this ready? The commits aren't signed. |
yes this is ready. i'm back in office on monday, i can finalize the checklist and fix the unsigned commits then |
feel free to leave a code review already |
b5ad6e6
to
46bdcd0
Compare
46bdcd0
to
13b1608
Compare
@fedirjh i just fixed commit signatures and updated the issue description. This is officially ready for review! 🚀 |
@chrispader In this step, These two logs are occurring repeatedly with different update IDs, is that expected ?
I confirmed that RAM usage is stable and there was no crash issue 🚀 |
Yes, this looks fine 👍 As long as it's not the same logs with the same update IDs over and over again, this is expected. |
Perfect! 🚀 |
Reviewer Checklist
Screenshots/VideosAndroid: mWeb ChromeN/A MacOS: Chrome / Safarihttps://share.cleanshot.com/t5zGqbHY CleanShot.2024-08-19.at.12.44.27-converted.mp4 |
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.
LGTM and tests well.
@arosiclair added you for an extra set of eyes as I think you have some familiarity with this code from working on this PR. |
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.
Looks good as far as I understand this part of the code 😄 I left some ideas for the comments.
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.
changes make sense to me based on the example, please address Marc's comments.
} | ||
} else { | ||
// If the previousUpdateID of the update after the gap is older than the lastUpdateIDFromClient, | ||
// we don't want to detect a missing update, since this would cause a recursion loop in "validateAndApplyDeferredUpdates". | ||
if (previousUpdateID <= lastUpdateIDFromClient) { |
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 we just raise this condition up next to the other if (lastUpdateID <= lastUpdateIDFromClient)
check? I think it's less confusing to follow there
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.
This shouldn't break the upper if
block, because there might be updates, that have an "outdated" previous update, but are still valid to be applied.
I used the chance to improve the code a bit and further improve the comments, so this might be more clear now.
The last commit adds the following changes:
|
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.
LGTM though the logic is still quite confusing at this point 😅. Maybe we can revisit this at another time though I'm not sure it can actually be simplified.
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.
LGTM. I agree we should try to document this with some kind of diagram to make it easier to understand.
I agree too, i don't think we can further simplify the code without too much effort. A diagram would really help understanding the logic of the whole |
Thanks for the changes @chrispader! Merging this to not be a blocker, but also share concerns about the complexity. Not necessarily a bad thing as long as the code works - but maybe something we can address/improve in the future. |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by https://github.com/marcaaron in version: 9.0.23-0 🚀
|
Facing issue with this PR trim.19463C12-9C29-4401-9110-C728906AE5D7.MOV |
This is already on staging yes. What is it that you're trying to investigate exactly? @mvtglobally I see two problems in the video you shared:
|
Just QAd and tested this on staging and it seems the No crashes, freezes or recursions/loops detected, when creating 1000+ reports in a short time. Here's a screen recording of what's going on: Screen.Recording.2024-08-22.at.18.15.34.mov |
🚀 Deployed to production by https://github.com/chiragsalian in version: 9.0.23-0 🚀
|
@AndrewGable @sakluger @hannojg
Details
This PR fixes a problem where the
OnyxUpdateManager
would end up in a recursive loop and therefore cause browser tabs to crash, because the recursive calls would build up the Stack and therefore memory. When memory consumption is to big, the browser tab will crash.This problem was caused, because some Onyx updates from the backend "span over" the last update that was applied to the client. What i mean by that is that we keep track of the
lastUpdateID
of the last update, that was applied to the client inONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT
. When a new (deferred) update has apreviousUpdateID
that is lower thanlastUpdateIDAppliedToClient
, this would cause the validation and application of deferred updates to end up in a loop, because we would always find a gap in the deferred updates.Example:
The current
lastUpdateIDAppliedToClient
is 10. Usually, the next (expected) update would havelastUpdateID
of 11 andpreviousUpdateID
of 10.We didn't yet handle the case properly, when next update (for some reason) has
lastUpdateID
11 andpreviousUpdateID
of 9 (or lower). We can't take 9 as the last update to fetch for missing updates, but instead have to jump out of the recursive validation process.Fixed Issues
$ #44744
PROPOSAL:
Tests
CreateReport
API call in the network log and copy it as node.js codeOffline tests
None needed.
QA Steps
Make sure the chrome tab doesn't use too much RAM and doesn't crash when multiple reports are created.
For testing, follow same procedure as in Tests.
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
MacOS: Desktop