-
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
De-dupe network requests #40059
De-dupe network requests #40059
Conversation
@hungvu193 Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Last testcase is failing for me:
Now Screen.Recording.2024-04-11.at.09.20.34.mov |
Also test is failing @roryabraham |
OK, I can reproduce this, consistently now. We need to repeat step 1 to step 17 few times. Test 1Test1.movTest 2Test2.mov |
src/libs/Network/SequentialQueue.ts
Outdated
// Add request to Persisted Requests so that it can be retried if it fails | ||
PersistedRequests.save(request); | ||
if (!hasConflict || !shouldIncludeCurrentRequestOnConflict) { |
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.
Because we flip the condition from shouldExcludeCurrentRequestOnConflict
to shouldIncludeCurrentRequestOnConflict
, we should remove the negation too.
if (!hasConflict || !shouldIncludeCurrentRequestOnConflict) { | |
if (!hasConflict || shouldIncludeCurrentRequestOnConflict) { |
I think we also need to set the default value for shouldIncludeCurrentRequestOnConflict
to true.
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.
@bernhardoj applying those changes doesn't seem to fix the issue I mentioned above:
Screen.Recording.2024-04-11.at.10.29.22.mov
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, the suggestion is to have the name match what it does. shouldIncludeCurrentRequestOnConflict
tells whether we should include the current request even if there is a conflict. If we negate it (!), then it's read as, don't include the current request when there is a conflict, but inside the if
, we include the request.
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 see, the issue above also happened on Staging, it doesn't relate to 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.
I think the problem is that the name is confusing. I see why too - right now shouldIncludeCurrentRequestOnConflict=true
means something like:
"if this request conflicts with other serialized requests, cancel it along with those other requests"
and shouldIncludeCurrentRequestOnConflict=false
means something like:
"if this request conflicts with other serialized requests, cancel those other requests but still send this one"
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 went ahead and renamed this param to shouldSkipThisRequestOnConflict
, which feels more clear to me:
- If
hasConflict && shouldSkipThisRequestOnConflict
then the request is skipped - if
hasConflict && !shouldSkipThisRequestOnConflict
, then the request is not skipped
src/libs/actions/Report.ts
Outdated
) as string[]; | ||
return persistedRequests.filter((request) => conflictingCommands.includes(request.command) && request.data?.reportActionID === reportActionID); | ||
}, | ||
handleConflictingRequest: () => Onyx.update(successData), | ||
shouldIncludeCurrentRequest: !isDeletedParentAction, | ||
shouldIncludeCurrentRequestOnConflict: !isDeletedParentAction, |
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.
Same with above, we need to remove the negation here.
shouldIncludeCurrentRequestOnConflict: !isDeletedParentAction, | |
shouldIncludeCurrentRequestOnConflict: isDeletedParentAction, |
isDeletedParentAction | ||
? [WRITE_COMMANDS.UPDATE_COMMENT] | ||
: [WRITE_COMMANDS.ADD_COMMENT, WRITE_COMMANDS.ADD_ATTACHMENT, WRITE_COMMANDS.UPDATE_COMMENT, WRITE_COMMANDS.DELETE_COMMENT] | ||
isDeletedParentAction ? [WRITE_COMMANDS.UPDATE_COMMENT] : [WRITE_COMMANDS.ADD_COMMENT, WRITE_COMMANDS.ADD_ATTACHMENT, WRITE_COMMANDS.UPDATE_COMMENT] |
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.
Btw, do we not want to conditionally add UPDATE_COMMENT only when isOptimisticAction
is true? (just like I did in my PR)
isDeletedParentAction ? [WRITE_COMMANDS.UPDATE_COMMENT] : [WRITE_COMMANDS.ADD_COMMENT, WRITE_COMMANDS.ADD_ATTACHMENT, WRITE_COMMANDS.UPDATE_COMMENT] | |
isDeletedParentAction ? [WRITE_COMMANDS.UPDATE_COMMENT] : [WRITE_COMMANDS.ADD_COMMENT, WRITE_COMMANDS.ADD_ATTACHMENT, reportAction.isOptimisticAction ? WRITE_COMMANDS.UPDATE_COMMENT : ''] |
What will happen if we always include it?
- Add a comment while online (added to server)
- Go offline
- Edit the comment. At this point, the persisted request contains UPDATE_COMMENT
- Delete the comment.
Both edit and delete request is cancelled out, the message is optimistically deleted, but the message will reappears when reopening the chat.
|
||
it('should always ignore any requests that have already been sent', async () => { | ||
expect(PersistedRequests.getAll().length).toBe(1); | ||
SequentialQueue.flush(); |
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.
@roryabraham You may need to mock flush as it will never resolve in tests.
@roryabraham Can you add an automated test?
Result: Only |
@roryabraham Can you define the ideal behavior in this case?
|
thanks for the comments here, jumping back in |
I broke this when fixing lint, should be fixed now. |
hmmm just thought of another case that's not covered correctly though:
In this case we'd want the But in this case:
we'd want both the |
I fixed that issue by making |
@roryabraham We might want to add a new API in this. |
Screen.Recording.2024-04-12.at.10.29.41.movI think the first case you mentioned here is still failing. It skipped both update and delete comment API. |
Thanks for all the reviews everyone. We've agreed that this is too risky / too low-level a PR to CP. Instead, we're going to proceed with a revert of all request de-duping features, CP that, then proceed with this PR on a less-rushed timeline, ensuring that everything works as expected and it receives full QA on staging |
@roryabraham You can close this PR |
@shubham1206agra why do you say that? We reverted the request de-duping logic completely with the intention of completing this PR and having it go through full regression tests |
Oh |
@roryabraham Can we start again to push this PR through? |
# Conflicts: # src/libs/actions/PersistedRequests.ts # src/libs/actions/Report.ts # src/types/onyx/Request.ts
Closing in favor of #47913 |
Details
This fixes a few problems:
DeleteComment
will "conflict" with itself, causing it to not be executed.AddComment
request, and you try to delete it, the delete will not run.Fixed Issues
$ #39432
$ #39307
PROPOSAL:
Tests / Offline Tests / QA Steps
Open a DM with someone
Send a comment
Delete it
Verify the comment deletes. Open a different report and come back - verify it does not come back.
Send another comment
Go offline
Delete the comment.
Verify that the comment appears with strikethrough
Come back online
Verify that the comment deletes. Open a different report and come back - verify it does not come back.
Go offline
(web) open the network tab in the dev tools and clear the requests
Send a comment
Delete the comment
Verify that the comment disappears (no strikethrough)
Come back online
(web) Verify that no
AddComment
orDeleteComment
requests were sent. Open a different report and come back - verify the comment does not appear.(web) In the network tab, click on the throttling dropdown, then
add
(web) add a profile with 5-10 seconds of latency (enough time that an
AddComment
request will still be pending when you go to delete it)Enable the new profile and clear the network requests
Send a comment and quickly delete it. Verify it appears and then delete soon thereafter
Verify that the comment is added and then disappears as expected.
Verify that both the
AddComment
andDeleteComment
request are processed.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
Only did screenshots on web for #urgency and because I'm close to the end of my day, and because this is a platform agnostic issue.
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
web.mov
web.mov
MacOS: Desktop