diff --git a/Dockerfile b/Dockerfile index 3854d7a..a72b981 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,30 +1,43 @@ -# multi-stage build: compile natively inside x86_64 linux container -# uses Debian (glibc) because zig's C++ codegen for musl -# produces illegal instructions in RocksDB's LRU cache -FROM --platform=linux/amd64 debian:bookworm-slim AS builder +# Multi-stage build for Linux amd64 and arm64. The build runs natively for the +# selected Docker platform; production selects linux/amd64 explicitly. +FROM debian:bookworm-slim AS builder +ARG ZIG_VERSION=0.16.0 RUN apt-get update && apt-get install -y --no-install-recommends curl xz-utils ca-certificates && rm -rf /var/lib/apt/lists/* -RUN curl -fSL https://ziglang.org/builds/zig-x86_64-linux-0.16.0-dev.3059+42e33db9d.tar.xz \ - | tar xJ -C /opt -ENV PATH=/opt/zig-x86_64-linux-0.16.0-dev.3059+42e33db9d:$PATH +RUN set -eux; \ + case "$(dpkg --print-architecture)" in \ + amd64) zig_arch=x86_64; zig_sha256=70e49664a74374b48b51e6f3fdfbf437f6395d42509050588bd49abe52ba3d00 ;; \ + arm64) zig_arch=aarch64; zig_sha256=ea4b09bfb22ec6f6c6ceac57ab63efb6b46e17ab08d21f69f3a48b38e1534f17 ;; \ + *) echo "unsupported architecture: $(dpkg --print-architecture)" >&2; exit 1 ;; \ + esac; \ + curl -fSL "https://ziglang.org/download/${ZIG_VERSION}/zig-${zig_arch}-linux-${ZIG_VERSION}.tar.xz" -o /tmp/zig.tar.xz; \ + echo "${zig_sha256} /tmp/zig.tar.xz" | sha256sum --check -; \ + tar xJf /tmp/zig.tar.xz -C /opt; \ + rm /tmp/zig.tar.xz; \ + mv "/opt/zig-${zig_arch}-linux-${ZIG_VERSION}" /opt/zig +ENV PATH=/opt/zig:$PATH WORKDIR /build -# patch Io.Uring networking (stubbed as Unavailable upstream, zig#31723) -COPY patches/ patches/ -RUN patch /opt/zig-x86_64-linux-0.16.0-dev.3059+42e33db9d/lib/std/Io/Uring.zig < patches/uring-networking.patch - # fetch dependencies first (cacheable — only changes when build.zig.zon changes) COPY build.zig build.zig.zon ./ -RUN zig build --fetch-only 2>/dev/null || true +RUN for delay in 0 2 5; do \ + sleep "$delay"; \ + zig build --fetch=all && exit 0; \ + done; \ + exit 1 # then copy source and build COPY src/ src/ -# ReleaseFast: Evented + ReleaseSafe GPFs immediately on startup (fiber.zig -# contextSwitch, confirmed 2026-04-05). This is a zig codegen bug, not our code. -# ReleaseFast avoids the bad optimization path. The previous production SIGSEGV -# under ReleaseFast was a websocket handshake bug, now fixed (9ac64da). -RUN zig build -Doptimize=ReleaseSafe -Dcpu=baseline -Dtarget=x86_64-linux-gnu +# Io.Threaded is the production backend; the old Io.Uring stdlib patch is not +# needed. Keep glibc for its allocator behavior under the thread-per-PDS model. +RUN set -eux; \ + case "$(dpkg --print-architecture)" in \ + amd64) target=x86_64-linux-gnu ;; \ + arm64) target=aarch64-linux-gnu ;; \ + *) echo "unsupported architecture: $(dpkg --print-architecture)" >&2; exit 1 ;; \ + esac; \ + zig build -Doptimize=ReleaseSafe -Dcpu=baseline "-Dtarget=${target}" -FROM --platform=linux/amd64 debian:bookworm-slim +FROM debian:bookworm-slim RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && rm -rf /var/lib/apt/lists/* COPY --from=builder /build/zig-out/bin/zlay /usr/local/bin/zlay RUN mkdir -p /data/events /data/collection-index diff --git a/README.md b/README.md index 571d8ec..396dd04 100644 --- a/README.md +++ b/README.md @@ -31,12 +31,14 @@ also implements `getLatestCommit`, `listReposByCollection`, and `getRepo` (302 r ## build -requires zig 0.15 and a C/C++ toolchain (for RocksDB). +requires zig 0.16 and a C/C++ toolchain (for RocksDB). ```bash zig build # build (debug) zig build test # run tests zig build -Doptimize=ReleaseSafe # release build (production default) +just docker-build # local container, native Linux architecture +just docker-build linux/amd64 # production-compatible container ``` ## configuration diff --git a/docs/evented-attempt.md b/docs/evented-attempt.md index 10757bd..afc36be 100644 --- a/docs/evented-attempt.md +++ b/docs/evented-attempt.md @@ -1,4 +1,8 @@ -# Evented backend (2026-03 to present) +# Evented backend attempt (2026-03 to 2026-04) + +> **Current status:** shelved. zlay uses `Io.Threaded`, and the Docker build no +> longer applies `patches/uring-networking.patch`. This document is retained as +> a historical record of the experiment. log of getting zlay running on `Io.Evented` (io_uring fibers) instead of `Io.Threaded` (one OS thread per task). goal: drop from ~2,800 threads to ~35. diff --git a/docs/stdlib-patches.md b/docs/stdlib-patches.md index fa45210..f1d28df 100644 --- a/docs/stdlib-patches.md +++ b/docs/stdlib-patches.md @@ -1,16 +1,20 @@ # zig stdlib patches for the Evented backend -zlay runs on `Io.Evented` (io_uring fiber scheduler) for network I/O. the -upstream zig 0.16-dev stdlib (`0.16.0-dev.3059+42e33db9d`) ships several -Uring networking operations as stubs that return `error.NetworkDown`. zlay -patches these at build time and works around other stdlib limitations. +> **Current status:** historical only. zlay uses `Io.Threaded`; none of the +> Uring patches or workarounds in this document are applied by the Docker build. + +During the Evented experiment, zlay ran on `Io.Evented` (io_uring fiber +scheduler) for network I/O. the upstream zig 0.16-dev stdlib +(`0.16.0-dev.3059+42e33db9d`) ships several Uring networking operations as +stubs that return `error.NetworkDown`. zlay patched these at build time and +worked around other stdlib limitations. this document tracks what we had to change, why, and what upstream work would let us drop each workaround. ## patch 1: Uring networking (`patches/uring-networking.patch`) -**applied in**: `Dockerfile` line 13, patches `lib/std/Io/Uring.zig` +**historical status**: preserved in `patches/uring-networking.patch`, not applied the upstream stdlib has these functions stubbed as `*Unavailable`: diff --git a/justfile b/justfile new file mode 100644 index 0000000..d8f063c --- /dev/null +++ b/justfile @@ -0,0 +1,13 @@ +# Show available commands. +default: + @just --list + +# Build a local container (usage: just docker-build [platform] [tag]). +docker-build platform="" tag="zlay:local": + #!/usr/bin/env bash + set -euo pipefail + args=(--tag "{{tag}}") + if [[ -n "{{platform}}" ]]; then + args+=(--platform "{{platform}}") + fi + docker build "${args[@]}" .