Skip to content
Draft
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
32 changes: 32 additions & 0 deletions features/cron-event.feature
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,35 @@ Feature: Manage WP Cron events
"""
Debug: Beginning execution of cron event 'wp_version_check'
"""

Scenario: --due-now respects the doing_cron transient and skips when another run is in progress
When I run `wp cron event schedule wp_cli_test_event_lock now hourly`
Then STDOUT should contain:
"""
Success: Scheduled event with hook 'wp_cli_test_event_lock'
"""

# Simulate an in-progress cron run by setting the doing_cron transient to now.
When I run `wp eval 'set_transient( "doing_cron", sprintf( "%.22F", microtime( true ) ) );'`

And I try `wp cron event run --due-now`
Then STDERR should contain:
"""
Warning: A cron event run is already in progress; skipping.
"""
And STDOUT should not contain:
"""
wp_cli_test_event_lock
"""

# After the transient is cleared, the run should proceed normally.
When I run `wp transient delete doing_cron`
And I try `wp cron event run --due-now`
Then STDOUT should contain:
"""
Executed the cron event 'wp_cli_test_event_lock'
"""
And STDOUT should contain:
"""
Executed a total of 1 cron event
"""
21 changes: 20 additions & 1 deletion src/Cron_Event_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,8 @@ public function schedule( $args, $assoc_args ) {
* : One or more hooks to run.
*
* [--due-now]
* : Run all hooks due right now.
* : Run all hooks due right now. Respects the doing_cron transient to
* prevent overlapping runs.
*
* [--exclude=<hooks>]
* : Comma-separated list of hooks to exclude.
Expand All @@ -243,10 +244,24 @@ public function schedule( $args, $assoc_args ) {
* Success: Executed a total of 2 cron events.
*/
public function run( $args, $assoc_args ) {
$due_now = Utils\get_flag_value( $assoc_args, 'due-now' );

if ( $due_now ) {
$lock_timeout = defined( 'WP_CRON_LOCK_TIMEOUT' ) ? WP_CRON_LOCK_TIMEOUT : 60;
$doing_cron_transient = get_transient( 'doing_cron' );
if ( is_string( $doing_cron_transient ) && (float) $doing_cron_transient > microtime( true ) - $lock_timeout ) {
WP_CLI::warning( 'A cron event run is already in progress; skipping.' );
return;
}
set_transient( 'doing_cron', sprintf( '%.22F', microtime( true ) ) );
}

$events = self::get_selected_cron_events( $args, $assoc_args );

if ( is_wp_error( $events ) ) {
if ( $due_now ) {
delete_transient( 'doing_cron' );
}
WP_CLI::error( $events );
}

Expand All @@ -263,6 +278,10 @@ public function run( $args, $assoc_args ) {
}
}

if ( $due_now ) {
delete_transient( 'doing_cron' );
}

$message = ( 1 === $executed ) ? 'Executed a total of %d cron event.' : 'Executed a total of %d cron events.';
WP_CLI::success( sprintf( $message, $executed ) );
}
Expand Down
Loading