Make WordPress Core

#64315 closed defect (bug) (fixed)

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

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

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
10 months ago

  • Milestone Awaiting Review → 6.9

#2 @westonruter
10 months ago

  • Owner set to westonruter
  • Status new → assigned

#3 @westonruter
10 months ago

  • Status assigned → 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.


10 months 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
10 months 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
10 months 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
10 months ago

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

Thanks for the quick response!

#8 @johnbillion
10 months 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
10 months ago

  • Resolution → fixed
  • Status accepted → 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
10 months ago

  • Keywords fixed-major added
  • Resolution fixed
  • Status closed → reopened

Re-opening for 6.9 backport consideration.

#11 @wildworks
10 months ago

  • Keywords dev-feedback added; commit removed

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


10 months ago

#13 @SergeyBiryukov
10 months ago

  • Resolution → fixed
  • Status reopened → 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.