Invalidate cache when menu items are updated
marco910 opened this issue · comments
Currently, WPGraphQL Smart Cache does only "track" changes to posts, comments and some other types and purges the cached items related to those changes. This does not work with menu items and menus for queries like this one:
{
menuItems(where: {location: MAIN_NAV}) {
nodes {
databaseId
label
}
}
}
A nice feature for future version (or a simple DIY workaround) would be to add cache purging to the plugin when menu items or menu get updated.
@marco910 WPGraphQL Smart Cache purges when menu items change. see: https://github.com/wp-graphql/wp-graphql-smart-cache/blob/main/src/Cache/Invalidation.php#L112-L114
Can you share some examples of queries you've executed and then actions in the admin that didn't cause queries to purge when you would have expected it to purge?
The more detailed steps to reproduce, the better. 🙏🏻
@jasonbahl I tested this with some simple queries like menus
and menuItems
which were cached from my Varnish cache. I tried to purge the cache using a custom purge_varnish()
function, which handles the purging of my Varnish cache internally.
As mentioned in the docs of WPGraphQL Smart Cache, there is the action graphql_purge
which can be used to call the custom purge function. I'm using that like so:
add_action('graphql_purge', array(new My_Class(), 'purge_varnish'), 10, 3);
This didn't purge the cache when a menu or nav item was updated. So I had to add the following actions in addition:
wp_update_nav_menu
wp_delete_nav_menu
wp_update_nav_menu_item
wp_delete_nav_menu_item
After adding them, the cache was also cleared when updating a menu or menu item.
Can you describe how you implement this, passing $purge_keys for these actions?
function purge_varnish_cache($purge_keys) { ... }
// Add an action hook for purging cache using WP GraphQL Smart Cache plugin
add_action('graphql_purge', "purge_varnish_cache", 10, 1);
@predaytor Sure, here is how I implemented this:
In the action I'm calling a custom class function called purge_varnish
.
add_action('graphql_purge', array(new My_Class(), 'purge_varnish'), 10, 3);
The function purge_varnish
is defined inside the class and takes the $purge_keys
param which is then passed to the Varnish cache invalidation. This is just a simple cUrl operation which purges the local Varnish cache by using the xKey module of Varnish.
When using this with posts and pages, everything works fine, but not with menus, menu items and users. This is why I had to implement custom actions for those.
Hey @marco910, can you share some examples of queries you've executed and then actions in the admin that didn't cause queries to purge when you would have expected it to purge?
This will help us reproduce this.
Hey @josephfusco, here a few examples of queries, that didn't work as expected.
Menu Items (same for similar menu/menu items queries)
{
headerNavItems: menuItems(where: {location: HEADER_NAV}, first: 100) {
nodes {
id: databaseId
title
target
path
parentDatabaseId
label
}
}
}
Single user
query ($slug: ID!) {
user(id: $slug, idType: SLUG) {
databaseId
name
firstName
lastName
slug
}
}
@marco910 I was able to reproduce this today.
Using your provided query:
{
headerNavItems: menuItems(where: {location: PRIMARY}, first: 100) {
nodes {
id: databaseId
title
target
path
parentDatabaseId
label
}
}
}
I executed a non-authenticated GET request.
I refreshed several times and saw X-Cache: HIT: 8
I then re-arranged menu items and executed the query again. The query results remained unchanged and the X-Cache: HIT
count increased.
I would expect for the response to have been invalidated and an X-Cache: MISS
with the correct, re-ordered menu items to be returned.
I've marked this actionable and we'll work on a fix!
Works great! Very grateful!
I can also confirm that it's working now. Thanks, @jasonbahl