TASK
Implementation
A MonotonicClock wraps the system clock and guarantees the returned value never decreases. Implement this wrapper and track what information is lost.
Request: {"type": "mono_read", "msg_id": 1}
Response: {"type": "mono_read_ok", "in_reply_to": 1, "time_ms": 1234567, "corrections": 0}Sample Test Cases
Mono read returns timeTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"mono_read","msg_id":2}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
Two reads are non-decreasingTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"mono_read","msg_id":2}}
{"src":"c1","dest":"n1","body":{"type":"mono_read","msg_id":3}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
Hints
Hint 1▾
Wrap the system clock to always return >= previous value
Hint 2▾
Use max(current, last_returned) as the strategy
Hint 3▾
Track how many times the wrapper prevented a backward jump
Hint 4▾
Information lost: you cannot detect when time actually went backward
Hint 5▾
time.monotonic() in Python provides this natively
OVERVIEW
Theoretical Hub
Concept overview coming soon
Key Concepts
monotonic clockclock wrapperinformation lossordering guarantee
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
#!/usr/bin/env python3
import sys, json, time
class MonotonicClock:
def __init__(self): self.last = 0; self.corrections = 0
def read(self, raw_ms):
# TODO: Return max(raw_ms, self.last), track corrections
pass
class Node:
def __init__(self):
self.node_id=None;self.node_ids=[];self.next_msg_id=0;self.
clock=MonotonicClock();self.offset=0
def send(self,d,b):b["msg_id"]=self.next_msg_id;self.next_msg_id+=1;print
(json.dumps({"src":self.node_id,"dest":d,"body":b}),flush=True)
def reply(self,r,b):b["in_reply_to"]=r["body"]["msg_id"];self.send(r
["src"],b)
def now_ms(self):return int(time.time()*1000)+self.offset
def main():
node=Node()
for line in sys.stdin:
line=line.strip()
if not line:continue
msg=json.loads(line);body=msg["body"];t=body["type"]
if t=="init":node.node_id=body["node_id"];node.node_ids=body
["node_ids"];node.reply(msg,{"type":"init_ok"})
elif t=="mono_read":pass
elif t=="simulate_ntp":node.offset+=body["offset_ms"];node.reply(msg,
{"type":"simulate_ntp_ok"})
if __name__=="__main__":main()