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

experimental_createPersister is not cleaning up after itself #7049

Open
rklomp opened this issue Mar 7, 2024 · 1 comment
Open

experimental_createPersister is not cleaning up after itself #7049

rklomp opened this issue Mar 7, 2024 · 1 comment

Comments

@rklomp
Copy link
Contributor

rklomp commented Mar 7, 2024

Describe the bug

experimental_createPersister creates a separate storage entry for each cache item.
If this item is not accessed anymore it will never be cleaned up and stays in storage indefinitely.

Your minimal, reproducible example

https://stackblitz.com/edit/github-1zcjsn?file=src%2Findex.jsx

Steps to reproduce

  1. make a query that is persisted.
  2. Never do that same query again
  3. Item will stay in storage indefinitely

Expected behavior

I expect there is some kind of garbage collection.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

Android, React Native

Tanstack Query adapter

react-query

TanStack Query version

5.25.0

TypeScript version

No response

Additional context

My quick solution for now

export function usePersistorGarbageCollect() {
    // Add AsyncStorage garbage collect
    useEffect(() => {
        const gcPersitor = async () => {
            try {
                //Remove the old offline cache
                AsyncStorage.removeItem("REACT_QUERY_OFFLINE_CACHE");

                const storage_keys = await AsyncStorage.getAllKeys();
                const keys = storage_keys.filter((key) =>
                    key.startsWith("tanstack-query-")
                );
                const items = await AsyncStorage.multiGet(keys);
                const expired_items = items.filter(
                    ([_, value]) =>
                        Date.now() - JSON.parse(value).state.dataUpdatedAt >
                        QUERY_GC_TIME
                );

                const expired_keys = expired_items.map((item) => item[0]);
                console.log("gcPersitor will cleanup", expired_keys);

                await AsyncStorage.multiRemove(expired_keys);
            } catch (e) {
                console.log("gcPersitor", e);
            }
        };

        gcPersitor();
    }, []);
}
@hirbod
Copy link
Contributor

hirbod commented Apr 8, 2024

Let's link the discussion as well #6788:

And I also have two code examples here: https://gist.github.com/hirbod/bc1538990d1b47419c3cb1f6622f7625

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants