Case studies
Exclusive driver assignment
How two riders competing for the same driver are settled with an atomic claim that expires, and how offers and retries avoid double bookings.
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:
- The matcher selects candidate D for trip T1.
- It claims D with the atomic command above.
- It offers the trip to D's app, with an accept timeout of about 5 to 15 seconds.
- If D accepts, the trip is created, D leaves the available set, and the rider is notified.
- 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
-
Why is
SET NXsafer than aGETfollowed by aSET?Answer:
NXmakes the check and the write one atomic step, so two workers cannot both claim the driver. -
What happens if the matcher crashes while holding a claim?
Answer: the
EXexpiry 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.
Related
Case study: ride-sharing
Uber-style dispatch: streaming driver locations into a geo index, matching under contention, trip state and geographic sharding. Start here for the ride-sharing map.
Acks and visibility timeouts
How a broker knows a message is still being worked on, what happens when a worker disappears, and how to set the timeout so work isn't duplicated.
Case study: ticket booking
Ticketmaster-style inventory under extreme contention, with holds that expire, a virtual waiting room and atomic seat commits so one seat is never sold twice.
Idempotency and retries
Making operations safe to retry, with idempotency keys, deduplicating consumers and jittered backoff, so at-least-once delivery never means a double charge.