Snapshot of the in-flight state that already existed, identically, in both this worktree and the main checkout before this session began: the initial HTTP Client platform implementation (previously untracked), the redis-lab removal, and the JPA / object-storage / notification integration work. Kept separate from this session's HTTP Client review response, which lands in the following commit, so the two bodies of work stay reviewable apart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
56 lines
2.6 KiB
Markdown
56 lines
2.6 KiB
Markdown
# HTTP Client Platform — Performance Baseline
|
|
|
|
The certification lane asserts **resource bounds**, not throughput targets. Its purpose is to prove
|
|
that a failing upstream, a large body, or a rotation cannot consume unbounded memory, connections,
|
|
threads, or upstream traffic. Nothing here becomes a runtime adaptive default: every bound comes
|
|
from an explicit profile setting.
|
|
|
|
## How to run
|
|
|
|
```bash
|
|
# structural bounds only (default; still executes every test)
|
|
./gradlew :adapter:outbound:httpclient:httpClientPerformanceTest --console=plain
|
|
|
|
# full certification, including machine-dependent bounds
|
|
./gradlew :adapter:outbound:httpclient:httpClientPerformanceTest \
|
|
-Pperformance.assertions.enabled=true --console=plain
|
|
|
|
# JMH benchmarks
|
|
./gradlew :adapter:outbound:httpclient:jmh --console=plain
|
|
```
|
|
|
|
Machine-dependent assertions are reported as explicitly skipped when the flag is absent — the lane
|
|
never silently degrades into a pass.
|
|
|
|
## Certified bounds
|
|
|
|
| Test | Bound | Kind |
|
|
|---|---|---|
|
|
| `RetryStormBudgetTest` | 10 000 logical calls against a failing upstream produce at most 11 000 physical attempts at a 10 % budget | structural |
|
|
| `LargeBodyResourceTest` | a 32 MiB streaming download consumes every byte without buffering the payload on the heap | structural + machine-dependent heap bound |
|
|
| `PoolSaturationPerformanceTest` | 24 concurrent calls against a 4-connection pool all reach a terminal outcome; none hang | structural |
|
|
| `Http2StreamSaturationTest` | 32 concurrent reactive streams share a 2-connection pool and complete | structural |
|
|
| `OAuthRefreshContentionTest` | 100 genuinely concurrent callers produce exactly one token request | structural |
|
|
| `RuntimeRotationDrainTest` | 50 rotations close all 50 retired generations and leave no drain thread | structural |
|
|
|
|
## Recording a baseline
|
|
|
|
When certifying a deployment, record alongside the numbers: the exact command, the commit, hardware,
|
|
JVM flags, the profile YAML under test, p50/p95/p99/max, peak heap, peak direct memory, thread count,
|
|
connection count, physical attempt count, and error count. A latency figure without its profile and
|
|
hardware is not a baseline; it is an anecdote.
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Command | _fill in at certification time_ |
|
|
| Commit | _fill in_ |
|
|
| Hardware / JVM | _fill in_ |
|
|
| Profile under test | _fill in_ |
|
|
| p50 / p95 / p99 / max | _fill in_ |
|
|
| Peak heap / direct memory | _fill in_ |
|
|
| Threads / connections | _fill in_ |
|
|
| Physical attempts / errors | _fill in_ |
|
|
|
|
The table is intentionally left unfilled in the repository: publishing numbers measured on a build
|
|
agent as if they were a certified baseline would be worse than having none.
|