SeniorEvent-driven
Orders span payment, restaurant and courier
A synchronous chain of calls needs manual fixes whenever a step fails halfway.
The setup today
The order service calls payment (capture the charge immediately), then the restaurant (accept or reject), then dispatch (assign a courier), in one request. If a later step fails, support staff refund and cancel by hand.
Current configuration
placeOrder():
payment.capture(amount) # money taken now
restaurant.requestAccept() # may reject, may time out
dispatch.assignCourier() # may find no courierWhat you know
- Restaurants reject about 3% of orders; no courier is found for about 0.5%.
- Support processes hundreds of manual refunds a week.
The new requirement
Failures must be handled automatically and safely: no manual refunds, no customer charged for an order that is not delivered, and a clear record of what happened to every order. There is no distributed transaction across these services or the payment provider.
Make the call
2 questions · first-try answers earn the most XP
What a strong answer also covers
- Persist the saga's state at every step, so it resumes after a crash instead of starting over.
- Give each step a timeout and decide what a timeout means (for a restaurant: treat as reject after N minutes).
- Orchestration is easier to follow and monitor for a core flow; choreography suits loosely coupled reactions.
- Track business metrics per step: acceptance time, compensation rate, sagas stuck in each state.