Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bu-navigation.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Author: Boston University (IS&T)
* Author URI: http://sites.bu.edu/web/
* Description: Provides alternative navigation elements designed for blogs with large page counts
* Version: 1.3.6
* Version: 1.3.7
* Text Domain: bu-navigation
* Domain Path: /languages
* License: GPL2+
Expand Down Expand Up @@ -94,7 +94,7 @@ class BU_Navigation_Plugin {
*
* @var string
*/
const VERSION = '1.3.6';
const VERSION = '1.3.7';

/**
* Plugin class constructor.
Expand Down
31 changes: 31 additions & 0 deletions composer-includes/bu-navigation-core-widget/src/data-get-urls.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,35 @@ function get_page_uri( $page, $ancestors ) {
*/
function get_page_uri_ancestors( $post ) {

// Try the cache first, mirroring load_sections(). This call resolves a post's
// ancestor chain via load_sections() + the uncached get_nav_posts() query, and
// runs once per missing-ancestor chain on every front-end render. Without a
// persistent cache it re-runs the raw posts query on each request, which is the
// dominant source of wp_posts read amplification during crawls.
//
// The key is version-stamped on the core posts 'last_changed' value (bumped by
// clean_post_cache() on any post edit) and site-scoped. The 'bu-navigation' group
// is Redis-backed (persistent) in production. Freshness is fully handled by the
// last_changed stamp; the TTL is only a self-healing backstop for the rare case an
// edit bypasses clean_post_cache() (e.g. a direct $wpdb write or import). Unlike
// load_sections() (keyed on post types, so a few keys per site), this cache is keyed
// per post, so a short TTL is used to keep orphaned key generations -- one per
// last_changed bump -- from accumulating in Redis.
$last_changed = wp_cache_get( 'last_changed', 'posts' );
if ( ! $last_changed ) {
$last_changed = microtime();
wp_cache_set( 'last_changed', $last_changed, 'posts' );
}

$cache_key = 'page_uri_ancestors:' . get_current_blog_id() . ':' . md5( $post->ID . ':' . $post->post_type . ":$last_changed" );
$cached = wp_cache_get( $cache_key, 'bu-navigation' );

// Use a strict check against false so that an empty-ancestors result (a top-level
// post with no ancestors) is still served from cache rather than recomputed.
if ( false !== $cached ) {
return $cached;
}
Comment thread
DannyCrews marked this conversation as resolved.

$ancestors = array();
$all_sections = load_sections( $post->post_type );

Expand Down Expand Up @@ -246,6 +275,8 @@ function get_page_uri_ancestors( $post ) {
}
}

wp_cache_set( $cache_key, $ancestors, 'bu-navigation', HOUR_IN_SECONDS );

return $ancestors;
}

Expand Down
12 changes: 11 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
**Tags:** navigation, hierarchical, post type, boston university, bu
**Requires at least:** 3.1
**Tested up to:** 5.7
**Stable tag:** 1.3.6
**Stable tag:** 1.3.7
**License:** GPLv2 or later
**License URI:** http://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -115,6 +115,16 @@ Please see this page for the details:

## Changelog

### 1.3.7

* Makes the per-post ancestor lookup (`get_page_uri_ancestors`) persistent, mirroring the
1.3.6 `load_sections` change. This call resolves a post's ancestor chain when building
permalinks and ran an uncached posts query once per missing-ancestor chain on nearly every
front-end render — the dominant source of `wp_posts` read amplification during crawls.
Results are now cached in the site-scoped, version-stamped `bu-navigation` cache (invalidated
on any post edit, with a short TTL backstop), so permalinks render identically while the
underlying query is reused across requests.

### 1.3.6

* Makes the navigation tree section cache (`load_sections`) persistent instead of
Expand Down
6 changes: 5 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Contributors: ntk, mgburns, gcorne, jtwiest, awbauer, inderpreet99
Tags: navigation, hierarchical, post type, boston university, bu
Requires at least: 3.1
Tested up to: 5.7
Stable tag: 1.3.6
Stable tag: 1.3.7
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -79,6 +79,10 @@ Please see this page for the details:

== Changelog ==

= 1.3.7 =

* Makes the per-post ancestor lookup (`get_page_uri_ancestors`) persistent, mirroring the 1.3.6 `load_sections` change. This call resolves a post's ancestor chain when building permalinks and ran an uncached posts query once per missing-ancestor chain on nearly every front-end render — the dominant source of `wp_posts` read amplification during crawls. Results are now cached in the site-scoped, version-stamped `bu-navigation` cache (invalidated on any post edit, with a short TTL backstop), so permalinks render identically while the underlying query is reused across requests.

= 1.3.6 =

* Makes the navigation tree section cache (`load_sections`) persistent instead of non-persistent, so the page-hierarchy `GROUP_CONCAT` query is reused across requests rather than re-run on nearly every front-end render. The cache key is site-scoped and version-stamped on the core posts cache, with a one-day TTL backstop; publication status, ordering, and navigation meta continue to be applied on the uncached posts query, so navigation output is unchanged.
Expand Down
Loading