store->committed_rows( $migration_id, $chunk_key, $transfer_uuid ); if ( null !== $receipt ) { // Replay of an already-committed chunk: serve the saved receipt. return $receipt; } $claimed = false; for ( $attempt = 0; $attempt < $this->contention_attempts && ! $claimed; $attempt++ ) { $claim_age = $this->store->pending_updated_at( $migration_id, $chunk_key, $transfer_uuid ); if ( null !== $claim_age && ( time() - $claim_age ) > self::CLAIM_STALE_AFTER_SECONDS ) { // The previous holder never finished; scrub its claim so a // retry re-runs the chunk exactly once. $this->store->clear_pending( $migration_id, $chunk_key, $transfer_uuid ); } if ( $this->store->set_pending( $migration_id, $chunk_key, $table, $transfer_uuid ) ) { $claimed = true; break; } // Another worker holds the live claim. Give it a bounded chance to // commit, then use its receipt instead of re-running. $receipt = $this->store->committed_rows( $migration_id, $chunk_key, $transfer_uuid ); if ( null !== $receipt ) { return $receipt; } if ( $attempt + 1 < $this->contention_attempts ) { usleep( $this->contention_wait_usec ); } } if ( ! $claimed ) { throw new RuntimeException( "Chunk {$chunk_key} is being replayed by another worker; refusing to run it twice." ); } try { $rows = (int) $execute(); } catch ( Throwable $e ) { // Release the claim so a retry is the only run. A failing cleanup write // must not mask the real import error. try { $this->store->clear_pending( $migration_id, $chunk_key, $transfer_uuid ); } catch ( Throwable $ignored ) { // Intentionally ignored. } throw $e; } // Only the claim owner promotes pending to committed. If that write fails, // release the claim so a retry re-runs the chunk instead of deadlocking the // row. A receipt that landed is untouched, since clear_pending only deletes // status = 'pending' rows. try { $this->store->set_committed( $migration_id, $chunk_key, $rows, $transfer_uuid ); } catch ( Throwable $e ) { try { $this->store->clear_pending( $migration_id, $chunk_key, $transfer_uuid ); } catch ( Throwable $ignored ) { // Intentionally ignored. } throw $e; } return $rows; } // phpcs:enable WordPress.Security.EscapeOutput.ExceptionNotEscaped }