Spaces:
Running
Running
Download apex/tools/bench_stream.py from Jishnupg/FileToLink: direct link, hf CLI and curl.
- Browser
- Download file 4.98 kB
-
https://huggingface.co/spaces/Jishnupg/FileToLink/resolve/main/apex/tools/bench_stream.py
- Command line
-
hf download hf://spaces/Jishnupg/FileToLink/apex/tools/bench_stream.py
-
curl -L -o bench_stream.py https://huggingface.co/spaces/Jishnupg/FileToLink/resolve/main/apex/tools/bench_stream.py
4.98 kB
| """Post-deployment playback + seek benchmark for the apex_stream Telegram engine. | |
| Snapshots /tg-stream/status + /tg-stream/metrics, runs a sequential full-file | |
| range GET and concurrent random seeks, then prints deltas (streams, cache | |
| hits/misses, bytes, throughput, active runs). | |
| Usage: | |
| python tools/bench_stream.py [base_url] [--workers 4] | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import asyncio | |
| import sys | |
| try: | |
| import httpx | |
| except ImportError: | |
| print("httpx is required: pip install httpx", file=sys.stderr) | |
| sys.exit(1) | |
| def _digest(status: dict, metrics: dict) -> dict: | |
| counters = metrics.get("counters", {}) if isinstance(metrics, dict) else {} | |
| totals = metrics.get("totals", {}) if isinstance(metrics, dict) else {} | |
| cache = status.get("cache", {}) if isinstance(status, dict) else {} | |
| admission = status.get("admission", {}) if isinstance(status, dict) else {} | |
| return { | |
| "counters": dict(counters), | |
| "totals": dict(totals), | |
| "cache": dict(cache), | |
| "active_global": admission.get("active_streams", 0), | |
| "active_by_source": dict(admission.get("active_by_source", {})), | |
| "inflight_runs": status.get("inflight_runs", 0), | |
| "cached_files": status.get("cached_files", 0), | |
| } | |
| async def _snapshot(client: httpx.AsyncClient, base: str) -> dict: | |
| status = (await client.get(f"{base}/tg-stream/status")).json() | |
| metrics = (await client.get(f"{base}/tg-stream/metrics")).json() | |
| return _digest(status, metrics) | |
| def _delta(kind: str, pre: dict, post: dict, key: str) -> int: | |
| return post[kind].get(key, 0) - pre[kind].get(key, 0) | |
| async def _run(args) -> int: | |
| base = args.base.rstrip("/") | |
| async with httpx.AsyncClient(timeout=httpx.Timeout(300.0, connect=15.0)) as client: | |
| pre = await _snapshot(client, base) | |
| print( | |
| f"baseline: cached_files={pre['cached_files']} cache_entries=" | |
| f"{pre['cache'].get('entries', 0)} inflight_runs={pre['inflight_runs']} " | |
| f"active_streams={pre['active_global']} uptime=" | |
| f"{pre['counters'].get('streams_total', 0)} streams" | |
| ) | |
| if pre["cache"].get("entries", 0) == 0 and not any( | |
| pre["active_by_source"] or pre["inflight_runs"] | |
| ): | |
| print( | |
| "WARNING: no active/cached source. Feed media to the webhook bot " | |
| "first, then re-run. Benchmark still exercises empty-cache seeks.", | |
| file=sys.stderr, | |
| ) | |
| size = args.chunk | |
| tasks = [] | |
| for w in range(args.workers): | |
| start = (w * (size // args.workers)) % size | |
| end = min(start + args.step, size - 1) | |
| tasks.append(_seek(client, base, start, end)) | |
| t0 = asyncio.get_running_loop().time() | |
| lat = await asyncio.gather(*tasks) | |
| total = asyncio.get_running_loop().time() - t0 | |
| post = await _snapshot(client, base) | |
| print("\n--- deltas ---") | |
| for k in ("streams_total", "streams_completed", "streams_cancelled", "streams_errors"): | |
| d = _delta("counters", pre, post, k) | |
| print(f" {k}: {d}") | |
| print( | |
| f" bytes_sent: " | |
| f"{_delta('totals', pre, post, 'stream_bytes_sent'):,}" | |
| ) | |
| hits = _delta("cache", pre, post, "hits") | |
| misses = _delta("cache", pre, post, "misses") | |
| print(f" cache: {hits} hits / {misses} misses (entries now {post['cache'].get('entries', 0)})") | |
| print( | |
| f" seeks: {len(tasks)} concurrent range GETs, avg " | |
| f"{sum(lat) / len(lat) * 1000:.0f} ms, " | |
| f"total throughput {(args.workers * args.step) / max(total, 1e-9) / 1048576:.1f} MiB/s" | |
| ) | |
| print(f" admission active: {post['active_global']} (per-source {post['active_by_source']})") | |
| print(f" inflight_runs: {post['inflight_runs']}") | |
| return 0 | |
| async def _seek(client, base: str, start: int, end: int) -> float: | |
| url = f"{base}/tg-stream/stream_file?file_id=bench&message_id=bench" | |
| t0 = asyncio.get_running_loop().time() | |
| async with client.stream("GET", url, headers={"Range": f"bytes={start}-{end}"}) as r: | |
| # streams may 404 cleanly when no media is cached yet; measure time to | |
| # decision, which still exercises the driver | |
| async for _ in r.aiter_bytes(): | |
| pass | |
| return asyncio.get_running_loop().time() - t0 | |
| def main() -> int: | |
| p = argparse.ArgumentParser() | |
| p.add_argument("base", nargs="?", default="https://jishnupg-apex.hf.space") | |
| p.add_argument("--workers", type=int, default=4) | |
| p.add_argument("--chunk", type=int, default=16 * 1024 * 1024, help="simulated file size (bytes)") | |
| p.add_argument("--step", type=int, default=1024 * 1024, help="bytes per seek window") | |
| args = p.parse_args() | |
| try: | |
| return asyncio.run(_run(args)) | |
| except KeyboardInterrupt: | |
| return 130 | |
| if __name__ == "__main__": | |
| sys.exit(main()) |