Guide

When two riders request a trip at the same moment, both may see driver D as the closest. Both matching workers then try to offer D the trip. Without coordination, both offers go out and the driver is booked twice. The fix is an exclusive claim: one atomic step that marks the driver as taken, and expires if the matcher disappears.

The big idea

A claim is a short-lived lock on a driver. The matching worker sets it only if nobody else has set it. The claim carries a time limit, so a crashed worker cannot hold the driver forever. This is a lease, the same pattern as a message's visibility timeout in acks and visibility timeouts.

The check and the write must be one step. Checking first and writing second lets two workers both pass the check.

Walking through it

A Redis command does the claim in one step. NX means "set only if the key does not exist". EX 30 means "expire after 30 seconds":

127.0.0.1:6379> SET driver:D:trip T1 NX EX 30
OK
127.0.0.1:6379> SET driver:D:trip T2 NX EX 30
(nil)

Worker one claims D for trip T1. Worker two, working for trip T2, gets (nil), which means the claim failed. It moves on to the next candidate. Rider B's match does not double-book D.

The full flow for one trip:

  1. The matcher selects candidate D for trip T1.
  2. It claims D with the atomic command above.
  3. It offers the trip to D's app, with an accept timeout of about 5 to 15 seconds.
  4. If D accepts, the trip is created, D leaves the available set, and the rider is notified.
  5. If D rejects or times out, the claim is released, and the matcher tries the next candidate.

Two more details matter. An offer should be idempotent. A retried offer must not send a second push notification to the driver. Rider taps should also be idempotent. A rider who taps "request" three times should get one trip, using an Idempotency-Key header.

Example

Rider A and rider B both see driver D as closest. A's worker wins the NX claim on D. B's worker fails and takes driver E. Without the claim, both could notify D and create a double booking. That is the same class of bug as selling one seat twice in ticket booking.

Common mistakes

  • Checking, then setting. Use one atomic command, such as SET NX.
  • A claim with no expiry. A crashed matcher leaves the driver stuck.
  • Notifying the driver before the claim. Claim first, then notify.
  • Retries that send duplicate offers. Make offers idempotent.

Check yourself

  1. Why is SET NX safer than a GET followed by a SET?

    Answer: NX makes the check and the write one atomic step, so two workers cannot both claim the driver.

  2. What happens if the matcher crashes while holding a claim?

    Answer: the EX expiry releases the claim, and the driver becomes available again.

Key takeaways

  • Exclusive assignment needs an atomic claim, such as SET NX, not a check followed by a write.
  • Give every claim an expiry, so crashes free the driver.
  • Make offers and trip requests idempotent, so retries do not create duplicates.
  • Claim first, then notify the driver.

Further learning

Next, see how a trip moves through its states after a driver accepts, in trip state machine.