Skip to content

refactor(vanilla-epoll): extract shared emit_xcache helper for io_uring parity#966

Closed
enghitalo wants to merge 1 commit into
MDA2AV:mainfrom
enghitalo:refactor/vanilla-epoll-emit-xcache
Closed

refactor(vanilla-epoll): extract shared emit_xcache helper for io_uring parity#966
enghitalo wants to merge 1 commit into
MDA2AV:mainfrom
enghitalo:refactor/vanilla-epoll-emit-xcache

Conversation

@enghitalo

Copy link
Copy Markdown
Contributor

What & why

Small maintainability refactor, paired with the vanilla-io_uring convergence PR. vanilla-epoll inlined the crud X-Cache response framing in two places (the crud GET cache hit and miss paths). This folds both into one emit_xcache helper.

The helper is byte-identical to the code it replaces, and identical to the emit_xcache now used by the vanilla-io_uring twin — so both entries share one audited X-Cache framing and diff cleanly. vanilla-epoll remains the performance reference; this only removes duplication.

Change

  • Add emit_xcache(mut out, ctype, body, cache) next to emit / write_resp.
  • Use it in start_crud_get (HIT) and render_crud_get (MISS).

No behavior or performance change.

Validation

Verified against a seeded Postgres that the crud GET MISS and HIT responses are byte-for-byte unchanged (and identical to the vanilla-io_uring twin, whose full-route byte-diff is covered in its PR).

🤖 Generated with Claude Code

…-Cache framing

Fold the two inlined X-Cache response framings (crud GET hit/miss) into one
emit_xcache helper — byte-identical output, and identical to the vanilla-io_uring
twin's emit_xcache, so both entries share one audited framing and diff cleanly.
No behavior or performance change (validated: crud GET MISS/HIT bytes unchanged).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@enghitalo

Copy link
Copy Markdown
Contributor Author

/benchmark -f vanilla-epoll

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

👋 /benchmark request received. A collaborator will review and approve the run.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

Framework: vanilla-epoll | Test: all tests

Test Conn RPS CPU Mem Δ RPS Δ Mem
baseline 512 3,664,027 6396.2% 77MiB -1.5% -1.3%
baseline 4096 4,078,658 6294.8% 154MiB -1.7% -3.1%
pipelined 512 39,394,796 6663.2% 73MiB -1.0% ~0%
pipelined 4096 39,802,857 6700.5% 163MiB -0.5% -0.6%
limited-conn 512 994,879 3188.1% 67MiB -0.7% ~0%
limited-conn 4096 1,015,795 3066.5% 99MiB -0.8% +39.4%
json 4096 2,151,652 6411.7% 185MiB -0.2% -2.6%
json-comp 512 2,103,334 6205.8% 82MiB +0.7% -13.7%
json-comp 4096 2,351,582 6457.6% 127MiB +1.2% -16.4%
json-comp 16384 2,326,732 6422.9% 172MiB +1.2% -34.1%
json-tls 4096 1,509,843 6125.5% 450MiB +0.6% +13.1%
upload 32 2,951 2112.6% 131MiB -0.2% -2.2%
upload 256 3,013 3744.3% 306MiB -0.1% -9.5%
api-4 256 67,006 399.6% 113MiB +6.1% +0.9%
api-16 1024 237,387 1332.8% 198MiB -3.7% +7.6%
static 1024 1,798,059 5734.3% 98MiB +0.2% +1.0%
static 4096 1,776,200 5712.6% 222MiB -0.2% -0.9%
static 6800 1,754,454 5380.1% 310MiB +1.1% -1.0%
async-db 1024 288,343 2999.7% 139MiB +0.3% -2.8%
crud 4096 313,530 787.8% 217MiB +0.9% -0.5%
fortunes 1024 168,464 6000.3% 255MiB +0.9% -0.8%
Full log
  Templates: 20
  Expected:  200
  Duration:  15s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   11.30ms    876us   34.30ms   73.40ms   112.20ms

  4771944 requests in 15.00s, 4771946 responses
  Throughput: 318.07K req/s
  Bandwidth:  95.72MB/s
  Status codes: 2xx=4702958, 3xx=0, 4xx=0, 5xx=68988
  Latency samples: 4771943 / 4771946 responses (100.0%)
  Reconnects: 22313
  Per-template: 96798,120868,156281,187940,218868,249279,279198,305940,326336,339432,346967,352003,353963,354602,355605,358091,128212,63371,83386,94803
  Per-template-ok: 93268,119253,154108,185391,216094,245802,275408,301535,322055,334923,342130,347487,349383,349815,350890,353364,128212,61585,80712,91540

  WARNING: 68988/4771946 responses (1.4%) had unexpected status (expected 2xx)
[info] CPU 787.8% | Mem 217MiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  200
  Templates: 20
  Expected:  200
  Duration:  15s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   12.41ms   6.25ms   34.90ms   66.00ms   93.70ms

  4416611 requests in 15.00s, 4416419 responses
  Throughput: 294.38K req/s
  Bandwidth:  90.09MB/s
  Status codes: 2xx=4341662, 3xx=0, 4xx=0, 5xx=74757
  Latency samples: 4416415 / 4416419 responses (100.0%)
  Reconnects: 20475
  Per-template: 102200,120638,149934,176622,205341,234778,258692,282248,299246,305005,308650,310653,310636,312729,314104,312248,144166,78688,90353,99484
  Per-template-ok: 99137,118789,147654,173622,201820,230705,254409,277650,294037,299889,303630,305264,305615,307537,308821,307057,144166,77022,87630,97204

  WARNING: 74757/4416419 responses (1.7%) had unexpected status (expected 2xx)
[info] CPU 768.9% | Mem 227MiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/
  Threads:   64
  Conns:     4096 (64/thread)
  Pipeline:  1
  Req/conn:  200
  Templates: 20
  Expected:  200
  Duration:  15s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   12.77ms   7.61ms   34.00ms   62.40ms   87.50ms

  4319316 requests in 15.00s, 4319316 responses
  Throughput: 287.91K req/s
  Bandwidth:  89.14MB/s
  Status codes: 2xx=4261635, 3xx=0, 4xx=0, 5xx=57681
  Latency samples: 4319311 / 4319316 responses (100.0%)
  Reconnects: 19860
  Per-template: 105613,121909,150361,176550,205127,231788,256053,276167,288293,295667,298383,297641,297792,296264,295572,294669,152529,84336,91432,103165
  Per-template-ok: 102848,120516,148413,174232,202202,228575,252875,272780,284570,291708,294612,293955,293978,292307,291816,290804,152529,82626,89422,100862

  WARNING: 57681/4319316 responses (1.3%) had unexpected status (expected 2xx)
[info] CPU 772.8% | Mem 232MiB

=== Best: 313530 req/s (CPU: 787.8%, Mem: 217MiB) ===
[info] input BW: 26.91MB/s (avg template: 90 bytes)
[info] saved results/crud/4096/vanilla-epoll.json
httparena-bench-vanilla-epoll
httparena-bench-vanilla-epoll

==============================================
=== vanilla-epoll / fortunes / 1024c (tool=gcannon) ===
==============================================
[info] resetting postgres for a clean per-profile baseline
[info] starting postgres sidecar
httparena-postgres
[info] postgres ready (seeded)
[info] waiting for server...
[info] server ready

[run 1/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.66ms   3.68ms   8.55ms   15.40ms   32.20ms

  842320 requests in 5.00s, 842320 responses
  Throughput: 168.40K req/s
  Bandwidth:  3.90GB/s
  Status codes: 2xx=842320, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 842319 / 842320 responses (100.0%)
[info] CPU 6000.3% | Mem 255MiB

[run 2/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.72ms   3.88ms   8.86ms   14.30ms   19.00ms

  822880 requests in 5.00s, 822880 responses
  Throughput: 164.51K req/s
  Bandwidth:  3.81GB/s
  Status codes: 2xx=822880, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 822876 / 822880 responses (100.0%)
[info] CPU 5969.6% | Mem 256MiB

[run 3/3]
gcannon v0.5.3
  Target:    localhost:8080/fortunes
  Threads:   64
  Conns:     1024 (16/thread)
  Pipeline:  1
  Req/conn:  unlimited (keep-alive)
  Expected:  200
  Duration:  5s


  Thread Stats   Avg      p50      p90      p99    p99.9
    Latency   4.83ms   4.20ms   8.79ms   13.40ms   17.70ms

  813881 requests in 5.00s, 813881 responses
  Throughput: 162.72K req/s
  Bandwidth:  3.77GB/s
  Status codes: 2xx=813881, 3xx=0, 4xx=0, 5xx=0
  Latency samples: 813876 / 813881 responses (100.0%)
[info] CPU 5838.8% | Mem 257MiB

=== Best: 168464 req/s (CPU: 6000.3%, Mem: 255MiB) ===
[info] saved results/fortunes/1024/vanilla-epoll.json
httparena-bench-vanilla-epoll
httparena-bench-vanilla-epoll
[info] skip: vanilla-epoll does not subscribe to baseline-h2
[info] skip: vanilla-epoll does not subscribe to static-h2
[info] skip: vanilla-epoll does not subscribe to baseline-h2c
[info] skip: vanilla-epoll does not subscribe to json-h2c
[info] skip: vanilla-epoll does not subscribe to baseline-h3
[info] skip: vanilla-epoll does not subscribe to static-h3
[info] skip: vanilla-epoll does not subscribe to gateway-64
[info] skip: vanilla-epoll does not subscribe to gateway-h3
[info] skip: vanilla-epoll does not subscribe to production-stack
[info] skip: vanilla-epoll does not subscribe to unary-grpc
[info] skip: vanilla-epoll does not subscribe to unary-grpc-tls
[info] skip: vanilla-epoll does not subscribe to stream-grpc
[info] skip: vanilla-epoll does not subscribe to stream-grpc-tls
[info] skip: vanilla-epoll does not subscribe to echo-ws
[info] skip: vanilla-epoll does not subscribe to echo-ws-pipeline
[info] rebuilding site/data/*.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/frameworks.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/api-16-1024.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/api-4-256.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/async-db-1024.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/baseline-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/baseline-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/crud-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/fortunes-1024.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-comp-16384.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-comp-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-comp-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/json-tls-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/limited-conn-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/limited-conn-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/pipelined-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/pipelined-512.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/static-1024.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/static-4096.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/static-6800.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/upload-256.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/upload-32.json
[updated] /home/diogo/actions-runner/_work/HttpArena/HttpArena/site/data/current.json
[info] done
httparena-postgres
httparena-redis
[info] restoring loopback MTU to 65536

@enghitalo

Copy link
Copy Markdown
Contributor Author

/benchmark -f vanilla-epoll --save

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

👋 /benchmark request received. A collaborator will review and approve the run.

@enghitalo

Copy link
Copy Markdown
Contributor Author

Superseded by #968 — same emit_xcache refactor, reopened clean on current main.

@enghitalo enghitalo closed this Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant