Automattic\WooCommerce\Internal\BatchProcessing

BatchProcessingController::remove_or_retry_failed_processors()privateWC 9.1.0

Hooked onto 'shutdown'. This cleanup routine checks enqueued processors and whether they are scheduled or not to either re-eschedule them or remove them from the queue. This prevents stale states where Action Scheduler won't schedule any more attempts but we still report the processor as enqueued.

Method of the class: BatchProcessingController{}

No Hooks.

Return

null. Nothing (null).

Usage

// private - for code of main (parent) class only
$result = $this->remove_or_retry_failed_processors(): void;

Changelog

Since 9.1.0 Introduced.

BatchProcessingController::remove_or_retry_failed_processors() code WC 9.2.3

private function remove_or_retry_failed_processors(): void {
	if ( ! did_action( 'wp_loaded' ) ) {
		return;
	}

	$last_error = error_get_last();
	if ( ! is_null( $last_error ) && in_array( $last_error['type'], array( E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ), true ) ) {
		return;
	}

	// The most efficient way to check for an existing action is to use `as_has_scheduled_action`, but in unusual
	// cases where another plugin has loaded a very old version of Action Scheduler, it may not be available to us.
	$has_scheduled_action = function_exists( 'as_has_scheduled_action') ? 'as_has_scheduled_action' : 'as_next_scheduled_action';

	if ( call_user_func( $has_scheduled_action, self::WATCHDOG_ACTION_NAME ) ) {
		return;
	}

	$enqueued_processors    = $this->get_enqueued_processors();
	$unscheduled_processors = array_diff( $enqueued_processors, array_filter( $enqueued_processors, array( $this, 'is_scheduled' ) ) );

	foreach ( $unscheduled_processors as $processor ) {
		try {
			$instance = $this->get_processor_instance( $processor );
		} catch ( \Exception $e ) {
			continue;
		}

		$exception = new \Exception( 'Processor is enqueued but not scheduled. Background job was probably killed or marked as failed. Reattempting execution.' );
		$this->update_processor_state( $instance, 0, $exception );
		$this->log_error( $exception, $instance, array() );

		if ( $this->is_consistently_failing( $instance ) ) {
			$this->log_consistent_failure( $instance, $this->get_process_details( $instance ) );
			$this->remove_processor( $processor );
		} else {
			$this->schedule_batch_processing( $processor, true );
		}
	}
}