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

Track and Purge Connections #233

Open
jasonbahl opened this issue Jul 21, 2023 · 0 comments
Open

Track and Purge Connections #233

jasonbahl opened this issue Jul 21, 2023 · 0 comments
Labels
effort: high More than a week type: enhancement Improvements to existing functionality

Comments

@jasonbahl
Copy link
Collaborator

Currently the WPGraphQL Cache Tagging and Cache Invalidation strategy is a bit naiive.

We currently track all nodes that are resolved in any given request and return the Node IDs so the response can be tagged with the node. Then, when nodes are edited or deleted we purge any queries that contained that node.

For connections, we currently track list:$type for when Types are queried as a list. Then when new nodes of that type are published we call purge( 'list:post' ), for example, purging any queries that had queried for a list of posts.

In the v1.14.5 release, we dropped nested list:$type tracking for non-root queries.

i.e.

{
  user( id: 123 ) {
    posts {
      nodes {
        id
        title
      }
    }
  }
}

Would have previously been tagged with list:post and thus would have been purged any time any post were published, not just when a post associated with user:123 were published. This lead to a lot of over-purging and lead to the 1.14.5 release, where nested connections/list fields no longer returned list:$type

So now, this query above will be tagged with the user:123 node Id, but will not be tagged with the list:posts key.

This means, however, that when a new post is published, even one written by user:123 the query remains cached.

So, we traded significant over-purging for missing some purges.

We could add a purge( 'user:123' ) call to the publish post event, but that too might have unintended side-effects.

For example, calling purge( 'user:123' ) would purge the query above, but would also purge queries such as:

query GetPostByUri( $uri: String! ) {
  post( id: $uri idType: URI ) {
    id
    title
    author {
      node {
        id
        name
      }
    }
  }
}

This query would be cached for every unique url for a post, and would be tagged with the author's Node ID.

If we call purge( 'user:123' ) any time user 123 publishes a new post, then we could potentially be purging hundreds or thousands of posts unnecessarily.

Proposal (needs more thought / digging)

I believe there's room for some middle ground with connection tagging.

Instead of generic list:$type tagging, we can get more granular with our tagging.

For example we could possibly to something like user:123::Post to indicate a connection between user:123 and the Post type.

Then, when a post is published by user:123 we could call purge( 'user:123::Post' ) thus purging any queries that had resolved a connection between the specific user and that Type of node.

Considerations

This could lead to header over-stuffing and could lead to some cache tags being skipped.

@jasonbahl jasonbahl added type: enhancement Improvements to existing functionality effort: high More than a week labels Sep 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
effort: high More than a week type: enhancement Improvements to existing functionality
Projects
None yet
Development

No branches or pull requests

1 participant