-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Option to pause Polling when window Unfocused #2516
Comments
Hmm. actually, looking at the code... if (
api.internalActions.updateSubscriptionOptions.match(action) ||
api.internalActions.unsubscribeQueryResult.match(action)
) {
updatePollingInterval(action.payload, mwApi)
}
// later
const lowestPollingInterval = findLowestPollingInterval(subscriptions)
if (!Number.isFinite(lowestPollingInterval)) {
cleanupPollForKey(queryCacheKey)
return
} so maybe dispatching |
That would get it out of sync with the hook. It's currently not supported, but a well thought-out PR would be welcome :) |
I would love to be able to contribute in some way, but this one might be out of my wheelhouse. I have solved my issue in the short term by creating actions for the Focus events and then setting state in const onFocus = createAction("__rtkq/focused");
const onFocusLost = createAction("__rtkq/unfocused"); I see these actions are exported here:
But I was unable to import them and use them in my project (NextJS). VSCode is happy to import them like this import {
onFocus,
onFocusLost,
} from "@reduxjs/toolkit/dist/query/core/setupListeners"; Typescript is happy with it but NextJS isn't. Running
While creating my own actions has worked, i'm not a fan of the idea long term as it depends on RTK not changing the ActionType at some point in the future. Is it possible to get these Actions exported so they can be used by projects as needed? Now this is something that I could create a PR for if you agree it is a worthy exercise :-). Thanks for your help. |
Chiming in to say I have similar issues with the imports of Also pausing polling seems like a really good feature as browsers have said they aren't happy if apps keep doing it whilst unfocused. |
I am interested in contributing here, but I want to clarify what the preferred behavior by the team is first. These are my initial thoughts on it, but I may be off the mark and missing something crucial about RTKQuery as this is my first real dive into the source. Options considered:specific option for polling only to check if the configSlice considers the document focused or not before sending a refetch:If the intention is to maintain the actual polling hooks functionality and interval, but just to block any actual refetch happening while the window is unfocused. Then I think simply adding a check before the actual refetch is dispatched could act as a pause while keeping the poll synced with the hook. I am unsure if the best way to pass this option would be through the createAPI definition or through the hook as it is only impacting polling in this implementation so I am just showing a snippet of the implementation idea rather than the actual option handling function startNextPoll({
queryCacheKey
}, api2) {
const state = api2.getState()[reducerPath];
const querySubState = state.queries[queryCacheKey];
// added boolean that takes from the config slice already tracking when the window is focused or unfocused
const isFocused = state.config.focused;
const subscriptions = internalState.currentSubscriptions[queryCacheKey];
if (!querySubState || querySubState.status === "uninitialized" /* uninitialized */)
return;
const lowestPollingInterval = findLowestPollingInterval(subscriptions);
if (!Number.isFinite(lowestPollingInterval))
return;
const currentPoll = currentPolls[queryCacheKey];
if (currentPoll?.timeout) {
clearTimeout(currentPoll.timeout);
currentPoll.timeout = void 0;
}
const nextPollTimestamp = Date.now() + lowestPollingInterval;
const currentInterval = currentPolls[queryCacheKey] = {
nextPollTimestamp,
pollingInterval: lowestPollingInterval,
timeout: setTimeout(() => {
currentInterval.timeout = void 0;
// Added conditional to not dispatch when unfocused
if (isFocused) {
api2.dispatch(refetchQuery(querySubState, queryCacheKey));
}
}, lowestPollingInterval)
};
} Similar concept to the first but probably requires more rewrite but might be safer to avoid unintended side-effectsHaving the same code as above but instead of just ignoring the dispatch, it can be added to the functionality that refetches a query when Other option but not necessarily in this scopePass an option to all hooks to not refetch server requests when unfocused and can handle it at the First time looking into RTKQ Code so very possible I'm missing something but thats my thoughts to begin |
It might be worth noting that a similar option was added to Apollo Client recently in apollographql/apollo-client#11397, so I suggest also reading the discussion there. |
Thanks, that was helpful read and I took a look at react-query's. That PR in apollo follows a very similar implementation to the first one listed above. Normal polling behaviour continues but the query doesn't dispatch if the flag is set either in the createApi declaration or in the hooks query options. Only difference is I planned on using the already existing focus state from the configSlice, but I think that's inconsequential, unless that handler has some behaviour im unaware of. I'll spin up a PR when I get up in the morning that aims at a query hook option and pollHandler logic and has some tests. I haven't actually looked at what is involved in adding the option to createApi or the actual endpoint definition yet if we want to involve that in this feature too. |
Sorry if this is a silly question, but is it possible to pause polling on a query if the window loses focus.
I currently have a situation where i need to manually
initiate
a query due to some other bad code where i have used prefetch in a horrible hacky way to bypass cache timeout (it's a pagination/inifinate scroll issue that is first on my list for a refactor!!).If there is no "native" way to pause polling, I think it should be possible to create a listener for the focus/unfocus action dispatches and set some state value accordingly.
I have posted here instead of SO in case the functionality could be useful (please close/delete the issue if there is no merit in the idea and I will ask on SO instead).
The text was updated successfully, but these errors were encountered: