Skip to content

fix(checkout-api): resolve checkout-race-condition#8

Open
Spkap wants to merge 1 commit intomainfrom
replayx/incident-checkout-race-001-mo64gmdt
Open

fix(checkout-api): resolve checkout-race-condition#8
Spkap wants to merge 1 commit intomainfrom
replayx/incident-checkout-race-001-mo64gmdt

Conversation

@Spkap
Copy link
Copy Markdown
Collaborator

@Spkap Spkap commented Apr 19, 2026

Summary

Resolve checkout-race-condition for checkout-api with a validated ReplayX patch candidate.

Changed Files

  • demo_app/src/inventory/reserve-stock.ts
  • demo_app/src/checkout/submit-order.ts

Validation

  • Concurrent checkout repro: exit 0
  • Sequential checkout sanity: exit 0

Rollback

Revert the live inventory guard and concurrent checkout settlement handling.

Copilot AI review requested due to automatic review settings April 19, 2026 18:51
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses the checkout-race-condition repro flow by preventing overselling during concurrent stock reservations and by treating OutOfStock as an expected outcome in the concurrent checkout scenario.

Changes:

  • Add a post-delay “live inventory” availability guard before committing a reservation.
  • Return reservation metadata based on the committed inventory record version (not the pre-delay snapshot).
  • In concurrent mode, use Promise.allSettled and only rethrow non-OutOfStock failures.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
demo_app/src/inventory/reserve-stock.ts Adds a post-delay availability check and returns committed snapshotVersion/token values.
demo_app/src/checkout/submit-order.ts Switches concurrent scenario to all-settled handling and filters expected OutOfStock failures.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 18 to +22
// Intentional bug: this delay makes the pre-check stale under concurrent checkout attempts.
await delay(25);

const record = getInventoryRecord(sku);

Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment about an "Intentional bug" making the pre-check stale is now misleading because you added a post-delay availability check against the live record. Please update the comment to reflect the current intent of the delay (e.g., simulating latency/concurrency) so future readers don’t assume the race is still present by design.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
const hardFailure = settled.find(
(result) =>
result.status === "rejected" &&
!(result.reason instanceof Error && result.reason.message.startsWith("OutOfStock:"))
);
Copy link

Copilot AI Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Classifying expected failures by matching the Error message prefix ("OutOfStock:") is brittle and easy to break if the message text changes. Consider using a dedicated error type (e.g., OutOfStockError), an error.name, or a structured field/code so this logic remains stable and type-checkable.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants