TASK
Implementation
System clocks can go backward due to NTP adjustments. Your task is to read the clock repeatedly and detect backward jumps.
Implement a clock_sample handler that reads the clock N times:
Request: {"type": "clock_sample", "msg_id": 1, "count": 100, "offset_ms": 0}
Response: {"type": "clock_sample_ok", "in_reply_to": 1, "samples": 100, "backward_jumps": 0, "max_delta_us": 15, "min_delta_us": 1}Also implement simulate_ntp to inject a backward offset:
Request: {"type": "simulate_ntp", "msg_id": 2, "offset_ms": -50}
Response: {"type": "simulate_ntp_ok", "in_reply_to": 2}Sample Test Cases
Clock sample returns statsTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"clock_sample","msg_id":2,"count":10}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
Simulate NTP responds okTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"simulate_ntp","msg_id":2,"offset_ms":-50}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
{"src": "n1", "dest": "c1", "body": {"type": "simulate_ntp_ok", "in_reply_to": 2, "msg_id": 1}}
Hints
Hint 1▾
Use time.time() for wall clock and time.monotonic() for monotonic clock
Hint 2▾
Compare consecutive readings to detect backward jumps
Hint 3▾
NTP adjustments can cause the wall clock to jump backward
Hint 4▾
Track minimum and maximum deltas between readings
Hint 5▾
Store readings in a buffer for analysis
OVERVIEW
Theoretical Hub
Concept overview coming soon
Key Concepts
system clockclock monotonicityNTPbackward jump
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
#!/usr/bin/env python3
import sys, json, time
class Node:
def __init__(self):
self.node_id = None; self.node_ids = []; self.next_msg_id = 0; self.
clock_offset = 0
def send(self, dest, body):
body["msg_id"] = self.next_msg_id; self.next_msg_id += 1
print(json.dumps({"src": self.node_id, "dest": dest, "body": body}),
flush=True)
def reply(self, req, body):
body["in_reply_to"] = req["body"]["msg_id"]; self.send(req["src"],
body)
def now_ms(self): return int(time.time() * 1000) + self.clock_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 == "clock_sample":
# TODO: Sample clock count times, detect backward jumps
pass
elif t == "simulate_ntp":
# TODO: Apply offset
pass
if __name__ == "__main__": main()