Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
286fb9e
vanilla: pin the V bootstrap, re-enable the four entries, size worker…
enghitalo Sep 30, 2026
7245ffb
vanilla-epoll, vanilla-io_uring: close after the response on Connecti…
enghitalo Sep 30, 2026
b919e8a
vanilla-epoll, vanilla-io_uring: record the json-tls verdict from val…
enghitalo Sep 30, 2026
45b70e1
vanilla-ws: subscribe to echo-ws-limited
enghitalo Sep 30, 2026
e58abcb
vanilla-epoll, vanilla-io_uring: async, 8gbit, latency-500k-8cpu, gat…
enghitalo Sep 30, 2026
54a47f1
vanilla-gateway: gateway-64 and gateway-h3 for vanilla-epoll
enghitalo Sep 30, 2026
66bf1af
vanilla-production: production-stack for vanilla-epoll
enghitalo Sep 30, 2026
b9415a6
vanilla-h2c: unary-grpc on :8080, per-connection buffers, vanilla @88…
enghitalo Sep 30, 2026
4cc0278
vanilla-h2c: vanilla @5012de9 (no allocation per request in http2), q…
enghitalo Sep 30, 2026
27ace46
vanilla-epoll, vanilla-io_uring: cache the RSA signing context in mbe…
enghitalo Sep 30, 2026
7b02a14
vanilla-epoll, vanilla-io_uring: retry the pg pool bring-up
enghitalo Sep 30, 2026
bf5dabc
vanilla-h2c: pin vanilla main @778ee95
enghitalo Sep 30, 2026
a76c415
vanilla-h2c, vanilla-ws: V @0c41fad, vanilla main @a6a73b0
enghitalo Sep 30, 2026
672280e
Benchmark results: 6 frameworks (all tests) [skip ci]
github-actions[bot] Sep 30, 2026
6cd0619
vanilla-epoll, vanilla-io_uring: port to vanilla main @a6a73b0 and V …
enghitalo Sep 30, 2026
fdcc95b
Merge remote-tracking branch 'origin/vanilla/pin-v-bootstrap' into va…
enghitalo Sep 30, 2026
86ec3f9
vanilla-*: V @b99970b
enghitalo Oct 1, 2026
9d1c98e
vanilla-epoll, vanilla-io_uring: static-tls over kTLS sendfile, vanil…
enghitalo Oct 1, 2026
0ab3d9d
vanilla-*: vanilla main @091c014
enghitalo Oct 1, 2026
af9a399
Benchmark results: 6 frameworks (all tests) [skip ci]
github-actions[bot] Oct 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 61 additions & 34 deletions frameworks/vanilla-epoll/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,52 @@ RUN apt-get -qq update && \
cmake curl bzip2 python3 && \
rm -rf /var/lib/apt/lists/*

# Pinned, reproducible V at master commit 02015a7c (built from source). Moved off
# the 0.5.1 tag: the codegen regression that forced the pin (single-element array
# push 4-7x slower, vlang/v#27468) is fixed (vlang/v#27470), and the vanilla library
# now uses `ArrayFlags.managed` (the buf_view non-marking window) which only exists
# on post-0.5.1 V. `make` bootstraps via the matching vc; if a much later rebuild
# ever fails to bootstrap, pin vlang/vc to the commit cut for this V.
RUN git clone https://github.com/vlang/v /opt/v && \
cd /opt/v && git checkout 02015a7ce111e4d0cfd5b5d78711ad0db7586936 && \
make && ln -s /opt/v/v /usr/local/bin/v
# Pinned, reproducible V at master commit b99970bd (0.5.2, built from source). The
# removed `json` module is replaced by x.json2 in main.v (encode with
# escape_unicode, so the /json bodies stay byte-identical).
#
# The bootstrap is pinned too. A bare `make` clones vlang/vc and vlang/tccbin at
# their CURRENT heads, so a fixed V source gets built by whatever compiler vc
# holds that day: that is what broke every V entry in #1288 ("C function C.open
# was already declared with a different signature"), and vc head has since
# failed in other ways. vc 2cbaf6bc is vc's newest snapshot (generated from V
# 0c41fadb, 40 commits earlier; vc has none for b99970bd yet), so it is what
# `make` bootstraps this V with today; tccbin d6e7ac1b is the head of tccbin's
# thirdparty-linux-amd64 branch, and `local=1` makes `make` build with both
# instead of pulling.
#
# Each repo is fetched at its one pinned commit (depth 1) rather than cloned:
# a full clone of v, vc and tccbin is hundreds of MB and a slow or flaky link
# stalls it past the validator's timeout; this is ~30 MB.
RUN git init -q /opt/v && cd /opt/v && \
git fetch -q --depth 1 https://github.com/vlang/v b99970bd438a7bdcdfbe38f74d9364db801d5439 && \
git checkout -q FETCH_HEAD && \
git init -q vc && \
git -C vc fetch -q --depth 1 https://github.com/vlang/vc 2cbaf6bc2367937cd5f0b4ef923d1ef9aad613b3 && \
git -C vc checkout -q FETCH_HEAD && \
git init -q thirdparty/tcc && \
git -C thirdparty/tcc fetch -q --depth 1 https://github.com/vlang/tccbin d6e7ac1b1bcc98aed734a6ecbfa8509f24606c74 && \
git -C thirdparty/tcc checkout -q FETCH_HEAD && \
make local=1 && ln -s /opt/v/v /usr/local/bin/v

# Install the vanilla HTTP server as the `vanilla` module (import vanilla.http_server),
# pinned to a specific commit: reproducible, and with NO per-build network call to
# detect changes. The previous approach `ADD`ed the GitHub API main-ref URL to cache-bust
# whenever main moved, but that hit api.github.com on every build and a transient 504
# (or rate-limit) failed the whole build (MDA2AV/HttpArena#895). To pick up upstream
# library fixes, bump this commit.
# Install vanilla as the `vanilla` module (import vanilla.server, vanilla.core, ...),
# pinned to a specific commit: reproducible, with NO per-build network call to
# detect changes. The previous approach `ADD`ed the GitHub API main-ref URL to
# cache-bust whenever main moved, but that hit api.github.com on every build and a
# transient 504 (or rate-limit) failed the whole build (MDA2AV/HttpArena#895). To
# pick up upstream library fixes, bump this commit.
#
# Pinned to vanilla main @be46940 — carries enghitalo/vanilla#101 (epoll async-runtime
# hardening, the twins found while building the io_uring async runtime #99: a `.done`
# resume now DRAINS requests pipelined behind a parked one that were already buffered;
# drain_pipelined deactivates a fully-drained queue inline BEFORE the serve that may
# re-park — the old trailing epilogue stranded such re-parks; and a watch registered by
# a handler whose park was rejected is torn down instead of leaking an active entry on
# a soon-reused client_fd). Also #96 (epoll TLS stateful make_state fix; inert for this
# entry's stateless TLS listener) and #94/#99 (io_uring-only). Previously @b189036 — the lib-wide alloc audit (#72 pg_async, #73
# static_assets, #74 TLS buffer pooling), kTLS record offload for json-tls
# (enghitalo/vanilla#79; after the Mbed TLS handshake the kernel does TLS 1.3 record
# AES-128-GCM via setsockopt TLS_TX+TLS_RX, so the epoll worker's steady-state
# read/write are plain recv/send), PLUS static_assets `url_prefix` (#80) and
# core.queue_buf borrowed send (#81) — this entry serves /static/* through the
# audited static_assets module (precompressed .br/.gz negotiation + ETag/Vary,
# sendfile for the large siblings) instead of a hand-rolled identity-only map.
RUN git clone https://github.com/enghitalo/vanilla /root/.vmodules/vanilla && \
git -C /root/.vmodules/vanilla checkout be46940b624363ed93991d3166f950143ee14c7b
# Pinned to vanilla main @091c014: top-level modules and one handler contract
# (core.Handler returning core.Step, watches through core.EventLoop), which main.v
# uses for both listeners. /static/* goes through the static_assets module on both:
# precompressed .br/.gz negotiation + ETag/Vary, snapshots that follow the disk
# (enghitalo/vanilla#180), and sendfile for bodies of 16 KiB or more, on :8080 and,
# over kTLS, on the :8081 TLS listener (enghitalo/vanilla#181; a userspace-TLS
# connection gets the bytes from RAM). Fetched at that one commit.
RUN git init -q /root/.vmodules/vanilla && \
git -C /root/.vmodules/vanilla fetch -q --depth 1 https://github.com/enghitalo/vanilla \
091c014a0191afd7e740b84f5599b9b1fc1fd914 && \
git -C /root/.vmodules/vanilla checkout -q FETCH_HEAD

# Mbed TLS 4 for the json-tls profile. The vanilla `tls` module's C shim
# (vanilla_tls.c, built with `-d vanilla_tls`) targets the Mbed TLS 4.x API
Expand All @@ -49,11 +61,22 @@ RUN git clone https://github.com/enghitalo/vanilla /root/.vmodules/vanilla && \
# tls_mbedtls_d_vanilla_tls.c.v (-L/usr/local/lib -lmbedtls -lmbedx509
# -lmbedcrypto). 4.x also produces libtfpsacrypto (the TF-PSA-Crypto split),
# linked transitively. Headers land in /usr/local/include for the build.
#
# mbedtls-rsa-sign-cache.patch (against 4.1.0): unpatched, every PSA RSA
# signature re-parses the key and regenerates the RSA blinding values from
# scratch, which was most of each TLS 1.3 handshake with the harness's
# RSA-2048 certificate (~11 ms of CPU). The patch keeps the signing key's
# parsed context in a per-thread cache, so blinding is updated by squaring
# as with any long-lived mbedtls_rsa_context; with -O3 -march=native a
# handshake costs ~8 ms. That is what 8gbit (512 fresh connections) and
# json-tls (4096) pay up front before the first request is answered.
ARG MBEDTLS_VERSION=4.1.0
COPY mbedtls-rsa-sign-cache.patch /tmp/
RUN curl -fsSL -o /tmp/mbedtls.tar.bz2 \
"https://github.com/Mbed-TLS/mbedtls/releases/download/mbedtls-${MBEDTLS_VERSION}/mbedtls-${MBEDTLS_VERSION}.tar.bz2" && \
tar -xf /tmp/mbedtls.tar.bz2 -C /tmp && \
cd "/tmp/mbedtls-${MBEDTLS_VERSION}" && \
patch -p1 < /tmp/mbedtls-rsa-sign-cache.patch && \
# THREAD-SAFETY (load-bearing): vanilla runs N TLS worker threads, each driving
# TLS 1.3 handshakes through Mbed TLS's PSA crypto, whose key store is a GLOBAL,
# process-wide table. Without MBEDTLS_THREADING_C the concurrent handshakes race
Expand All @@ -65,7 +88,7 @@ RUN curl -fsSL -o /tmp/mbedtls.tar.bz2 \
python3 tf-psa-crypto/scripts/config.py set MBEDTLS_THREADING_C && \
python3 tf-psa-crypto/scripts/config.py set MBEDTLS_THREADING_PTHREAD && \
cmake -S "/tmp/mbedtls-${MBEDTLS_VERSION}" -B /tmp/mbedtls-build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS_RELEASE="-O3 -march=native -DNDEBUG" \
-DUSE_SHARED_MBEDTLS_LIBRARY=On -DUSE_STATIC_MBEDTLS_LIBRARY=Off \
-DENABLE_TESTING=Off -DENABLE_PROGRAMS=Off \
-DCMAKE_INSTALL_PREFIX=/usr/local && \
Expand Down Expand Up @@ -95,4 +118,8 @@ COPY --from=build /app/server /server
# bind-mounts the cert/key at /certs and the server reads /certs/server.{crt,key}
# (override via TLS_CERT/TLS_KEY); with no cert mounted it self-signs.
EXPOSE 8080 8081
CMD ["/server"]
# One worker per CPU the container may run on. vanilla defaults to nr_cpus,
# which reads the host's online CPUs (128 on the bench box) and ignores the
# cpuset, so a 64-CPU profile started 128 workers and latency-500k-8cpu would
# start 128 on 8. nproc honours the cpuset; an explicit VANILLA_WORKERS wins.
CMD ["/bin/sh", "-c", "VANILLA_WORKERS=${VANILLA_WORKERS:-$(nproc)} exec /server"]
Loading