From 3b835bddca1c530a348e38486f564ec0de20b531 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 9 Nov 2022 16:17:57 -0700 Subject: [PATCH] - v0.3.0 --- README.md | 2 +- docs/cache-invalidation.md | 69 ++++++++++++++++++++++++++++++-------- docs/network-cache.md | 8 +++++ docs/object-cache.md | 6 ++++ docs/persisted-queries.md | 6 ++++ readme.txt | 5 +++ wp-graphql-smart-cache.php | 4 +-- 7 files changed, 83 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 86df6038..b86ed1a5 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ WPGraphQL Smart Cache is a free, open-source WordPress plugin that provides supp ## Docs 📖 - [Overview](#overview) -- [Quick Start](#quick-start) +- [Quick Start](#-quick-start) - Features - [Network Cache](./docs/network-cache.md) - [Object Cache](./docs/object-cache.md) diff --git a/docs/cache-invalidation.md b/docs/cache-invalidation.md index b8d5b3a1..3f9c34c7 100644 --- a/docs/cache-invalidation.md +++ b/docs/cache-invalidation.md @@ -1,38 +1,64 @@ # Cache Invalidation - -## GraphQL Cache Invalidation - One of the primary features of the WPGraphQL Smart Cache plugin is the cache invalidation. -Unlike RESTful APIs which are 1 enpdoint per resource type, GraphQL Queries can be constructed in nearly infinite ways, and can contain resources of many types. +Unlike RESTful APIs where each enpdoint is related to specific resource type, GraphQL Queries can be constructed in nearly infinite ways, and can contain resources of many types. -Thus, caching and invalidating caches can be tricky. +Because of the flexibility that GraphQL offers, caching and invalidating caches can be tricky. This is where WPGraphQL Smart Cache really shines. -WPGraphQL Smart Cache listens for events in WordPress, and purges caches for relevant queries in response to said events. - -### Invalidation Strategy - -When a GraphQL request is executed against the WPGraphQL endpoint, the query is analyzed to determine: +When a GraphQL request is executed against the WPGraphQL endpoint, the query is analyzed at run time to determine: - The operation name of the query - The ID of the query (a hash of the query document string) - What types of nodes were asked for as a list - The individual nodes resolved by the query -The results of this query analysis are returned in the `X-GraphQL-Keys` header. +The results of the GraphQL query are cached and "tagged" with this meta data. +When [relevant events](#tracked-events) occur in WordPress, WPGraphQL Smart Cache emits a `purge` action to purge cached documents with the key(s) called in the purge action. ## Invalidation Strategy -- **Publish Events:** when something is made publicly visible we call purge( `list:$types` ) -- **Update Events:** when something public is updated, we call `purge( $node_id )` -- **Delete Events:** when something public is made not-public, we call `purge( $node_id )` +Below are details about what events trigger purging of the cache, and what tags will be purged in response to the events. + +### Publish Events + +When something in WordPress transitions from not being publicly visible to becoming publicly visible, this will emit a purge event for "lists" of the type. + +For example, publishing a new post will call `purge( 'list:post' )`. + +Creating a new draft post, however, will not emit a `purge` action, as a draft post is not a publicly visible entity. When the draft post is published, it will emit the event. + +Similarly, Creating a user will not emit a `purge` action, as a user with no published content is not considered a publicly visible entity. + +However, a User with no published content publishing their first post as the assigned author will call `purge( 'list:user' )`, as the user will now transition from a private entity (a non-published author) to a public entity (a published author). + +### Update Events + +When a publicly visible entity (such as a published post) is updated, this will emit a `purge( $node_id )` event _and_ a `purge( 'skipped:$type_name )` event. + +Thus, any queries that have been tagged with the id of the node, or with `skipped:$type_name`, will be purged. + +### Delete Events + +When something public is made not-public (converting a published post to draft, or trashing a published post, etc), this will emit a `purge( $node_id )` event _and_ a `purge( 'skipped:$type_name )` event. + +Thus, any queries that have been tagged with the id of the node, or with `skipped:$type_name`, will be purged. + +### Hold up... What's the deal with the `skipped$type_name` thing? + +Because of [header length limitations](https://nodejs.org/en/blog/vulnerability/november-2018-security-releases/#denial-of-service-with-large-http-headers-cve-2018-12121), queries that return an excessive number of nodes might have the headers truncated and replaced with a generic `skipped:$type_name` header. + +For example, if I queried for 500 posts, 500 pages, and 500 users, that would likely cause a header overlfow. This would likely lead to the following headers being returned, instead of each individual node ID that was resolved: `skipped:post`, `skipped:page`, `skipped:user`. + +When a cache is tagged with `skipped:$type_name` it will be purged more often than if it were tagged with the specific node id(s), as editing _any_ node of that type will evict this cache, instead of evicting only when a relevant node in the response has been edited. ## Tracked Events +WPGraphQL Smart Cache tracks events related to all the core WordPress data types, with the current exception of Options. + ### Posts, Pages, Custom Post Types - published @@ -63,4 +89,19 @@ The results of this query analysis are returned in the `X-GraphQL-Keys` header. ### Comments +- inserted +- transition status + ### Settings / Options + +Currently WPGraphQL Smart Cache does not track events related to updating settings. + +There is a lot of nuance to consider. You can read more about this here: [https://github.com/wp-graphql/wp-graphql-smart-cache/issues/158](https://github.com/wp-graphql/wp-graphql-smart-cache/issues/158) + +---- + +## 👉 Up Next: + +- [Network Cache](./docs/network-cache.md) +- [Object Cache](./docs/object-cache.md) +- [Persisted Queries](./docs/persisted-queries.md) diff --git a/docs/network-cache.md b/docs/network-cache.md index 93a8c7f8..3de6bb73 100644 --- a/docs/network-cache.md +++ b/docs/network-cache.md @@ -264,3 +264,11 @@ The network cache layer should respond to calls of the purge action and purge an - **Example with Varnish xkey**: [https://github.com/varnish/varnish-modules/blob/master/src/vmod_xkey.vcc#L45](https://github.com/varnish/varnish-modules/blob/master/src/vmod_xkey.vcc#L45) - **Example with Fastly**: [https://docs.fastly.com/en/guides/purging-with-surrogate-keys](https://docs.fastly.com/en/guides/purging-with-surrogate-keys) + +---- + +## 👉 Up Next: + +- [Object Cache](./docs/object-cache.md) +- [Persisted Queries](./docs/persisted-queries.md) +- [Cache Invalidation](./docs/cache-invalidation.md) diff --git a/docs/object-cache.md b/docs/object-cache.md index 57de948d..3e65ab66 100644 --- a/docs/object-cache.md +++ b/docs/object-cache.md @@ -49,3 +49,9 @@ In addition to enabling Object Caching, you can: - see the last time caches were purged Setting the expiration, and purging caches will only take effect if Object Caching is enabled. + +## 👉 Up Next: + +- [Network Cache](./docs/network-cache.md) +- [Persisted Queries](./docs/persisted-queries.md) +- [Cache Invalidation](./docs/cache-invalidation.md) diff --git a/docs/persisted-queries.md b/docs/persisted-queries.md index 1331024a..8f2b47ed 100644 --- a/docs/persisted-queries.md +++ b/docs/persisted-queries.md @@ -132,3 +132,9 @@ This max-age will be used as the max-age for the query to expire if another even This can be handy if you have queries that might not be invalidating properly based on changes to data in WordPress. For example, currently queries for "Settings" are not invalidating when settings change. For these queries, they will invalidate (expire) when the max age has been hit. + +## 👉 Up Next: + +- [Network Cache](./docs/network-cache.md) +- [Object Cache](./docs/object-cache.md) +- [Cache Invalidation](./docs/cache-invalidation.md) diff --git a/readme.txt b/readme.txt index f78e6ccf..1946f760 100644 --- a/readme.txt +++ b/readme.txt @@ -24,6 +24,11 @@ In order to use v0.2.0+ of WPGraphQL Smart Cache, you will need WPGraphQL v1.12. == Changelog == += 0.3.0 = + +- feat: a LOT of updates to the documentation +- feat: add opt-in telemetry via Appsero. + = 0.2.3 = - fix: fixes a bug where X-GraphQL-Keys weren't being returned properly when querying a persisted query by queryId diff --git a/wp-graphql-smart-cache.php b/wp-graphql-smart-cache.php index 451975ba..ead920b1 100644 --- a/wp-graphql-smart-cache.php +++ b/wp-graphql-smart-cache.php @@ -11,7 +11,7 @@ * Requires PHP: 7.4 * Text Domain: wp-graphql-smart-cache * Domain Path: /languages - * Version: 0.2.3 + * Version: 0.3.0 * License: GPL-3 * License URI: https://www.gnu.org/licenses/gpl-3.0.html * @@ -36,7 +36,7 @@ } const WPGRAPHQL_REQUIRED_MIN_VERSION = '1.2.0'; -const WPGRAPHQL_SMART_CACHE_VERSION = '0.2.3'; +const WPGRAPHQL_SMART_CACHE_VERSION = '0.3.0'; require __DIR__ . '/vendor/autoload.php';