TASK
Implementation
Distributed transactions across multiple services cannot use a single database commit. A saga breaks the operation into a sequence of local steps, each with a corresponding compensation action. If any step fails, all already-completed steps are rolled back by executing their compensations in reverse order.
Implement a node that executes sagas and handles failures:
// Execute all steps successfully
{ "type": "execute", "msg_id": 1,
"saga_id": "booking-123",
"steps": ["book_flight", "book_hotel", "book_car"] }
-> { "type": "saga_completed", "in_reply_to": 1,
"saga_id": "booking-123",
"state": "completed", "completed_steps": 3 }
// Fail at book_hotel, compensate completed steps in reverse
{ "type": "execute", "msg_id": 2,
"saga_id": "booking-124",
"steps": ["book_flight", "book_hotel"],
"fail_step": "book_hotel" }
-> { "type": "saga_compensated", "in_reply_to": 2,
"saga_id": "booking-124",
"state": "compensated",
"compensated_steps": ["book_flight"] }When a step fails, only the steps that were successfully completed before it need to be compensated — the failing step itself is not compensated because it never completed. Compensation order is the reverse of execution order.
Sample Test Cases
Execute saga successfullyTimeout: 5000ms
Input
{
"src": "orchestrator",
"dest": "saga",
"body": {
"type": "execute",
"msg_id": 1,
"saga_id": "booking-123",
"steps": [
"book_flight",
"book_hotel",
"book_car"
]
}
}Expected Output
{"type": "saga_completed", "in_reply_to": 1, "saga_id": "booking-123", "state": "completed", "completed_steps": 3}Compensate on failureTimeout: 5000ms
Input
{
"src": "orchestrator",
"dest": "saga",
"body": {
"type": "execute",
"msg_id": 1,
"saga_id": "booking-124",
"steps": [
"book_flight",
"book_hotel"
],
"fail_step": "book_hotel"
}
}Expected Output
{"type": "saga_compensated", "in_reply_to": 1, "saga_id": "booking-124", "state": "compensated", "compensated_steps": ["book_flight"]}Hints
Hint 1▾
Execute steps in order; on any failure, compensate all previously completed steps in reverse order
Hint 2▾
fail_step in the test input tells you which step should fail — simulate that failure
Hint 3▾
compensated_steps must list only the steps that were successfully executed before the failure
Hint 4▾
The compensation order is reverse of execution: last completed step is compensated first
Hint 5▾
saga_id must be echoed back in every response so the caller can correlate requests
OVERVIEW
Theoretical Hub
Concept overview coming soon
Key Concepts
saga patterndistributed transactionscompensationrollbackchoreography
main.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
import sys
import json
def main():
# Your implementation here
for line in sys.stdin:
msg = json.loads(line)
print(json.dumps(msg), flush=True)
if __name__ == "__main__":
main()