-
Notifications
You must be signed in to change notification settings - Fork 14
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
Unable to purge post after changing status from Draft
to Published
#223
Comments
@predaytor do you have GraphQL Object Caching enabled or disabled? Since you're using varnish, make sure to disable the GraphQL Object Caching. Can you confirm that it is disabled when you experience this behavior? |
@jasonbahl, confirm, I have Object Caching disabled. |
@predaytor so if I understand correctly, you're querying for a post by slug, but that post is a draft? So you get a null response and no node ID in the cache key response? How would the client know about that slug if the draft post wasn't already publicly visible? Can you help me understand more about the flow? Are you using authenticated requests to query draft posts? |
@jasonbahl not exactly. The post has a status of But after changing that particular post's status back to Creating a new post (which I assume has no status at all) works fine, all queries get MISS (purge works). So the problem is only with a query for a specific post (querying by slug in the example) that has a status of Authorization headers are not used during request execution (using Insomnia GET requests). |
@predaytor ya, so my question is, how is the client making the query for the draft post by slug if the slug isn't known yet? |
@jasonbahl, but I'm assuming that after changing the status to |
Ya, so it seems like you're querying for a draft post by slug:
Since it's a draft, the query gets cached with So, when the project is published and So, my question remains, how does the client know about the "draft-project" slug if the draft project isn't publicly queryable? Like what path is leading the client codebase to executing queries for draft projects by slug if the slug isn't actually known publicly because it's still a draft? |
This is an interesting scenario, though. Perhaps we need to track nodes that are resolved under the hood but not returned. Like in this case, the draft node ( But, perhaps we need to output those un-returned Nodes in the X-GraphQL-Keys for cases like this where a node transitions from draft to published and back 🤔 |
Oh, I get it. Will try to investigate more! |
I have a page with a list of all projects with links to each of them ( I use varnish I've also enabled prefetching (using the Astro framework) which pre-renders the HTML, styles, etc. of a particular page on hover in the background (ie our Or the user already knows a certain link to the project (in bookmarks, etc.). So, if the post is |
@predaytor ok, thanks for the info. I think we might need to consider tracking ids of nodes that are resolved but not returned, as proposed here: #223 (comment) 🤔 |
fyi, I'm actively working on this. I think I might have a solution. Will try to get an update out soon! 🤞🏻 |
Thanks 🙏 |
Hi @jasonbahl, is there any update on this bug? I am having the same issue with draft and scheduled posts. |
I thought I had a solution in July, but didn't quite work the way I hoped so it needs to be re-visited. Definitely interested in contributions if anyone has ideas on how to support this scenario. Since draft posts are not public, their IDs are never exposed, so their ID is not tracked in the X-GraphQL-Keys, and therefore a cached query for a draft post will not be tagged with the ID of the post, and will not be purged from the cache when that post is published and I'm not sure the best way to handle this. We could maybe output the IDs of nodes that aren't public in the X-GraphQL-Keys header potentially, allowing for a query for a draft that returns |
My current thought is that if a query asks for node(s) and no nodes are returned, we could return a 🤔 |
Another idea is that we could return a This would allow queries with null responses to remain cached until some event purges them, which would likely benefit the server compared to not caching at all. 🤔 i.e. {
nodeByUri( uri: "non-existing-page" ) { ... }
} would be cached. Subsequent hits to that query would be Whenever a publish event (publishing a post being the most common one) we'd call So it's a balance again of allowing these types of queries to benefit from caching, but also benefit from being cache miss when potentially related actions have occurred. This also would allow us to NOT expose IDs of non-public nodes in headers, as ideated here: #223 (comment) |
👋🏻 This filter can be used: add_filter( 'graphql_response_headers_to_send', function( $headers ) {
$request = \WPGraphQL\Router::get_request();
if ( ! $request instanceof \WPGraphQL\Request ) {
return $headers;
}
$query_analyzer = $request->get_query_analyzer();
if ( empty( $query_analyzer->get_runtime_nodes() ) ) {
$headers['Cache-Control'] = 'no-cache, must-revalidate';
}
return $headers;
}, 20, 1 ); This will return a 'no-cache, must-revalidate' header if no nodes are resolved in the request. Trade OffsWith this filter in place queries for things that are not nodes, such as WordPress settings, would not be cached with this strategy. However, currently settings are not being properly invalidated once they are cached. . .so whether this is addressed or not there's a "bug" with querying settings and caching at the moment. Related issues: |
Thanks! |
When the status of a post changes from
Draft
toPublished
, the query for specific post (project
in the example) does not have an associated key as it did before. That is, we can't invalidate the keys, it will always beHIT
until theCache-Control
expires.Even updating the data in such a post does not purge anything because it no longer has an associated key.
All other events are working fine, as far as the post was not in
Draft
state (or restored from trash) and then turned toPublished
again.Querying a completely new created post works fine.
Testing custom
Project
Post type (single post is present):Query example (testing via Insomnia):
(projects)
http://localhost/wp/graphql?query={projects{edges{node{id,title}}}}
(project)
http://localhost/wp/graphql?query={project(id:"our-slug",idType:SLUG){id,title}}
First run:
projects query -> MISS
c42fab2f4dc81c75f2e4b6180f1b5d0cdfd0fb22f863231bebab2f2a02bd3e10 graphql:Query list:project cG9zdDozNDU=
project query -> MISS
51404600df1e2ceed74fbd14251755e4b7958a369dc28ae551d6e5ff2a64831f graphql:Query cG9zdDozNDU=
Change status to
Draft
:projects query -> MISS
c42fab2f4dc81c75f2e4b6180f1b5d0cdfd0fb22f863231bebab2f2a02bd3e10 graphql:Query list:project
project query -> MISS
51404600df1e2ceed74fbd14251755e4b7958a369dc28ae551d6e5ff2a64831f graphql:Query
Change status back to
Published
:projects query -> MISS
c42fab2f4dc81c75f2e4b6180f1b5d0cdfd0fb22f863231bebab2f2a02bd3e10 graphql:Query list:project cG9zdDozNDU=
project query -> HIT
51404600df1e2ceed74fbd14251755e4b7958a369dc28ae551d6e5ff2a64831f graphql:Query
Post is updated:
projects query -> MISS
c42fab2f4dc81c75f2e4b6180f1b5d0cdfd0fb22f863231bebab2f2a02bd3e10 graphql:Query list:project cG9zdDozNDU=
project query -> HIT
51404600df1e2ceed74fbd14251755e4b7958a369dc28ae551d6e5ff2a64831f graphql:Query
New post is published:
projects query -> MISS
c42fab2f4dc81c75f2e4b6180f1b5d0cdfd0fb22f863231bebab2f2a02bd3e10 graphql:Query list:project cG9zdDoxMDM4 cG9zdDozNDU=
project query (new post)-> MISS
d9154add95f1fabfe6844d1716c23cd1b7ef0c4ca43d1ba867219e16859a88ed graphql:Query cG9zdDoxMDM4
purge-varnish-cache.php
:default.vcl
Varnish config:The text was updated successfully, but these errors were encountered: