atproto relay in zig zlay.waow.tech
relay zig atproto
zlay docs gotchas.md
2.2 kB
Markdown

gotchas #

hard-won knowledge from debugging zlay. check here before guessing.

zig 0.15 #

  • &.{...} in loops creates stack-local arrays that alias across iterations — all references point to same memory. heap-allocate instead.
  • operator precedence: (byte & 0xf0) == 0 not byte & 0xf0 == 0
  • ArrayList is unmanaged — pass allocator to each method
  • f.readAll() not f.reader().readAll() — File.reader() takes a buffer arg in zig 0.15

pg.zig #

  • pool.rowUnsafe() for single-row queries — .get(T, col) returns T
  • pool.query() + result.nextUnsafe() for multi-row
  • QueryRow.deinit() returns !void — use defer row.deinit() catch {}
  • DB-dependent tests skip via requireDatabaseUrl() → error.SkipZigTest

rocksdb-zig #

  • iterator Data has .free = rocksdb_free but points to internal buffers — do NOT call .deinit() on iterator entries (SIGABRT). only deinit Data from db.get()
  • DB.open passes dir.ptr raw to C API — path must be null-terminated (use realpathAlloc or zero-init buffer)
  • ColumnFamilyOptions is a stub — use extern fn rocksdb_set_options_cf to set options post-open

websocket.zig fork #

fork of karlseguin/websocket.zig, canonical at tangled.org:zzstoatzz.io/websocket.zig (pinned v0.1.8), with patches:

  • httpFallback: _handleHandshake catches parse errors, routes to H.httpFallback if present — this is how all HTTP API endpoints are served on the WS port
  • lenient handshake parser: non-WS headers skip instead of error

metrics #

  • mallinfo() overflows at 2 GiB (c_int fields) — smaps metrics are the reliable RSS source
  • relay_build_info{git_sha,optimize} confirms what binary is running

deploy #

  • containers are minimal debian — no curl, wget, or shell utilities. use busybox pod or kubectl port-forward
  • two separate kubeconfigs: Go relay (kubeconfig.yaml) vs zlay (zlay-kubeconfig.yaml)
  • $ZLAY_KUBECONFIG is only set inside just — raw shell needs the absolute path
  • after helm upgrade, must kubectl set image back to SHA tag (helm uses latest from values)
  • never change probe paths and image in separate operations (see incident-2026-03-04.md)