ActionScheduler_QueueCleaner::clean_actionspublicWC 1.0

Delete selected actions based on status and date. The function's behavior depends on the context:

  • For scheduled cleanup actions, the function operates within execution budget constraints optimized for high-traffic stores.
  • Otherwise, it strictly follows the provided parameters without the scheduled cleanup optimizations.

Method of the class: ActionScheduler_QueueCleaner{}

No Hooks.

Returns

Array. Actions deleted.

Usage

$ActionScheduler_QueueCleaner = new ActionScheduler_QueueCleaner();
$ActionScheduler_QueueCleaner->clean_actions( $statuses_to_purge, $cutoff_date, $batch_size, $context );
$statuses_to_purge(string[]) (required)
List of action statuses to purge.
Default: canceled, complete
$cutoff_date(DateTime) (required)
Date limit for selecting actions.
Default: 31 days ago
$batch_size(int|null)
Maximum number of actions per status to delete.
Default: 20
$context(string)
Calling process context.
Default: old

ActionScheduler_QueueCleaner::clean_actions() code WC 11.0.1

public function clean_actions( array $statuses_to_purge, DateTime $cutoff_date, $batch_size = null, $context = 'old' ) {
	$batch_size        = ! is_null( $batch_size ) ? $batch_size : $this->batch_size;
	$cutoff            = ! is_null( $cutoff_date ) ? $cutoff_date : as_get_datetime_object( $this->month_in_seconds . ' seconds ago' );
	$lifespan          = time() - $cutoff->getTimestamp();
	$statuses_to_purge = empty( $statuses_to_purge ) ? $this->default_statuses_to_purge : $statuses_to_purge;

	// When deletion is performed as a separate action, we can enforce a minimum batch size to achieve consistent deletion throughput.
	// For inline cleanup during a queue run, the batch size should remain unchanged to avoid increasing the process footprint.
	$is_scheduled_cleanup = doing_action( self::RUN_SCHEDULED_CLEANER_HOOK )
		|| doing_action( self::CONTINUE_SCHEDULED_CLEANER_HOOK );
	// 250 balances replication safety, backlog clearance speed, and claim slot duration on high-volume stores.
	$iteration_batch_size       = $is_scheduled_cleanup ? max( 250, $batch_size ) : $batch_size;
	$iteration_unused_budget    = 0;
	$continue_scheduled_cleanup = false;
	if ( $is_scheduled_cleanup ) {
		// Sort the statuses to optimize execution budget usage based on the typical status distribution.
		usort(
			$statuses_to_purge,
			static function( $a, $b ) {
				// Place the 'canceled' status first to help ensure that any unspent execution budget can be used for processing other statuses.
				if ( ActionScheduler_Store::STATUS_CANCELED === $a ) {
					return -1;
				}
				if ( ActionScheduler_Store::STATUS_CANCELED === $b ) {
					return 1;
				}

				// Place the 'complete' status at the end to use any remaining execution budget for processing.
				if ( ActionScheduler_Store::STATUS_COMPLETE === $a ) {
					return 1;
				}
				if ( ActionScheduler_Store::STATUS_COMPLETE === $b ) {
					return -1;
				}

				return 0;
			}
		);
	}

	$deleted_actions = array();
	foreach ( $statuses_to_purge as $status ) {
		$iteration_execution_budget = $iteration_batch_size + $iteration_unused_budget;
		$actions_to_delete          = $this->store->query_actions(
			array(
				'status'           => $status,
				'modified'         => $cutoff,
				'modified_compare' => '<=',
				'per_page'         => $iteration_execution_budget,
				'orderby'          => 'none',
			)
		);
		$deleted_actions[]          = $this->delete_actions( $actions_to_delete, $lifespan, $context );

		$fetched_actions_count      = count( $actions_to_delete );
		$iteration_unused_budget    = $is_scheduled_cleanup ? ( $iteration_execution_budget - $fetched_actions_count ) : 0;
		$continue_scheduled_cleanup = $continue_scheduled_cleanup || ( $iteration_execution_budget === $fetched_actions_count );
	}

	// When called from the scheduled cleanup hook, unique=true prevents duplicates at the SQL level. When called
	// from a continuation, that same flag would match the running entry, so check for a pending continuation first.
	$called_from_run = doing_action( self::RUN_SCHEDULED_CLEANER_HOOK );
	if ( $is_scheduled_cleanup && $continue_scheduled_cleanup && ( $called_from_run || ! $this->has_pending_continuation() ) ) {
		as_schedule_single_action( time(), self::CONTINUE_SCHEDULED_CLEANER_HOOK, array(), 'ActionScheduler', $called_from_run, 0 );
	}

	return array_merge( array(), ...$deleted_actions );
}