feat: network-wide presence aggregation for multisite - #299
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
▶ Preview in WordPress PlaygroundBoots a fresh WordPress with this PR's presence-api build, seeds 5 demo users, and drops you on the dashboard. Stress-test variant: 40 demo users · Built from |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #299 +/- ##
==========================================
Coverage 97.15% 97.16%
Complexity 190 190
==========================================
Files 14 15 +1
Lines 2076 2220 +144
==========================================
+ Hits 2017 2157 +140
- Misses 59 63 +4
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
9086208 to
ee17555
Compare
204605f to
ad241c7
Compare
a43e3be to
9f75e80
Compare
There was a problem hiding this comment.
Pull request overview
Adds the network-presence aggregation foundation for multisite using a shared push-based summary table.
Changes:
- Provisions and updates a network-wide presence summary table.
- Aggregates fresh site snapshots without switching blogs.
- Adds multisite provisioning, aggregation, freshness, and recovery tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
presence-api.php |
Registers storage and lifecycle hooks. |
includes/network-functions.php |
Implements provisioning, pushing, and aggregation. |
includes/functions.php |
Emits change events and renders avatar stacks. |
tests/test-network-presence.php |
Tests aggregation and refresh behavior. |
tests/test-network-summary-table-creation.php |
Tests table provisioning and recovery. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if ( $held_since && $held_since > time() - MINUTE_IN_SECONDS ) { | ||
| return; | ||
| } | ||
| update_site_option( $lock_option, time() ); |
| dbDelta( | ||
| "CREATE TABLE {$wpdb->presence_network_summary} ( |
| $rows = $wpdb->get_results( | ||
| $wpdb->prepare( | ||
| "SELECT blog_id, data FROM {$wpdb->presence_network_summary} WHERE updated_gmt > %s", | ||
| $cutoff | ||
| ) | ||
| ); |
| $total_users = 0; | ||
|
|
||
| foreach ( $by_site as $blog_id => $entries ) { | ||
| $site = get_site( $blog_id ); |
| // get_site_url()/get_blog_option() switch blogs on every call; the raw | ||
| // WP_Site fields don't, at the cost of not reflecting a mapped domain. | ||
| 'url' => ( is_ssl() ? 'https://' : 'http://' ) . $site->domain . $site->path, |
20cda43 to
8a3c989
Compare
|
Went through this against the sharding question in #310, with the numbers measured on a live multisite rather than read off the diff. Write amplification on every pageview
This is not just the heartbeat tick. Coalescing bounds row churn. It does not bound statement rate, connection count, or row-lock acquisition, and the SELECT that feeds the comparison runs either way. Full answer to #310 over on that issue. Fix: debounce the push through the object cache so a site pushes at most once per Nothing ever removes a rowThere is no
The read path is unbounded
At 300 sites averaging 15 users, the avatar hydration alone: Smaller
|
Multisite networks had no way to see who's online across sites.
Part of #298
See #310 for an open question on this design worth discussion before merge.
Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Sonnet 5
Used for: Assisting with design, implementation, and testing