Skip to content
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

RTK-Query - keepUnusedDataFor has problems with very high values #2535

Closed
nimajnebp opened this issue Jul 22, 2022 · 10 comments · Fixed by #2595
Closed

RTK-Query - keepUnusedDataFor has problems with very high values #2535

nimajnebp opened this issue Jul 22, 2022 · 10 comments · Fixed by #2595
Labels
bug Something isn't working

Comments

@nimajnebp
Copy link

nimajnebp commented Jul 22, 2022

I use RTK-Query for api fetches in my project, and I've met with an issue I can't fully understand.

Use Case:

I open a modal, once the modal mounts, I call a query endpoint by the auto generated query hook. So this will trigger a couple of actions, first "api/executeQuery/pending", then "api/executeQuery/fulfilled", so far so good, everything works as expected, data is in store, we are happy. Then I close the modal, component unmounts, this triggers yet another 2 actions, first "api/subscriptions/unsubscribeQueryResult", then "api/queries/removeQueryResult", this will do what it says, remove the data, because there are no more subscribers.

So my goal is to prolong the cache time of that query result, because this modal is being opened frequently, so going through the docs I see "keepUnusedDataFor" option which in theory would do just I what I want.

Reference from docs:
"Once the subscription is removed (e.g. when last component subscribed to the data unmounts), after an amount of time (default 60 seconds), the data will be removed from the cache. The expiration time can be configured with the keepUnusedDataFor"

As I understand this, for my use-case, the query that ran when the modal was open, should be kept, for at least 60 seconds, till after the component unmounts. But in reality, the "api/subscriptions/unsubscribeQueryResult" and the "api/queries/removeQueryResult" actions run immediately after modal unmounts, there is no 60 seconds delay. I've tried setting it to longer, but was cheap shot obviously, I miss out on something or just not understanding clearly how this should behave.

Ideas?

Package versions:
"redux": "^4.0.5",
"react-redux": "^7.2.2",
"redux-thunk": "^2.3.0",
"@reduxjs/toolkit": "^1.8.3",

@phryneas
Copy link
Member

That is how it should work. Are you running any mutation that would invalidate that query? Because then instead of refetching it (which would refetch data that is potentially never being displayed again), that data is removed from cache entries without subscribers.

@nimajnebp
Copy link
Author

That is how it should work. Are you running any mutation that would invalidate that query? Because then instead of refetching it (which would refetch data that is potentially never being displayed again), that data is removed from cache entries without subscribers.

No mutation.

But then this sentence, - "Once the subscription is removed (e.g. when last component subscribed to the data unmounts), after an amount of time (default 60 seconds), the data will be removed from the cache." - is just not clear at all about the behaviour IMO.

The lifecycle should be: Component unsubscribes (unmounts) -> Wait 60 seconds -> Remove data.
What in reality is: Component unsubscribes (unmounts) -> Remove data. // where did the 60 seconds play part here?

@phryneas
Copy link
Member

The lifecycle should be: Component unsubscribes (unmounts) -> Wait 60 seconds -> Remove data.

Yes, that's what it should be and usually is and that's why I'm asking you for a reproduction ;)

@nimajnebp
Copy link
Author

nimajnebp commented Jul 22, 2022

The lifecycle should be: Component unsubscribes (unmounts) -> Wait 60 seconds -> Remove data.

Yes, that's what it should be and usually is and that's why I'm asking you for a reproduction ;)

export const weatherApi = createApi({
  reducerPath: "weatherApi",
  baseQuery: fetchBaseQuery({ baseUrl }),
  keepUnusedDataFor: 3600000, // 1 hour cache time
  endpoints: (builder) => ({
    getCities: builder.query({
      query: () => `locations/v1/topcities/50?apikey=${apiKey}`,
    }),
    getForecast: builder.query({
      query: (locationKey) =>
        `forecasts/v1/daily/1day/${locationKey}?apikey=${apiKey}`,
    }),
  }),
});
function Modal() {
  const cities = weatherApi.useGetCitiesQuery();
  return <div>...</div>;
}

Screenshot 2022-07-22 at 11 53 53

@phryneas
Copy link
Member

Please make a CodeSandbox that actually shows the problem - I won't be able to see the problem from snippets.

This example is very similar to whay you are doing and works perfectly: https://codesandbox.io/s/stoic-pateu-4w8vdr

@nimajnebp
Copy link
Author

Please make a CodeSandbox that actually shows the problem - I won't be able to see the problem from snippets.

This example is very similar to whay you are doing and works perfectly: https://codesandbox.io/s/stoic-pateu-4w8vdr

https://codesandbox.io/s/rtk-query-keepunuseddatafor-ctqxgc

@phryneas
Copy link
Member

Ah. It works if you use a realistic value like 3600 - the value is in seconds, not milliseconds, so you're specifying 41 days here.

Of course, that should still work as well so I'm a bit confused. 🤔

Further reserach shows that browsers get an integer overflow with timers over 20 days: https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value

I guess we'll have to add a check for that.

@phryneas phryneas changed the title RTK-Query - keepUnusedDataFor - Doesn't work as expected. RTK-Query - keepUnusedDataFor has problems with very high values Jul 23, 2022
@phryneas phryneas added the bug Something isn't working label Jul 23, 2022
@phryneas phryneas added this to the 1.9 milestone Jul 23, 2022
@nimajnebp
Copy link
Author

Ah. It works if you use a realistic value like 3600 - the value is in seconds, not milliseconds, so you're specifying 41 days here.

Of course, that should still work as well so I'm a bit confused. 🤔

Further reserach shows that browsers get an integer overflow with timers over 20 days: https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value

I guess we'll have to add a check for that.

You are right, I was misreading the description about the unit, and the number was too great. Thank you very much for spotting it.

@markerikson
Copy link
Collaborator

Hmm. This is labeled as a 1.9 item, but we should put this out as a 1.8.x bugfix before then.

@yash-vaddi
Copy link

Hello ,
In RTK Query The KeepUnusedDataFor Time Is 60 Second To Keep Data In Cache.
You Can See In Demo.
Screencast from 13-07-23 03:30:56 PM IST.webm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants