Automattic\WooCommerce\Internal\BatchProcessing

BatchProcessingController::remove_or_retry_failed_processors │ private │ WC 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.

Returns

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 11.2.2

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;
	}

	// Everything below reads "not scheduled" as grounds for recording a failure against a processor
	// and eventually dropping it from the queue. Action Scheduler being unloaded also reads as
	// "not scheduled", so bail rather than dismantle the queue over a missing dependency.
	if ( ! $this->can_check_scheduled_actions() ) {
		return;
	}

	if ( $this->has_scheduled_action( self::WATCHDOG_ACTION_NAME ) ) {
		return;
	}

	/*
	 * Sanitize before array_diff()/array_filter(): array_diff() string-casts its operands (fatal on an object
	 * entry in PHP 8) and is_scheduled() is typed string, so a corrupted option must be reduced to class-name
	 * strings first.
	 */
	$enqueued_processors    = $this->sanitize_processor_list( $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 );
		}
	}
}