| 541 | |
| 542 | |
| 543 | async def _witness( |
| 544 | url: str, |
| 545 | rng: random.Random, |
| 546 | deadline: float, |
| 547 | interval_s: float, |
| 548 | witness_results: list[Result], |
| 549 | test_start: float, |
| 550 | ) -> None: |
| 551 | import aiohttp |
| 552 | |
| 553 | timeout = aiohttp.ClientTimeout(total=120) |
| 554 | connector = aiohttp.TCPConnector(limit=4, force_close=True) |
| 555 | async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session: |
| 556 | while time.perf_counter() < deadline: |
| 557 | t0 = time.perf_counter() |
| 558 | status = 0 |
| 559 | err = "" |
| 560 | nbytes = 0 |
| 561 | try: |
| 562 | async with session.get( |
| 563 | f"{url}/", timeout=aiohttp.ClientTimeout(total=60) |
| 564 | ) as resp: |
| 565 | status = resp.status |
| 566 | body = await resp.read() |
| 567 | nbytes = len(body) |
| 568 | ok = 200 <= status < 400 |
| 569 | except Exception as e: |
| 570 | ok = False |
| 571 | err = f"{type(e).__name__}: {e}"[:120] |
| 572 | latency_ms = (time.perf_counter() - t0) * 1000.0 |
| 573 | witness_results.append( |
| 574 | Result( |
| 575 | ok=ok, |
| 576 | status=status, |
| 577 | latency_ms=latency_ms, |
| 578 | bytes=nbytes, |
| 579 | t_end_s=time.perf_counter() - test_start, |
| 580 | err=err, |
| 581 | ) |
| 582 | ) |
| 583 | await asyncio.sleep(max(0.0, interval_s - (time.perf_counter() - t0))) |
| 584 | |
| 585 | |
| 586 | async def run_slowread(args: argparse.Namespace) -> dict: |