Automattic\WooCommerce\Internal\BatchProcessing
BatchProcessingController::remove_processor
Dequeue and de-schedule a processor instance so that it won't be processed anymore.
Method of the class: BatchProcessingController{}
No Hooks.
Returns
true|false. True if the processor has been dequeued, false if the processor wasn't enqueued (so nothing has been done).
Usage
$BatchProcessingController = new BatchProcessingController(); $BatchProcessingController->remove_processor( $processor_class_name ): bool;
- $processor_class_name(string) (required)
- Fully qualified class name of the processor.
BatchProcessingController::remove_processor() BatchProcessingController::remove processor code WC 11.0.1
public function remove_processor( string $processor_class_name ): bool {
// Resolve membership authoritatively inside the lock (no unguarded fast-path read). remove_processor() is
// not a per-request hot path — the continuous-sync 'shutdown' handler enqueues rather than removes — so it
// always takes the lock and re-reads the freshest list rather than acting on a possibly-stale cached copy.
$was_enqueued = false;
$remaining_processors = $this->mutate_enqueued_processors(
function ( array $enqueued_processors ) use ( $processor_class_name, &$was_enqueued ): array {
if ( ! in_array( $processor_class_name, $enqueued_processors, true ) ) {
return $enqueued_processors;
}
$was_enqueued = true;
return array_values( array_diff( $this->sanitize_processor_list( $enqueued_processors ), array( $processor_class_name ) ) );
}
);
if ( ! $was_enqueued ) {
return false;
}
/*
* $remaining_processors is the list exactly as persisted inside the critical section above, so the empty
* check is decided from the lock-guarded snapshot rather than a second, unguarded re-read (which would only
* ever see this request's own post-mutation value anyway). When that snapshot is empty we unschedule every
* single-batch action to sweep up any orphaned "ghost" actions left in Action Scheduler for processors that
* are no longer enqueued; otherwise only the removed processor's own scheduling needs tearing down, so we
* unschedule by class name.
*
* This intentionally does NOT unschedule the watchdog: handle_watchdog_action() returns without rescheduling
* itself once the list is empty (so a lingering watchdog fires at most once more and then stops), and leaving
* it in place is what makes the empty-list sweep safe. force_clear_all_processes() is deliberately avoided:
* its own unguarded read-modify-write would clobber a processor that a concurrent request enqueued in the gap
* after this mutation committed — the exact lost-update race this change exists to prevent.
*
* There is still a narrow window: a concurrent request can enqueue processor Q and have the watchdog schedule
* Q's single-batch action after our lock releases but before the sweep runs, in which case the sweep cancels
* Q's action even though Q remains enqueued. Q is never lost from the option (the source of truth), so this is
* a bounded scheduling delay, not a lost update: the watchdog we leave in place reschedules Q on its next run.
* That recovery is bounded by the watchdog delay (woocommerce_batch_processor_watchdog_delay_seconds), not the
* next request, because remove_or_retry_failed_processors() no-ops while any watchdog is already scheduled.
*/
if ( empty( $remaining_processors ) ) {
as_unschedule_all_actions( self::PROCESS_SINGLE_BATCH_ACTION_NAME );
} else {
as_unschedule_all_actions( self::PROCESS_SINGLE_BATCH_ACTION_NAME, array( $processor_class_name ) );
}
$this->clear_processor_state( $processor_class_name );
return true;
}