fix(domain): skip async enqueue of wu_add_domain/wu_add_subdomain when no listener is hooked#1232
Conversation
…n no listener is hooked The Domain_Manager unconditionally enqueued the 'wu_add_domain' and 'wu_add_subdomain' Action Scheduler jobs on every site creation and custom-domain change. Those hooks are extension points consumed only by host-provider integration modules (Cloudflare, cPanel, Hostinger, RunCloud, Hestia, Plesk, BunnyCDN, etc.) — each one registers its listener inside register_hooks() only when the integration is enabled. In environments where no host integration is active, Action Scheduler ran each enqueued job with zero callbacks and logged 'no callbacks are registered' on every site/domain operation. Site creation and the wu_async_process_domain_stage DNS/SSL chain were never affected by this — the domain stage progression has its own dedicated listener (class-domain-manager.php:155). Guard both enqueue sites with has_action(...). Host providers register their listeners at plugin init, well before Action Scheduler claims async jobs, so has_action() is authoritative at enqueue time. Any enabled integration continues to receive both hooks as before. Adds four regression tests covering both the skip path (no listener registered) and the enqueue path (listener registered) for each hook.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughDomain_Manager now enqueues async actions ChangesConditional async action enqueueing with regression tests
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
Summary
FixGuard both enqueue sites with
Why not remove the hooks?They are not vestigial. The TestsFour new regression tests in
VerificationOut of scopeThe same aidevops.sh v3.17.8 plugin for OpenCode v1.15.5 with claude-sonnet-4-20250514 spent 3h 34m on this as a headless worker. Merged via PR #1232 to main. |
|
Performance Test Results Performance test results for a4269fb are in 🛎️! Note: the numbers in parentheses show the difference to the previous (baseline) test run. Differences below 2% or 0.5 in absolute values are not shown. URL:
|
Summary
Domain_Managerunconditionally enqueued thewu_add_domainandwu_add_subdomainAction Scheduler jobs on every site creation and custom-domain change. Those hooks are extension points consumed only by host‑provider integration modules (Cloudflare, cPanel, Hostinger, RunCloud, Hestia, Plesk, BunnyCDN, etc.) — each one registers its listener insideregister_hooks()only when the integration is enabled.In environments where no host integration is active, Action Scheduler ran each enqueued job with zero callbacks and logged
"no callbacks are registered"on every site/domain operation. This was observed against every site created since 2026‑05‑08 (blogs 70–80) on an install with no host integration enabled.Site creation and the
wu_async_process_domain_stageDNS/SSL chain were never affected — domain stage progression has its own dedicated listener (class-domain-manager.php:155), which is whystage=donestill completes.Fix
Guard both enqueue sites with
has_action(...):inc/managers/class-domain-manager.php:339(subdomain, insidehandle_site_created)inc/managers/class-domain-manager.php:776(domain, insidesend_domain_to_host)Host providers register their listeners at plugin init, well before Action Scheduler claims async jobs, so
has_action()is authoritative at enqueue time. Any enabled integration continues to receive both hooks as before.Why not remove the hooks?
They are not vestigial. The
Base_Host_Provider::register_hooks()method atinc/integrations/host-providers/class-base-host-provider.php:361,371plus 17 capability modules underinc/integrations/providers/*/class-*-domain-mapping.phpall subscribe. Removing the hooks would break every host integration.Tests
Four new regression tests in
tests/WP_Ultimo/Managers/Domain_Manager_Test.php:test_send_domain_to_host_skips_enqueue_without_listener— asserts no action is queued when nothing is hooked towu_add_domain.test_send_domain_to_host_enqueues_when_listener_registered— asserts the action is queued with the expected args when a listener exists.test_handle_site_created_skips_subdomain_enqueue_without_listener— same pair forwu_add_subdomain.test_handle_site_created_enqueues_subdomain_when_listener_registered— same pair forwu_add_subdomain.Each test snapshots
$GLOBALS['wp_filter'][$hook], mutates it, asserts the precondition (has_action(...)), exercises the manager method, and queries Action Scheduler directly viawu_get_scheduled_actions()with statusSTATUS_PENDINGand exact args matching. Original listeners are restored infinally.Verification
Out of scope
The same
"no callbacks are registered"warning also appears forfetch_patterns(WordPress core block-pattern cache prime) andwc-admin_process_pending_orders_batch(WooCommerce Admin order stats backfill). Both are external to this plugin and not addressed here.aidevops.sh v3.17.8 plugin for OpenCode v1.15.5 with claude-sonnet-4-20250514 spent 3h 34m on this as a headless worker.
Summary by CodeRabbit