-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
useQuery
: delay unsubscribe to fix race conditions
#10629
Conversation
🦋 Changeset detectedLatest commit: 60dd769 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@@ -1746,26 +1755,37 @@ describe('useQuery Hook', () => { | |||
expect(result.current.data).toBe(undefined); | |||
|
|||
await waitFor(() => { | |||
expect(result.current.loading).toBe(false); |
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 test tested if a single query was made but never tested if there was any actual polling going on - that's why we never were aware of this bug.
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.
Thanks for fixing this and adding tests @phryneas!
test.each< | ||
[ | ||
fetchPolicy: WatchQueryFetchPolicy, | ||
initialQueryValue: TestQueryValue | undefined, | ||
shouldFetchOnFirstRender: boolean, | ||
shouldFetchOnSecondRender: boolean | ||
] | ||
>([ | ||
[`cache-first`, emptyData, true, false], | ||
[`cache-first`, cacheData, false, false], | ||
[`cache-only`, emptyData, false, false], | ||
[`cache-only`, cacheData, false, false], | ||
[`cache-and-network`, emptyData, true, false], | ||
[`cache-and-network`, cacheData, false, false], | ||
[`network-only`, emptyData, true, false], | ||
[`network-only`, cacheData, false, false], | ||
[`no-cache`, emptyData, true, false], | ||
[`no-cache`, cacheData, true, false], | ||
[`standby`, emptyData, false, false], | ||
[`standby`, cacheData, false, false], | ||
])( | ||
"fetchPolicy %s, cache: %p should fetch during `disableNetworkFetches`: %p and after `disableNetworkFetches` has been disabled: %p", | ||
async (policy, initialQueryValue, shouldFetchOnFirstRender, shouldFetchOnSecondRender) => { |
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 love this style of writing lists of test cases! Please feel free to refactor any other places where you see something similar but uglier, if you come across any.
// Do the "unsubscribe" with a short delay. | ||
// This way, an existing subscription can be reused without an additional | ||
// request if "unsubscribe" and "resubscribe" to the same ObservableQuery | ||
// happen in very fast succession. | ||
return () => setTimeout(() => subscription.unsubscribe()); |
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.
Some precedent for this technique:
if (sub) setTimeout(() => sub.unsubscribe()); |
If the delay between the last unsubscription and the resubscription ever gets longer than the minimum setTimeout
delay, that seems like it could reintroduce this problem unpredictably, but the consequences would be the same as without this change.
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.
Yup, this is mostly good if the unsubscribe and subscribe are called synchronously - for everything else, it's just a band-aid - but at some level of delay, a refetch might actually be intended.
Thanks for fixing this one @phryneas! |
commit 72b222e Merge: def116b afccbdb Author: Gaston Morixe <gaston@gastonmorixe.com> Date: Fri Mar 10 18:23:57 2023 -0300 Merge branch 'main' into gm/fix/merge-function-called-before-deepmerge-sep202022 commit afccbdb Author: Trevin Avery <TrevinAvery@gmail.com> Date: Wed Mar 8 11:18:47 2023 -0800 Fix snapshot with non-ascii character (apollographql#10611) commit 02605bb Author: Lenz Weber-Tronic <lorenz.weber-tronic@apollographql.com> Date: Wed Mar 8 10:18:29 2023 +0100 `useQuery`: delay unsubscribe to fix race conditions (apollographql#10629) * add test for current behavior * add failing test for polling * slightly delay unsubscribe * adjust tests to new behavior commit 355dce8 Author: Jeff Auriemma <bignimbus@users.noreply.github.com> Date: Tue Mar 7 11:47:45 2023 -0500 Bump date in roadmap commit 3b504f7 Author: Jeff Auriemma <bignimbus@users.noreply.github.com> Date: Tue Mar 7 11:41:42 2023 -0500 Update dates and notes for upcoming releases commit c4daaf6 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Mar 6 15:34:20 2023 -0500 chore(deps): update dependency graphql-ws to v5.12.0 (apollographql#10625) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Alessia Bellisario <alessia@apollographql.com> commit 88993a2 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Mar 6 14:02:53 2023 -0500 chore(deps): update dependency @types/node to v18.14.6 (apollographql#10622) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit aa81522 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Mon Mar 6 14:01:45 2023 -0500 chore(deps): update dependency rimraf to v4.3.0 (apollographql#10623) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e4fb0ca Author: Henry Q. Dineen <henryqdineen@users.noreply.github.com> Date: Fri Mar 3 12:14:58 2023 -0500 remove obsolete @types/fast-json-stable-stringify dev dep (apollographql#10617) commit 260914a Author: Trevin Avery <TrevinAvery@gmail.com> Date: Fri Mar 3 08:43:01 2023 -0800 Update batchLink tests to use fake timers (apollographql#10612) * Update batchLink tests to use fake timers * fix: refactor batch interval test to support fake timers --------- Co-authored-by: Alessia Bellisario <alessia@apollographql.com> commit ebee40b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Fri Mar 3 10:49:59 2023 -0500 chore(deps): update dependency eslint to v8.35.0 (apollographql#10613) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 5161f09 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Mar 2 17:41:57 2023 -0700 chore(deps): update dependency @types/node to v18.14.4 (apollographql#10602) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit 7823843 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Mar 2 17:31:57 2023 -0700 chore(deps): update cimg/node docker tag to v19.7.0 (apollographql#10605) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit f8fed6b Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Mar 2 16:59:56 2023 -0700 chore(deps): update dependency @babel/parser to v7.21.2 (apollographql#10606) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e9f0dd5 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Mar 2 16:45:50 2023 -0700 chore(deps): update dependency @types/glob to v8.1.0 (apollographql#10607) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit bbb04b0 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Mar 2 16:32:10 2023 -0700 chore(deps): update dependency terser to v5.16.5 (apollographql#10603) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit f9868b8 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Mar 2 16:03:25 2023 -0700 chore(deps): update dependency @typescript-eslint/eslint-plugin to v5.54.0 (apollographql#10608) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit ef13979 Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Mar 2 15:43:19 2023 -0700 chore(deps): update jaywcjlove/github-action-package action to v1.3.1 (apollographql#10604) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit e6d552f Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Thu Mar 2 15:33:26 2023 -0700 chore(deps): update dependency @typescript-eslint/parser to v5.54.0 (apollographql#10609) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> commit def116b Merge: a32e0d2 6bd651b Author: Gaston Morixe <gaston@gastonmorixe.com> Date: Tue Sep 20 11:57:40 2022 -0500 Merge tag 'v3.6.8' into gm/fix/merge-function-called-before-deepmerge-sep202022 commit a32e0d2 Author: Gaston Morixe <gaston@gastonmorixe.com> Date: Tue Mar 8 17:38:31 2022 -0300 custom version commit 42a20f8 Author: Gaston Morixe <gaston@gastonmorixe.com> Date: Tue Mar 8 17:07:12 2022 -0300 increatese maxSize to 28.65 commit 045a9d5 Author: Gaston Morixe <gaston@gastonmorixe.com> Date: Mon Mar 7 18:35:02 2022 -0300 Run Policies's merge before cache merge adds test fix formatting
/release:pr |
/release:pr |
A new release has been made for this PR. You can install it with |
This changes the behavior found in #10540 and fixes #9819.
Checklist:
Discussion
This change significantly changes how
disableNetworkFetches
behaves in some situations:Assuming a scenario where
disableNetworkFetches
istrue
, a component usinguseQuery
renders,disableNetworkFetches
changes tofalse
and the component usinguseQuery
rerenders, we have this behavior change:The good
Where before,
cache-and-network
,network-only
, andno-cache
ran their queries twice on an empty cache, those now only run on the first render.This is generally desirable behavior.
The same happens for
no-cache
when a cache entry is present: two requests are down to one.The questionable:
Before,
cache-and-network
andnetwork-only
did not run their queries when a cache entry was found but ran a query oncedisableNetworkFetches
was turned on (and the component rerendered for any reason).Now they don't run that network request.
That behavior was flimsy (it only occurred when the component was rerendered for any reason), but I can think of good and bad arguments for why it should be the expected behavior - our docs don't help me there.
So the question is: are we okay with this change?
If yes: Great, let's merge this and call it a day.
But if we would want network requests to be triggered once
disableNetworkFetches
flips fromtrue
tofalse
, we might revisit something along the lines of #8721