Automattic\WooCommerce\Internal\BatchProcessing
BatchProcessingController::mutate_enqueued_processors
Run a read-modify-write of the enqueued-processors option inside a short-lived critical section.
The list is stored in a single option and mutated by several code paths (including the per-request 'shutdown' enqueue from continuous HPOS background sync), so an unguarded read-modify-write can lose updates under concurrency: two requests read the same list, each writes its own version, and the later write silently drops the other's change. This serializes those mutations with a self-expiring options-table mutex and re-reads the freshest persisted value inside the lock so the mutator always operates on current state.
The lock is best-effort: if it cannot be acquired within ENQUEUED_PROCESSORS_LOCK_ATTEMPTS tries the mutation still proceeds, which is no worse than the previous lock-free behavior. The fresh re-read inside the section narrows the race window even when the lock provides no real exclusion, and the watchdog reconciles any residual divergence on its next run.
Метод класса: BatchProcessingController{}
Хуков нет.
Возвращает
array. The list as persisted (the mutator's return value).
Использование
// private - только в коде основоного (родительского) класса $result = $this->mutate_enqueued_processors( $mutator ): array;
- $mutator(callable) (обязательный)
- Receives the current list (array of class-name strings) and returns the new list.
Список изменений
| С версии 11.0.0 | Введена. |
Код BatchProcessingController::mutate_enqueued_processors() BatchProcessingController::mutate enqueued processors WC 11.1.1
private function mutate_enqueued_processors( callable $mutator ): array {
$lock_token = $this->acquire_enqueued_processors_lock();
try {
/*
* Drop any request-cached copy so the read below reflects writes committed by concurrent requests
* that landed after this request first read the option. Both the per-option entry AND the shared
* 'notoptions' entry must be cleared: when the option does not yet exist (first enqueue, or after a
* corrupted option was deleted), get_option() short-circuits on a stale 'notoptions' hit and would
* otherwise return the default empty list even though a concurrent request just created the row.
*/
wp_cache_delete( self::ENQUEUED_PROCESSORS_OPTION_NAME, 'options' );
wp_cache_delete( 'notoptions', 'options' );
$current = $this->get_enqueued_processors();
$updated = $mutator( $current );
if ( $updated !== $current ) {
$this->set_enqueued_processors( $updated );
}
return $updated;
} finally {
if ( null !== $lock_token ) {
$this->release_enqueued_processors_lock( $lock_token );
}
}
}