• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubernetes-sigs / inference-perf / 34317783776
80%

Build:
DEFAULT BRANCH: main
Ran 09 Sep 2026 06:15AM UTC
Jobs 1
Files 116
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

09 Sep 2026 06:08AM UTC coverage: 78.379% (+0.09%) from 78.286%
34317783776

push

github

web-flow
feat(loadgen): bounded retry for pre-response transport faults (#780)

Fixes #777

## Problem

A replayed session is a dependency graph, so a single transport error
doesn't cost one
request — it cancels every event downstream of the failed one. Because
the cost depends on
*where* in the graph the fault landed rather than how serious it was, a
request error rate
well under 1% can erase a double-digit percentage of a run's events.
These are connection
faults, not rejected requests: the endpoint stays up and keeps
answering, it just closes
connections that are in flight or idle in the pool.

There is no retry anywhere in the model-server clients today — a
`ServerDisconnectedError`
goes straight to `process_failure` and the session is marked failed.

## What this does

Adds `load.request_retries` (default **0**) and
`load.request_retry_backoff_sec` (default
0.5, exponential with jitter). Default 0 preserves today's behavior
byte-for-byte.

```yaml
load:
  request_retries: 2
  request_retry_backoff_sec: 0.5
```

## Why only pre-first-byte

The retry boundary is deliberately narrow, and the aiohttp hierarchy
splits along exactly
the line we want:

- **Retried:** `aiohttp.ClientConnectionError` —
`ServerDisconnectedError`, `ClientOSError`.
- **Not retried:** `asyncio.TimeoutError`, even though
`ServerTimeoutError` inherits from
`ClientConnectionError`. A timeout may have reached the model, and
`request_timeout`
  applies **per attempt**, so re-sending multiplies the deadline.
- **Not retried:** `ClientPayloadError` — outside the family on purpose.
A body that broke
mid-transfer already produced a TTFT, so retrying it would report the
second attempt's
  latency instead of the original's.

A `response is None` guard backs the predicate up, so nothing raised
after headers arrive
is retried regardless of type.

What the boundary guarantees is specific: it avoids mixing partial
client-side response
measurements across attempts. It is *not* a claim that the server... (continued)

146 of 163 new or added lines in 8 files covered. (89.57%)

9208 of 11748 relevant lines covered (78.38%)

0.78 hits per line

Uncovered Changes

Lines Coverage ∆ File
10
84.2
-1.67% inference_perf/utils/cli_summary.py
3
81.3
2.07% inference_perf/client/modelserver/openai_client.py
2
92.94
-0.04% inference_perf/reportgen/base.py
1
91.8
0.71% inference_perf/apis/base.py
1
52.77
-0.02% inference_perf/client/modelserver/otel_instrumentation.py
Jobs
ID Job ID Ran Files Coverage
1 34317783776.1 09 Sep 2026 06:15AM UTC 116
78.38
GitHub Action Run
Source Files on build 34317783776
  • Tree
  • List 116
  • Changed 12
  • Source Changed 12
  • Coverage Changed 12
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #34317783776
  • 4d03e961 on github
  • Prev Build on main (#34299339164)
  • Next Build on main (#34476005319)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc