Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 3 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,9 @@ frameworks/blitz/zig-linux-*
frameworks/blitz/.zig-cache
frameworks/fletch/.dart_tool/
!frameworks/hyperf/bin/
frameworks/zix/.zig-cache
frameworks/zix/zig-out
frameworks/zix/vendor
frameworks/zix-grpc/.zig-cache
frameworks/zix-grpc/zig-out
frameworks/zix-grpc/vendor
frameworks/zix-ws/.zig-cache
frameworks/zix-ws/zig-out
frameworks/zix-ws/vendor
frameworks/zix*/.zig-cache
frameworks/zix*/zig-out
frameworks/zix*/vendor

# IDE settings
*.user
Expand Down
4 changes: 4 additions & 0 deletions frameworks/zix/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.zig-cache
zig-out
zig-package
vendor
76 changes: 40 additions & 36 deletions frameworks/zix/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ ARG RETRY=6
ARG TARGETARCH
ARG RETRY_DELAY=3
ARG ZIG_VERSION=0.16.0
ARG ZIX_VERSION=0.4.x-rc3
RUN apk add --no-cache ca-certificates curl git tar xz
ARG ZIX_VERSION=0.5.x-rc1
RUN apk add --no-cache ca-certificates curl git tar xz openssl

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

# Vendor zix X.Y.Z, 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 X.Y.Z 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.
WORKDIR /src
COPY build.zig build.zig.zon ./
COPY src ./src

# Resolve zix with zig fetch, then build in the same layer. The mirror and version fill the
# build.zig.zon placeholder, zig fetch downloads it and prints the hash. Codeberg first, GitHub second.
#
# Add +aes+pclmul: x86_64_v3 omits AES-NI / PCLMUL, so zix TLS would compile the ~40x slower
# software AES-GCM. Every x86_64_v3 CPU has them, so it is safe.
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; \
cp build.zig.zon build.zig.zon.tmpl; \
save_zix() { \
base="$1"; \
attempt=1; \
while [ "${attempt}" -le "${RETRY}" ]; do \
sed -e "s|{URL_ZIX_SOURCE}|${base}|g" -e "s|{ZIX_VERSION}|${ZIX_VERSION}|g" \
build.zig.zon.tmpl > build.zig.zon; \
if hash="$(zig fetch "${base}/${ZIX_VERSION}.tar.gz")"; then \
awk -v h="${hash}" '{ print } /\.url = /{ print " .hash = \"" h "\"," }' \
build.zig.zon > build.zig.zon.next; \
mv build.zig.zon.next build.zig.zon; \
return 0; \
fi; \
echo "zix: ${base} attempt ${attempt}/${RETRY} failed" >&2; \
attempt=$((attempt + 1)); \
sleep "${RETRY_DELAY}"; \
[ "${attempt}" -le "${RETRY}" ] && 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; \
save_zix "https://codeberg.org/prothegee/zix/archive" \
|| { echo "zix: codeberg exhausted ${RETRY} attempts, trying github" >&2; \
save_zix "https://github.com/prothegee/zix/archive/refs/heads"; } \
|| { echo "zix: github exhausted ${RETRY} attempts" >&2; exit 1; }; \
rm -f build.zig.zon.tmpl; \
case "${TARGETARCH:-amd64}" in \
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}" -Dcpu="${ZIG_CPU}" --release=fast
zig build -Dtarget="${ZIG_TARGET}" -Dcpu="${ZIG_CPU}+aes+pclmul+adx" --release=fast

# Self-signed Ed25519 cert generated at image build, baked at /etc/zix-tls. Ed25519 handshake
RUN set -eu; \
mkdir -p /etc/zix-tls; \
openssl genpkey -algorithm ED25519 -out /etc/zix-tls/server.key; \
openssl req -new -x509 -key /etc/zix-tls/server.key -out /etc/zix-tls/server.crt \
-days 3650 -subj "/CN=localhost"

FROM alpine:3.20
COPY --from=build /src/zig-out/bin/zix /zix
COPY --from=build /etc/zix-tls /etc/zix-tls
EXPOSE 8080
ENTRYPOINT ["/zix"]
2 changes: 1 addition & 1 deletion frameworks/zix/build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
.dependencies = .{
.zix = .{
.path = "vendor/zix",
.url = "{URL_ZIX_SOURCE}/{ZIX_VERSION}.tar.gz",
},
},
}
6 changes: 4 additions & 2 deletions frameworks/zix/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
"display_name": "zix",
"language": "Zig",
"type": "engine",
"engine": "zix",
"description": "Zig HTTP/1.1 server on the zix.Http1 raw engine (no std.http). Shared-nothing: each worker runs its own SO_REUSEPORT multishot accept plus io_uring completion loop and owns its connections. The /json endpoint serves from the per-worker response cache, and request bodies larger than the read buffer are drained rather than buffered.",
"engine": "zix uring",
"description": "Zig HTTP/1.1 server on the zix.Http1 raw engine (no std.http). Shared-nothing: each worker owns its SO_REUSEPORT accept, io_uring loop, and connections. /json serves from a per-worker cache and gzips the body (json-comp) when the client sends Accept-Encoding: gzip. json-tls serves the same /json over TLS 1.3 on a separate port with a baked self-signed Ed25519 cert. Oversized request bodies are drained, not buffered.",
"repo": "https://github.com/prothegee/zix",
"enabled": true,
"tests": [
"baseline",
"pipelined",
"limited-conn",
"json",
"json-comp",
"json-tls",
"upload",
"static"
],
Expand Down
2 changes: 1 addition & 1 deletion frameworks/zix/src/dataset.zig
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ fn renderItemPrefix(buf: *std.ArrayList(u8), aa: std.mem.Allocator, obj: std.jso
try buf.append(aa, ':');
try writeValue(buf, aa, kv.value_ptr.*);
}
// Intentionally no closing `}` caller appends `,"total":N}`.
// Intentionally no closing `}`: the caller appends `,"total":N}`.
}

fn writeValue(buf: *std.ArrayList(u8), aa: std.mem.Allocator, v: std.json.Value) !void {
Expand Down
Loading