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

Async type policies yielding in unexpected garbage collection #9617

Closed
ruiconti opened this issue Apr 22, 2022 · 3 comments
Closed

Async type policies yielding in unexpected garbage collection #9617

ruiconti opened this issue Apr 22, 2022 · 3 comments

Comments

@ruiconti
Copy link

Intended outcome:
I need to wait for perform async operations inside a query type policy's merge/read functions.

e.g.

    Query: {
        fields: {
            someQuery: {
                async read(existing, { cache }) {
                    await writeRelayQuery(cache, existing);
                    return existing;
                },
                async merge(existing, incoming, { cache }) {
                    ...
                    if (shouldRelayWrite) {
                        await writeRelayQuery(cache, mergedValues);
                        return mergedValues;
                    }
                    return mergedValues;
                },
            },
        },
    }

Actual outcome:
The code works i.e. gets executed as expected. However, Apollo garbage collector misbehaves. The value that gets written to ROOT_QUERY.someQuery is a Promise wrapping the underlying cache references. That way, whenever the Apollo's garbage collector is run, it cannot establish a relationship between those wrapped values from the query entry AND the actual cache entries. Yielding in those values being mysteriously being garbage collected.

How to reproduce the issue:
The repro steps:

  1. Define async type policies
  2. Trigger those by writing/reading the query
  3. Capture the values' cache entry ids
  4. Execute client.cache.gc()
  5. Validate that those entries are no longer present in client.cache.data.data

Versions

  System:
    OS: Linux 5.13 Ubuntu 20.04.3 LTS (Focal Fossa)
  Binaries:
    Node: 16.11.1 - ~/.nvm/versions/node/v16.11.1/bin/node
    Yarn: 1.17.3 - /d/outlook/client-web/node_modules/.bin/yarn
    npm: 8.1.0 - ~/.nvm/versions/node/v16.11.1/bin/npm
  npmPackages:
    @apollo/client: ^3.5.8 => 3.5.8
@benjamn
Copy link
Member

benjamn commented Apr 22, 2022

We don’t support async read functions right now, but that’s part of a larger plan to support arbitrary scalar wrapping values (like Date and Promise). Right now, returning a Promise is the same as returning an object with no own properties, which is probably not what you want, but may explain some of the downstream behavior.

@ruiconti
Copy link
Author

Gotcha. If it's not supported, do you think is worth preventing users from hitting this corner scenario? e.g.

  1. mention that this is not supported in the docs
  2. enforce this through the type checker

@jerelmiller
Copy link
Member

Hey @ruiconti, we just released some docs updates that help better describe this behavior (#10282). This is now reflected in our docs.

@benjamn has some more context in this comment about the challenges of using async read functions.

I'm doing a bit of housekeeping right now so I'm going to close this issue as working-as-intended. Do feel free to reopen the issue if you need more from us! 🙏

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants