Skip to content
63 changes: 43 additions & 20 deletions frameworks/zix-grpc/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
# syntax=docker/dockerfile:1.7
#
# zix-grpc. Zig gRPC h2c server using the zix library.
# EPOLL dispatch: single accept loop + worker pool, EPOLLONESHOT per stream.
# Implements benchmark.BenchmarkService/GetSum (unary) and StreamSum (server-streaming).
# Built statically against musl so the runtime image is a single binary on scratch.

FROM debian:bookworm-slim AS build
ARG ZIG_VERSION=0.16.0
FROM alpine:3.20 AS build
ARG RETRY=6
ARG TARGETARCH
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl xz-utils \
&& rm -rf /var/lib/apt/lists/*
ARG RETRY_DELAY=3
ARG ZIG_VERSION=0.16.0
ARG ZIX_VERSION=0.4.x
RUN apk add --no-cache ca-certificates curl git tar xz

RUN set -eu; \
case "${TARGETARCH:-amd64}" in \
Expand All @@ -24,23 +19,51 @@ RUN set -eu; \
mv "/opt/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}" /opt/zig
ENV PATH="/opt/zig:${PATH}"

# Vendor zix 0.3.x, separate layer so source-only rebuilds skip the download.
# Strip the top-level directory produced by GitHub's archive.
RUN mkdir -p /src/vendor/zix && \
curl -fsSL https://github.com/prothegee/zix/archive/refs/heads/0.3.x.tar.gz \
| tar -xz --strip-components=1 -C /src/vendor/zix
# Vendor zix 0.4.x, separate layer so source-only rebuilds skip the fetch.
# The Http1 raw engine work this image needs (large-body drain plus the per-worker
# response cache used by the /json endpoint) must be present on the 0.4.x branch.
# Four ordered attempts before giving up: curl the archive tarball from github then
# codeberg, then a shallow git clone from github then codeberg. The github archive
# redirects to codeload.github.com (which the benchmark runner may not resolve), so
# curl can fall through to the codeberg tarball, and git clone talks to github.com
# and codeberg.org directly as the deeper fallback. RETRY and RETRY_DELAY bound
# every attempt.
RUN set -eu; \
fetch() { \
rm -rf /src/vendor/zix; mkdir -p /src/vendor/zix; \
curl -fsSL --retry ${RETRY} --retry-delay ${RETRY_DELAY} --retry-all-errors "$1" -o /tmp/zix.tar.gz \
&& tar -xz --strip-components=1 -C /src/vendor/zix -f /tmp/zix.tar.gz; \
}; \
clone() { \
attempt=0; \
while [ "${attempt}" -lt "${RETRY}" ]; do \
rm -rf /src/vendor/zix; \
git clone --depth 1 --branch "${ZIX_VERSION}" "$1" /src/vendor/zix && return 0; \
attempt=$((attempt + 1)); \
sleep "${RETRY_DELAY}"; \
done; \
return 1; \
}; \
fetch "https://github.com/prothegee/zix/archive/refs/heads/${ZIX_VERSION}.tar.gz" \
|| { echo "FAILED: curl ${RETRY} times from github" >&2; \
fetch "https://codeberg.org/prothegee/zix/archive/${ZIX_VERSION}.tar.gz" \
|| { echo "FAILED: curl ${RETRY} times from codeberg" >&2; \
clone "https://github.com/prothegee/zix.git" \
|| { echo "FAILED: git clone ${RETRY} times from github" >&2; \
clone "https://codeberg.org/prothegee/zix.git" \
|| { echo "FAILED: git clone ${RETRY} times from codeberg" >&2; exit 1; }; }; }; }

WORKDIR /src
COPY build.zig build.zig.zon ./
COPY src ./src
RUN set -eu; \
case "${TARGETARCH:-amd64}" in \
amd64) ZIG_TARGET=x86_64-linux-musl ;; \
arm64) ZIG_TARGET=aarch64-linux-musl ;; \
amd64) ZIG_TARGET=x86_64-linux-musl; ZIG_CPU=x86_64_v3 ;; \
arm64) ZIG_TARGET=aarch64-linux-musl; ZIG_CPU=baseline ;; \
esac; \
zig build -Dtarget="${ZIG_TARGET}" --release=fast
zig build -Dtarget="${ZIG_TARGET}" -Dcpu="${ZIG_CPU}" --release=fast

FROM debian:bookworm-slim
FROM alpine:3.20
COPY --from=build /src/zig-out/bin/zix-grpc /zix-grpc
EXPOSE 8080
ENTRYPOINT ["/zix-grpc"]
4 changes: 2 additions & 2 deletions frameworks/zix-grpc/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"language": "Zig",
"type": "engine",
"engine": "zix",
"description": "Zig gRPC h2c server using the zix framework. Single epoll event loop; worker pool handles one stream per slot. Implements GetSum (unary) and StreamSum (server-streaming).",
"repo": "https://github.com/prothegee/zix",
"description": "Zig gRPC h2c server using the zix network backend library. Shared-nothing io_uring: each worker owns its own ring and listener, multiplexing streams per connection. Implements GetSum (unary) and StreamSum (server-streaming).",
"repo": "https://codeberg.org/prothegee/zix",
"enabled": true,
"tests": [
"unary-grpc",
Expand Down
17 changes: 15 additions & 2 deletions frameworks/zix-grpc/src/main.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
//! HttpArena: zix-grpc
//! zix version: 0.3.0
//! zix version: 0.4.x
//!
//! zix HttpArena gRPC (h2c) entry point.
//!
//! Intent: demonstrate zix.Grpc (EPOLL dispatch model) against the HttpArena
//! gRPC benchmark suite (unary, server-streaming).
//!
//! Design choices:
//! - GetSum: unary SumRequest{a, b} -> SumReply{a + b}. The compute is a single
//! add and the reply is a few bytes, well below the response-cache crossover,
//! so caching would cost more than it saves and stays off here.
//! - StreamSum: server-streaming, count replies of a + b + i.
//! - max_streams is wide enough that a client opening many parallel streams is
//! never refused at startup.
const std = @import("std");
const zix = @import("zix");

Expand All @@ -8,7 +21,7 @@ const zix = @import("zix");
const PORT: u16 = 8080;
/// Required for ipv4 and ipv6
const LISTEN_IP: []const u8 = "::";
const DISPATCH_MODEL: zix.Grpc.DispatchModel = .EPOLL;
const DISPATCH_MODEL: zix.Grpc.DispatchModel = .URING;
const KERNEL_BACKLOG: u31 = 1024 * 16;
const WORKERS: usize = 0;

Expand Down
4 changes: 2 additions & 2 deletions site/data/frameworks.json
Original file line number Diff line number Diff line change
Expand Up @@ -901,8 +901,8 @@
},
"zix-grpc": {
"dir": "zix-grpc",
"description": "Zig gRPC h2c server using the zix framework. Single epoll event loop; worker pool handles one stream per slot. Implements GetSum (unary) and StreamSum (server-streaming).",
"repo": "https://github.com/prothegee/zix",
"description": "Zig gRPC h2c server using the zix network backend library. Shared-nothing io_uring: each worker owns its own ring and listener, multiplexing streams per connection. Implements GetSum (unary) and StreamSum (server-streaming).",
"repo": "https://codeberg.org/prothegee/zix",
"type": "engine",
"engine": "zix"
},
Expand Down
14 changes: 7 additions & 7 deletions site/data/stream-grpc-64.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,20 @@
{
"framework": "zix-grpc",
"language": "Zig",
"rps": 8331000,
"avg_latency": "143.74ms",
"p99_latency": "812.02ms",
"cpu": "44.3%",
"memory": "90MiB",
"rps": 8468000,
"avg_latency": "146.13ms",
"p99_latency": "385.19ms",
"cpu": "37.9%",
"memory": "141MiB",
"connections": 64,
"threads": 64,
"duration": "5s",
"pipeline": 1,
"bandwidth": "0",
"reconnects": 0,
"status_2xx": 8331,
"status_2xx": 8468,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 144
"status_5xx": 0
}
]
13 changes: 7 additions & 6 deletions site/data/unary-grpc-1024.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,18 @@
{
"framework": "zix-grpc",
"language": "Zig",
"rps": 6895367,
"avg_latency": "7.74ms",
"cpu": "3933.8%",
"memory": "1.1GiB",
"rps": 7122075,
"avg_latency": "7.63ms",
"p99_latency": "84.09ms",
"cpu": "3008.6%",
"memory": "1.2GiB",
"connections": 1024,
"threads": 64,
"duration": "5s",
"pipeline": 1,
"bandwidth": "438.36MB/s",
"bandwidth": "453.67MB/s",
"reconnects": 0,
"status_2xx": 34821605,
"status_2xx": 36037700,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
Expand Down
13 changes: 7 additions & 6 deletions site/data/unary-grpc-256.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,18 @@
{
"framework": "zix-grpc",
"language": "Zig",
"rps": 7041146,
"avg_latency": "2.29ms",
"cpu": "3801.9%",
"memory": "346MiB",
"rps": 7239103,
"avg_latency": "2.22ms",
"p99_latency": "45.43ms",
"cpu": "2927.0%",
"memory": "394MiB",
"connections": 256,
"threads": 64,
"duration": "5s",
"pipeline": 1,
"bandwidth": "447.62MB/s",
"bandwidth": "457.47MB/s",
"reconnects": 0,
"status_2xx": 35557792,
"status_2xx": 36340300,
"status_3xx": 0,
"status_4xx": 0,
"status_5xx": 0
Expand Down
1 change: 0 additions & 1 deletion site/static/logs/stream-grpc/64/zix-grpc.log
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
zix grpc server (epoll mux): :::8080 (64 workers)
1 change: 0 additions & 1 deletion site/static/logs/unary-grpc/1024/zix-grpc.log
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
zix grpc server (epoll mux): :::8080 (64 workers)
1 change: 0 additions & 1 deletion site/static/logs/unary-grpc/256/zix-grpc.log
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
zix grpc server (epoll mux): :::8080 (64 workers)