Skip to content
Merged
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 ) ) );'`

When I run `wp cron event run --due-now`
Comment thread
swissspidy marked this conversation as resolved.
Outdated
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 run `wp cron event run --due-now`
Comment thread
swissspidy marked this conversation as resolved.
Outdated
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 ) ) );
Comment thread
swissspidy marked this conversation as resolved.
Outdated
}

$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' );
}
Comment thread
swissspidy marked this conversation as resolved.
Outdated

$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