-
Notifications
You must be signed in to change notification settings - Fork 1.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: ensure initCache setter function stays within bounds of subscriptions #2411
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 296a994:
|
Thanks for the PR! Can you add a test for this? |
It's quite challenging making a test that reproduce the original problem, as it looks to me as a race condition when two or more caches are initiated at the same time with the same key for the global store, but different number of subscriptions. I can add a unit test for the |
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 problem may invovle some implementaion details of react which makes it hard to create a test case.
When sub[i] is called, React will be told to update. If the update happened immediately and cause some swr hooks umounted, then sub will be changed and it is not safe to call sub[i] anymore
However when i try to reproduce this problem, i noticed that the update won't happen right way. It seems that all the updates will be batched.
I think we could merge this now and add test case later.
_internal/utils/cache.ts
Outdated
if (subscriptions[key]) { | ||
// Make a copy of subscriptions to avoid mutations of subscriptions to affect | ||
// the array while looping | ||
const subs = subscriptions[key].slice() |
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.
const subs = subscriptions[key].slice() | |
const subs = subscriptions[key] | |
if (subs) { | |
for (const fn of subs) { | |
fn(value, prev) | |
} | |
} |
Maybe we could use for of
here, so it don't need a extra copy of subs here ?
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.
Yeah, that should probably achieve the same. I can update on Monday as soon as I have access to a computer! Thanks for feedback and attention!
[](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [swr](https://swr.vercel.app) ([source](https://togithub.com/vercel/swr)) | [`2.0.3` -> `2.0.4`](https://renovatebot.com/diffs/npm/swr/2.0.3/2.0.4) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>vercel/swr</summary> ### [`v2.0.4`](https://togithub.com/vercel/swr/releases/tag/v2.0.4) [Compare Source](https://togithub.com/vercel/swr/compare/v2.0.3...v2.0.4) #### Patches - build: fix release job condition by [@​huozhi](https://togithub.com/huozhi) in [https://github.com/vercel/swr/pull/2392](https://togithub.com/vercel/swr/pull/2392) - types: fix some mutation type issue by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2421](https://togithub.com/vercel/swr/pull/2421) - fix: Error retry should be handled by global revalidator instead of local revalidation function by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2415](https://togithub.com/vercel/swr/pull/2415) - fix: ensure initCache setter function stays within bounds of subscriptions by [@​lfbergee](https://togithub.com/lfbergee) in [https://github.com/vercel/swr/pull/2411](https://togithub.com/vercel/swr/pull/2411) #### Misc - test: stream ssr e2e by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2395](https://togithub.com/vercel/swr/pull/2395) - test: fix an act warning by [@​koba04](https://togithub.com/koba04) in [https://github.com/vercel/swr/pull/2403](https://togithub.com/vercel/swr/pull/2403) #### New Contributors - [@​lfbergee](https://togithub.com/lfbergee) made their first contribution in [https://github.com/vercel/swr/pull/2411](https://togithub.com/vercel/swr/pull/2411) **Full Changelog**: vercel/swr@v2.0.3...v2.0.4 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/Unleash/unleash). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4xNTkuMCIsInVwZGF0ZWRJblZlciI6IjM0LjE1OS4wIn0=--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
[](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [swr](https://swr.vercel.app) ([source](https://togithub.com/vercel/swr)) | [`2.0.3` -> `2.1.0`](https://renovatebot.com/diffs/npm/swr/2.0.3/2.1.0) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>vercel/swr</summary> ### [`v2.1.0`](https://togithub.com/vercel/swr/releases/tag/v2.1.0) [Compare Source](https://togithub.com/vercel/swr/compare/v2.0.4...v2.1.0) #### Feature - Subscription mode by [@​huozhi](https://togithub.com/huozhi) in [https://github.com/vercel/swr/pull/1263](https://togithub.com/vercel/swr/pull/1263) - parallel option for useSWRInfinite by [@​koba04](https://togithub.com/koba04) in [https://github.com/vercel/swr/pull/2404](https://togithub.com/vercel/swr/pull/2404) Checkout [subscription docs](https://swr.vercel.app/docs/subscription) and [useSWRInfinite parallel fetching docs](https://swr.vercel.app/docs/pagination#parallel-fetching-mode) for more details #### Patches - fix: use the latest config in useSWRMutation by [@​koba04](https://togithub.com/koba04) in [https://github.com/vercel/swr/pull/2468](https://togithub.com/vercel/swr/pull/2468) - Fix: type support for suspense and fallbackData([#​2396](https://togithub.com/vercel/swr/issues/2396)) by [@​taro-28](https://togithub.com/taro-28) in [https://github.com/vercel/swr/pull/2452](https://togithub.com/vercel/swr/pull/2452) - Error should be reset when new data comes by [@​huozhi](https://togithub.com/huozhi) in [https://github.com/vercel/swr/pull/2472](https://togithub.com/vercel/swr/pull/2472) - fix: avoid creating new snapshot if cache is not updated at client during streaming by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2475](https://togithub.com/vercel/swr/pull/2475) - refactor: initialize the cache only on first access by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2479](https://togithub.com/vercel/swr/pull/2479) #### Misc - ci: fix publish workflow by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2453](https://togithub.com/vercel/swr/pull/2453) - ci: faster e2e test by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2428](https://togithub.com/vercel/swr/pull/2428) - test: add a test for keepPreviousData without changing key by [@​koba04](https://togithub.com/koba04) in [https://github.com/vercel/swr/pull/2470](https://togithub.com/vercel/swr/pull/2470) - Always assume subscriptions will return sub count from current key by [@​huozhi](https://togithub.com/huozhi) in [https://github.com/vercel/swr/pull/2460](https://togithub.com/vercel/swr/pull/2460) - test: Fix flaky e2e test by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2476](https://togithub.com/vercel/swr/pull/2476) - chore: Add subscription example by [@​huozhi](https://togithub.com/huozhi) in [https://github.com/vercel/swr/pull/2480](https://togithub.com/vercel/swr/pull/2480) #### New Contributors - [@​taro-28](https://togithub.com/taro-28) made their first contribution in [https://github.com/vercel/swr/pull/2452](https://togithub.com/vercel/swr/pull/2452) **Full Changelog**: vercel/swr@v2.0.4...v2.1.0 ### [`v2.0.4`](https://togithub.com/vercel/swr/releases/tag/v2.0.4) [Compare Source](https://togithub.com/vercel/swr/compare/v2.0.3...v2.0.4) #### Patches - build: fix release job condition by [@​huozhi](https://togithub.com/huozhi) in [https://github.com/vercel/swr/pull/2392](https://togithub.com/vercel/swr/pull/2392) - types: fix some mutation type issue by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2421](https://togithub.com/vercel/swr/pull/2421) - fix: Error retry should be handled by global revalidator instead of local revalidation function by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2415](https://togithub.com/vercel/swr/pull/2415) - fix: ensure initCache setter function stays within bounds of subscriptions by [@​lfbergee](https://togithub.com/lfbergee) in [https://github.com/vercel/swr/pull/2411](https://togithub.com/vercel/swr/pull/2411) #### Misc - test: stream ssr e2e by [@​promer94](https://togithub.com/promer94) in [https://github.com/vercel/swr/pull/2395](https://togithub.com/vercel/swr/pull/2395) - test: fix an act warning by [@​koba04](https://togithub.com/koba04) in [https://github.com/vercel/swr/pull/2403](https://togithub.com/vercel/swr/pull/2403) #### New Contributors - [@​lfbergee](https://togithub.com/lfbergee) made their first contribution in [https://github.com/vercel/swr/pull/2411](https://togithub.com/vercel/swr/pull/2411) **Full Changelog**: vercel/swr@v2.0.3...v2.0.4 </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/kula-app/OnLaunch). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNS44LjMiLCJ1cGRhdGVkSW5WZXIiOiIzNS44LjMifQ==-->
This PR closes #2357, by creating a copy of the
subscriptions[key]
array in thesetter
function forinitCache
. By doing this we avoid an intermittent bug wheresubscriptions[key]
is mutated while the for-loop is running, potentially causing an out of bounce lookup.By copying the object, mutations of the original object will not affect the
setter
function while executing. Alternatively we could lock write operation while running the read operation. Or use a different iterator method, that make it's own copy instead of a vanilla for-loop.This is somewhat hard bug to reproduce, as it's highly intermittent.