wp-graphql / wp-graphql-smart-cache

Smart Caching & Cache Invalidation for WPGraphQL

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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!

@marco910 I've opened a PR to address this issue: #272

Would love if you were able to confirm that it works as expected for your use cases. 🙏🏻

Works great! Very grateful!

I can also confirm that it's working now. Thanks, @jasonbahl