TASK
Implementation
Handle client retries without duplicate execution:
- Client assigns sequence number to each request
- Server tracks (client_id -> latest_seq, response)
- If request seq <= latest_seq, return cached response
- Otherwise, process and cache new response
This makes at-least-once delivery safe for non-idempotent operations.
Sample Test Cases
First request executesTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"write","msg_id":2,"key":"x","value":1,"client_id":"c1","seq":1}}
Expected Output
{"src":"n1","dest":"c0","body":{"type":"init_ok","in_reply_to":1,"msg_id":0}}
{"src":"n1","dest":"c1","body":{"type":"write_ok","in_reply_to":2,"msg_id":1}}
Hints
Hint 1▾
Client assigns unique ID to each request
Hint 2▾
Server tracks latest response per client
Hint 3▾
Duplicate request returns cached response
OVERVIEW
Theoretical Hub
Exactly-Once Semantics
Network issues cause retries. Without deduplication, a PUT might execute twice. By tracking client sessions and sequence numbers, we can detect and skip duplicates.
Session State
The deduplication table must survive leader changes. Store it in the replicated state machine. Periodically garbage collect old sessions.
Key Concepts
idempotencyclient sessionsdeduplication
main.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/env python3
import sys
import json
import time
class ClientTracker:
def __init__(self, session_timeout=300):
self.sessions = {} # client_id -> {seq, response, last_seen}
self.session_timeout = session_timeout
def register_request(self, client_id, seq, operation):
# TODO: Check if duplicate
# Return (is_dup, cached_response or None)
pass
def record_response(self, client_id, seq, response):
# TODO: Cache response for client
pass
def gc_expired_sessions(self):
# TODO: Remove old sessions
pass
class DedupKVStore:
def __init__(self, kv_store, tracker):
self.kv = kv_store
self.tracker = tracker
def handle_request(self, client_id, seq, operation):
# TODO: Check dedup, process or return cached
pass