| 1 | """Baseline network round-trip probe for hosted lanes (stdlib only).
|
| 2 |
|
| 3 | For each host: n fresh TCP connects (pure network RTT) and n small HTTPS GETs
|
| 4 | on one kept-alive TLS connection (RTT + server/edge time for a trivial
|
| 5 | request). Separates network RTT from per-request server time.
|
| 6 | """
|
| 7 |
|
| 8 | from __future__ import annotations
|
| 9 |
|
| 10 | import http.client
|
| 11 | import socket
|
| 12 | import statistics
|
| 13 | import time
|
| 14 |
|
| 15 |
|
| 16 | def tcp_rtt_ms(host: str, port: int = 443, n: int = 20) -> list:
|
| 17 | out = []
|
| 18 | for _ in range(n):
|
| 19 | t = time.perf_counter()
|
| 20 | s = socket.create_connection((host, port), timeout=10)
|
| 21 | out.append((time.perf_counter() - t) * 1000)
|
| 22 | s.close()
|
| 23 | return out
|
| 24 |
|
| 25 |
|
| 26 | def warm_get_ms(host: str, path: str, n: int = 20) -> list:
|
| 27 | c = http.client.HTTPSConnection(host, timeout=20)
|
| 28 | c.request("GET", path, headers={"User-Agent": "oakbench-rtt"})
|
| 29 | c.getresponse().read()
|
| 30 | out = []
|
| 31 | for _ in range(n):
|
| 32 | t = time.perf_counter()
|
| 33 | c.request("GET", path, headers={"User-Agent": "oakbench-rtt"})
|
| 34 | r = c.getresponse()
|
| 35 | r.read()
|
| 36 | out.append((time.perf_counter() - t) * 1000)
|
| 37 | c.close()
|
| 38 | return out
|
| 39 |
|
| 40 |
|
| 41 | def summarize(vals: list) -> dict:
|
| 42 | v = sorted(vals)
|
| 43 | return {"n": len(v), "median_ms": statistics.median(v), "min_ms": v[0], "max_ms": v[-1]}
|
| 44 |
|
| 45 |
|
| 46 | if __name__ == "__main__":
|
| 47 | import json
|
| 48 | import sys
|
| 49 | targets = [("oak.space", "/robots.txt"), ("cdn.oak.space", "/"), ("github.com", "/robots.txt")]
|
| 50 | res = {}
|
| 51 | for host, path in targets:
|
| 52 | res[host] = {"tcp_connect": summarize(tcp_rtt_ms(host)), "warm_https_get": summarize(warm_get_ms(host, path))}
|
| 53 | json.dump(res, sys.stdout, indent=1)
|