Make WordPress Core

Opened 3 weeks ago

Closed 2 weeks ago

#64315 closed defect (bug) (fixed)

Running `_wp_cron()` on shutdown breaks `ALTERNATE_WP_CRON`

Reported by: karl94's profile karl94 Owned by: westonruter's profile westonruter
Milestone: 6.9 Priority: normal
Severity: major Version: 6.9
Component: Cron API Keywords: has-patch has-test-info fixed-major dev-feedback
Focuses: Cc:

Description

In #63858, [60925] moved cron spawing from the wp_loaded hook to shutdown.
While this is fine for usual cron spawning via wp_remote_post(), the alternative cron behavior doesn't work properly after this change.

ALTERNATE_WP_CRON is an alternative cron spawning method: it's meant to be used in environments where HTTP loopback request cannot be used and works by redirecting the client to the same URL with just an extra doing_wp_cron query param. This way, on the first request (the one that outputs the redirect) crons are executed "in background" while the client follows the redirect and loads the URL requested.

The issue is that by moving _wp_cron() execution to shutdown the redirect can't be performed as output already started (and triggers the Cannot modify header information - headers already sent warning).

https://github.com/WordPress/wordpress-develop/blob/217d39aa50c5e15584a921c3e58eb104f0d96eed/src/wp-includes/cron.php#L918

Furthermore, wp-cron.php may call die(), which would then terminate execution preventing other callbacks attached to the shutdown hook to run.

I think that on ALTERNATE_WP_CRON the previous behavior should be restored: the wp_loaded hook should be used instead of shutdown.

Change History (13)

#1 @peterwilsoncc
3 weeks ago

  • Milestone changed from Awaiting Review to 6.9

#2 @westonruter
3 weeks ago

  • Owner set to westonruter
  • Status changed from new to assigned

#3 @westonruter
3 weeks ago

  • Status changed from assigned to accepted

Thank you. I was able to reproduce this issue.

  1. I added define( 'ALTERNATE_WP_CRON', true ); to my wp-config.php.
  2. I scheduled a post to publish in one minute.
  3. I loaded the frontend after the scheduled publish time, and in the footer (and in the error log) I saw:

PHP Warning: Cannot modify header information - headers already sent by (output started at /var/www/src/wp-includes/template-canvas.php:13) in /var/www/src/wp-includes/pluggable.php on line 1534

This ticket was mentioned in PR #10561 on WordPress/wordpress-develop by @westonruter.


3 weeks ago
#4

  • Keywords has-patch added

This restores the part of wp_cron() which was replaced in r60925, but only when ALTERNATE_WP_CRON is enabled.

Trac ticket: https://core.trac.wordpress.org/ticket/64315

#5 @westonruter
3 weeks ago

@karl94 This PR fixes the issue for me: https://github.com/WordPress/wordpress-develop/pull/10561

Would you please test and confirm it resolves the issues you experienced?

#6 @parthvataliya
3 weeks ago

  • Keywords has-test-info added

Test Report

Description

I have tested it, and it works as expected. There is no PHP warning displayed with this PR: https://github.com/WordPress/wordpress-develop/pull/10561

Patch tested: https://patch-diff.githubusercontent.com/raw/WordPress/wordpress-develop/pull/10561.diff

Environment

  • WordPress: 6.9-RC3-61308-src
  • PHP: 8.2.26
  • Server: nginx/1.27.3
  • Database: mysqli (Server: 8.4.4 / Client: mysqlnd 8.2.26)
  • Browser: Chrome 140.0.0.0
  • OS: Linux
  • Theme: Twenty Twenty-Five 1.3
  • MU Plugins: None activated
  • Plugins:
    • Test Reports 1.2.1

Actual Results

  1. ✅ Issue resolved with a patch.

#7 @karl94
3 weeks ago

Hi @westonruter, I can confirm the patch fixes the issue.

Thanks for the quick response!

#8 @johnbillion
3 weeks ago

  • Keywords commit added

Tested locally by enabling ALTERNATE_WP_CRON, scheduling a cron event to run a few moments later, and confirming that the redirect to the doing_wp_cron URL correctly occurs without the "headers already sent" warning.

#9 @westonruter
3 weeks ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 61313:

Cron API: Restore spawning cron at wp_loaded when using alternate WP Cron (ALTERNATE_WP_CRON).

Developed in https://github.com/WordPress/wordpress-develop/pull/10561

Follow-up to [60925].

Props karl94, peterwilsoncc, parthvataliya, johnbillion, westonruter.
See #63858.
Fixes #64315.

#10 @westonruter
3 weeks ago

  • Keywords fixed-major added
  • Resolution fixed deleted
  • Status changed from closed to reopened

Re-opening for 6.9 backport consideration.

#11 @wildworks
2 weeks ago

  • Keywords dev-feedback added; commit removed

This ticket was mentioned in Slack in #core by akshayar. View the logs.


2 weeks ago

#13 @SergeyBiryukov
2 weeks ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 61332:

Cron API: Restore spawning cron at wp_loaded when using alternate WP Cron (ALTERNATE_WP_CRON).

Developed in #10561 Restore prior wp_cron() logic when ALTERNATE_WP_CRON is enabled.

Follow-up to [60925].

Reviewed by westonruter, SergeyBiryukov.
Merges [61313] to the 6.9 branch.

Props karl94, peterwilsoncc, parthvataliya, johnbillion, westonruter.
See #63858.
Fixes #64315.

Note: See TracTickets for help on using tickets.