TASK
Implementation
While 3PC improves on 2PC, it still has blocking scenarios. The key limitation: if a network partition occurs before PreCommit, participants may not be able to proceed.
Scenario 1: Partition before PreCommit:
- Coordinator sends
CanCommitto all participants - Some participants vote
Yes, others are partitioned - Coordinator cannot collect all votes
- No participant can proceed: non-partitioned participants don't know if all voted Yes
- Result: blocking
Scenario 2: Partition during PreCommit:
- Coordinator sends
CanCommit, all participants voteYes - Network partition occurs
- Coordinator sends
PreCommitto only some participants - Partitioned participants never receive
PreCommit - Result: partitioned participants block, non-partitioned participants can timeout and commit
Example: Partition before PreCommit:
Request: {"type": "txn_begin", "msg_id": 1, "participants": ["p1", "p2", "p3"], "partition_after": "can_commit", "partitioned_participants": ["p3"]}
Response: {"type": "txn_begin_ok", "in_reply_to": 1, "txn_id": "txn42"}
// p1 and p2 vote Yes
{"type": "can_commit_yes", "src": "p1", "txn_id": "txn42"}
{"type": "can_commit_yes", "src": "p2", "txn_id": "txn42"}
// p3 is partitioned, cannot vote
// Coordinator cannot proceed: doesn't know if p3 would vote Yes or No
// p1 and p2 block: they don't know if p3 voted NoWhy this is unavoidable:
- Before
PreCommit, participants don't know if all participants voted Yes - If any participant voted No, the transaction must abort
- Without knowing all votes, no participant can safely decide
- This is a fundamental trade-off: 3PC reduces but doesn't eliminate blocking
Sample Test Cases
Partition before PreCommit blocksTimeout: 6000ms
Input
{"src":"c0","dest":"coord","body":{"type":"init","msg_id":1,"participants":["p1","p2","p3"]}}
{"src":"c1","dest":"coord","body":{"type":"txn_begin","msg_id":2,"participants":["p1","p2","p3"],"operations":[{"transfer":100,"from":"a","to":"b"}],"partition_after":"can_commit","partitioned_participants":["p3"],"timeout_ms":2000}}
Expected Output
{"src": "coord", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
Partition during PreCommit allows commitTimeout: 6000ms
Input
{"src":"c0","dest":"coord","body":{"type":"init","msg_id":1,"participants":["p1","p2","p3"]}}
{"src":"c1","dest":"coord","body":{"type":"txn_begin","msg_id":2,"participants":["p1","p2","p3"],"operations":[{"transfer":100,"from":"a","to":"b"}],"partition_after":"pre_commit","partitioned_participants":["p3"],"timeout_ms":2000}}
Expected Output
{"src": "coord", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
Hints
Hint 1▾
3PC still blocks if coordinator crashes before PreCommit
Hint 2▾
3PC blocks if network partition separates coordinator from some participants
Hint 3▾
If participants are in CAN_COMMIT state and can't reach coordinator, they must wait
Hint 4▾
Show: partition coordinator from participants after CanCommit phase
Hint 5▾
Result: non-partitioned participants block because they don't know if all voted Yes
OVERVIEW
Theoretical Hub
Concept overview coming soon
Key Concepts
network partitionblocking scenariossplit brainsafety vs livenessCAP theorem
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()