Replace the fixed 15s TTL on GET /state/summary with per-table revision watermarks, stale-while-revalidate background refresh, and a progress-tail section split. SQLAlchemy write hooks invalidate core or progress sections on mutation. Adds tests, benchmark script, and operator docs.
40 lines
No EOL
1.3 KiB
Python
40 lines
No EOL
1.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Quick benchmark for /state/summary revision cache (STATE-WP-0066)."""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import statistics
|
|
import sys
|
|
import time
|
|
import urllib.request
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--base-url", default="http://127.0.0.1:8000")
|
|
parser.add_argument("--requests", type=int, default=10)
|
|
args = parser.parse_args()
|
|
|
|
url = f"{args.base_url.rstrip('/')}/state/summary"
|
|
timings: list[float] = []
|
|
last_cache = ""
|
|
|
|
# Prime cache
|
|
with urllib.request.urlopen(url, timeout=30) as resp:
|
|
resp.read()
|
|
last_cache = resp.headers.get("X-StateHub-Cache", "")
|
|
|
|
for _ in range(args.requests):
|
|
started = time.perf_counter()
|
|
with urllib.request.urlopen(url, timeout=30) as resp:
|
|
resp.read()
|
|
last_cache = resp.headers.get("X-StateHub-Cache", "")
|
|
timings.append(time.perf_counter() - started)
|
|
|
|
p95 = statistics.quantiles(timings, n=20)[18] if len(timings) >= 2 else timings[0]
|
|
print(f"requests={args.requests} p50={statistics.median(timings):.3f}s p95={p95:.3f}s last_cache={last_cache}")
|
|
return 0 if last_cache == "hit-revision" else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |