How g41797/tofu works
1. What this repo is
Tofu is a Zig library for asynchronous, message-oriented networking. The core product is a reusable messaging runtime, not an application. Its architecture is centered on a message API, an event-driven reactor, and pluggable OS backends for stream transports like TCP and Unix Domain Sockets.
2. Public surface / domain model
The top-level library entry points are in src/tofu.zig, src/message.zig, src/address.zig, and src/status.zig. These define the concepts an application uses directly: messages, endpoints/addresses, and operation results/statuses. This is the boundary where application code stops and the runtime begins.
3. Async runtime core
The src/ampe subtree is the internal engine. It contains the reactor, poller, notifier, pools, queues, and channel management that move messages between user code and sockets without blocking. The important architectural idea is that “messages” are scheduled and transported by the runtime, not by application threads directly.
4. Reactor and event dispatch
src/ampe/Reactor.zig, poller.zig, Notifier.zig, channels.zig, and MchnGroup.zig form the control plane. The reactor owns the event loop; the poller waits for I/O readiness; notifiers wake the loop from other threads; channels and machine groups model connection endpoints and flow control. This is the central orchestration layer in the diagram.
5. Memory and buffering
src/ampe/Pool.zig, Appendable.zig, IntrusiveQueue.zig, and helper/internal files provide the runtime’s message and buffer management. The library explicitly includes internal pooling and appendable buffers, so the architecture should show a memory-management boundary inside the runtime rather than relying only on caller-owned allocations.
6. Transport abstraction
The src/platform tree is the portability boundary. It separates socket and poller behavior by platform family, so the core runtime can stay mostly OS-agnostic. This layer is where differences in readiness notification, socket creation, and trigger mechanisms are isolated.
7. Two platform strategies
There are two platform families: src/platform/stdposix and src/platform/posixnet. stdposix contains direct platform backends for Linux, macOS, and Windows (epoll, kqueue, wepoll). posixnet adds a wrapper layer with C adapters and FFI glue, suggesting an alternate portability path or a more specialized socket backend. A diagram should treat these as alternative backend stacks below the same core runtime.
8. OS-specific backends
Under src/platform/stdposix, each OS has its own socket and poller implementation: Linux uses epoll_backend.zig, macOS uses kqueue_backend.zig, and Windows uses wepoll_backend.zig, along with OS-specific socket creator and trigger files. These are the lowest-level components before the kernel boundary.
9. Data flow through the system
The main flow is: application code uses the public Tofu API, creates messages/addresses, and submits them into the ampe runtime; the reactor and poller route those messages to a channel/socket; the platform backend performs OS I/O; inbound data returns through the same path into message objects and callbacks/handlers. The system is duplex, so both directions use the same message-driven pipeline.
10. Concurrency and backpressure
The README emphasizes multithread safety and backpressure, and the code structure reflects that with notifier-based wakeups, queues, pools, and channel groups. That means the architecture is not “one thread per connection”; it is a shared async core that coordinates concurrent producers and consumers safely.
11. Usage patterns and examples
recipes/ contains cookbook-style examples such as MultiHomed.zig and service-oriented samples. These are not core runtime pieces, but they show how the public API is intended to be composed into higher-level messaging flows. For a diagram, they belong above the library layer as usage examples.
12. Tests as architecture validation
The tests/ tree is broad and maps closely to the subsystem boundaries: address, message, reactor, poller, sockets, platform-specific pollers, and tofu behavior. That makes the test suite a good indicator of the repo’s modular structure and the main seams where platform differences matter.
13. Build, docs, and delivery
build.zig and build.zig.zon define the Zig build; GitHub Actions run Linux, macOS, and Windows CI. The docs/ and docs_site/ trees contain generated documentation and site assets, while docs_site.sh / docs_zig.sh support doc generation. These are delivery/support systems around the library, not runtime components.
14. External boundaries
The only material external dependency boundary is the OS networking/event API layer: epoll, kqueue, and Windows I/O polling through backend adapters. Everything else is internal library structure. If you draw the architecture, the kernel boundary should sit directly beneath the platform backends, with the public API and examples clearly separated above the async core.
Main entry points: ampe.zig AMPE · tofu.zig Tofu API · stdposix Std POSIX · tofu_tests.zig Tests
Components 23
Public API
Library entry points and user-facing concepts.
- Tofu API · Top-level library entry point for applications using the messaging runtime.
src/tofu.zig - Messages · Message type and message-oriented API used by callers and the runtime.
src/message.zig - Addresses · Endpoint and address abstractions for stream transports.
src/address.zig - Statuses · Operation outcomes and status types exposed to callers.
src/status.zig
Async Runtime
Message scheduling, event dispatch, buffering, and connection management.
- AMPE · Async message-processing engine that coordinates reactors, channels, queues, and buffering.
src/ampe.zig - Reactor · Owns the event loop and orchestrates readiness, wakeups, and dispatch.
src/ampe/Reactor.zig - Poller · Waits for OS readiness events and feeds them back into the reactor.
src/ampe/poller.zig - Notifier · Cross-thread wakeup mechanism that interrupts the event loop safely.
src/ampe/Notifier.zig - Channels · Models endpoints, flow, and message transport between runtime machines and sockets.
src/ampe/channels.zig - Machine Groups · Groups machines and coordinates shared runtime state and backpressure.
src/ampe/MchnGroup.zig - Pool · Reusable allocation boundary for runtime objects and message storage.
src/ampe/Pool.zig - Appendable · Growable buffer abstraction used by the runtime when assembling payloads.
src/ampe/Appendable.zig - Intrusive Queue · Internal queue used to move work and messages through the async core.
src/ampe/IntrusiveQueue.zig
Platform Backends
OS portability layers and kernel-facing adapters.
- Std POSIX · Primary portability layer for POSIX-like and Windows poller/socket backends.
src/platform/stdposix - Posix Net · Alternate backend stack with C adapters and FFI glue.
src/platform/posixnet - Linux Backend · Linux-specific sockets, creators, triggers, and epoll integration.
src/platform/stdposix/linux/epoll_backend.zig - macOS Backend · macOS-specific sockets, creators, triggers, and kqueue integration.
src/platform/stdposix/mac/kqueue_backend.zig - Windows Backend · Windows-specific sockets, creators, triggers, and wepoll integration.
src/platform/stdposix/windows/wepoll_backend.zig - Wrapper Layer · C adapters, poll wrapper, and FFI boundary for the posixnet path.
src/platform/posixnet/wrapper/ffi.zig
Delivery
Examples, docs, build, and validation surfaces around the library.
- Recipes · Cookbook-style usage examples showing how the public API is composed.
recipes/cookbook.zig - Docs Site · Generated docs and site content for library guidance and API reference.
docs_site/mkdocs.yml - Build · Zig build entry and dependency manifest for building and packaging.
build.zig - Tests · Subsystem-oriented tests covering address, message, reactor, poller, sockets, and platform behavior.
tests/tofu_tests.zig
Connections 26
- Tofu API → Messages: exports · Public API exposes message concepts directly.
- Tofu API → Addresses: exports · Public API exposes endpoint/address types.
- Tofu API → Statuses: exports · Public API exposes operation statuses and results.
- Tofu API → AMPE: uses · Applications call into the async runtime through the top-level library.
- AMPE → Reactor: owns · Core runtime centers on the reactor control plane.
- AMPE → Poller: drives · Runtime delegates readiness waiting to the poller.
- AMPE → Notifier: wakes · Runtime uses notifiers for cross-thread wakeups.
- AMPE → Channels: routes · Runtime moves messages through channel abstractions.
- AMPE → Machine Groups: coordinates · Runtime organizes machines into groups for shared flow control.
- AMPE → Pool: allocates · Runtime uses internal pools for reusable memory management.
- AMPE → Appendable: buffers · Runtime builds payloads through appendable buffers.
- AMPE → Intrusive Queue: queues · Runtime schedules work through internal queues.
- Reactor → Poller: dispatches · Reactor depends on the poller for readiness events.
- Reactor → Notifier: receives wakeups · Notifier interrupts the reactor loop from other threads.
- Channels → Std POSIX: targets · Channel/socket operations flow into platform-specific backends.
- Std POSIX → Linux Backend: includes · Linux path uses epoll-based backend components.
- Std POSIX → macOS Backend: includes · macOS path uses kqueue-based backend components.
- Std POSIX → Windows Backend: includes · Windows path uses wepoll-based backend components.
- Posix Net → Wrapper Layer: wraps · Alternate backend path adds a C/FFI wrapper layer.
- Recipes → Tofu API: demonstrates · Examples show intended composition of the public API.
- Docs Site → Tofu API: documents · Site content explains the public surface and runtime model.
- Build → Tofu API: builds · Build system compiles the library and supporting artifacts.
- Tests → Reactor: verifies · Tests cover reactor behavior and orchestration.
- Tests → Poller: verifies · Tests cover poller behavior and platform readiness handling.
- Tests → Channels: verifies · Tests cover channel and socket flow management.
- Tests → Std POSIX: verifies · Tests exercise platform-specific poller and socket backends.