Skip to content
v1.0.0-zig0.15.2

Quick Reference

A compact lookup for “how do I do X in Volt?” Copy-paste the pattern you need.

const volt = @import("volt");
// Zero-config (auto worker count, page allocator)
pub fn main() !void {
try volt.run(myApp);
}
// Custom config
pub fn main() !void {
try volt.runWith(allocator, .{
.num_workers = 4,
.max_blocking_threads = 128,
}, myApp);
}
// Explicit (full control, recommended for production)
pub fn main() !void {
var io = try volt.Io.init(allocator, .{ .num_workers = 4 });
defer io.deinit();
try io.run(myApp);
}
fn myApp(io: volt.Io) void {
// All Volt APIs available here
_ = io;
}

PatternCode
Spawn + awaitvar f = try io.@"async"(fn, .{args}); const result = f.@"await"(io);
Fire-and-forget_ = try io.@"async"(fn, .{args});
Blocking poolvar f = try io.concurrent(fn, .{args}); const result = try f.@"await"(io);
Group (structured)var g = volt.Group.init(io); _ = g.spawn(fn, .{args}); g.wait();
Cancelf.cancel(io); or g.cancel();

PrimitiveCreateTry (no runtime)Convenience (needs io)Release
Mutexvar m = volt.sync.Mutex.init();if (m.tryLock()) { ... }m.lock(io);m.unlock();
RwLockvar rw = volt.sync.RwLock.init();if (rw.tryReadLock()) { ... }rw.readLock(io);rw.readUnlock();
if (rw.tryWriteLock()) { ... }rw.writeLock(io);rw.writeUnlock();
Semaphorevar s = volt.sync.Semaphore.init(n);if (s.tryAcquire(1)) { ... }s.acquire(io, 1);s.release(1);
Notifyvar n = volt.sync.Notify.init();n.wait(io);n.notifyOne(); / n.notifyAll();
Barriervar b = volt.sync.Barrier.init(n);b.wait(io);(auto-releases)
OnceCellvar o = volt.sync.OnceCell(T).init();o.get()o.getOrInit(io, initFn)

All sync primitives are zero-allocation. No deinit() needed.


TypeCreatedeinit?SendReceive
Channelvar ch = try volt.channel.bounded(T, alloc, cap);Yesch.trySend(val) / ch.send(io, val)ch.tryRecv() / ch.recv(io)
Oneshotvar os = volt.channel.oneshot(T);No_ = os.sender.send(val);os.receiver.tryRecv() / os.receiver.recv(io)
Broadcastvar bc = try volt.channel.broadcast(T, alloc, cap);Yes_ = bc.send(val);rx.tryRecv() / rx.recv(io)
Watchvar wt = volt.channel.watch(T, initial);Nowt.send(val);rx.borrow() / rx.changed(io)

Rule: if you passed an allocator, you must defer ch.deinit().


var listener = try volt.net.listen("0.0.0.0:8080");
defer listener.close();
while (true) {
if (try listener.tryAccept()) |result| {
var stream = result.stream;
_ = io.@"async"(handle, .{stream}) catch continue;
}
}
var stream = try volt.net.connect("127.0.0.1:8080");
defer stream.close();
// With DNS
var stream2 = try volt.net.connectHost(allocator, "example.com", 443);
defer stream2.close();
const n = stream.tryRead(&buf) catch return orelse continue;
if (n == 0) return; // Peer closed
processData(buf[0..n]);
stream.writeAll(data) catch return;
var sock = try volt.net.UdpSocket.bind(volt.net.Address.fromPort(8080));
defer sock.close();
if (try sock.tryRecvFrom(&buf)) |result| {
_ = try sock.trySendTo(result.data, result.addr);
}

// Duration constructors
const d1 = volt.Duration.fromSecs(5);
const d2 = volt.Duration.fromMillis(100);
const d3 = volt.Duration.fromNanos(1000);
// Create a sleep (use with timer driver or poll manually)
var slp = volt.time.sleep(volt.Duration.fromSecs(1));
// For blocking contexts (non-async):
volt.time.blockingSleep(volt.Duration.fromSecs(1));
// Instant (monotonic clock)
const start = volt.time.Instant.now();
// ... do work ...
const elapsed = start.elapsed();

// Wait for Ctrl+C
volt.signal.waitForCtrlC();
// Graceful shutdown
var shutdown = try volt.shutdown.Shutdown.init();
defer shutdown.deinit();
while (!shutdown.isShutdown()) {
// ... accept connections ...
}
// Wait for in-flight work
_ = shutdown.waitPendingTimeout(volt.Duration.fromSecs(5));

  1. io means async. If a function takes io: volt.Io, it yields the task (safe on worker threads). If it doesn’t take io and does I/O, it blocks the thread.

  2. Allocator means deinit(). If you passed an allocator to create it (Channel, BroadcastChannel), defer x.deinit(). Everything else is zero-allocation.

  3. Use var for futures. Futures are mutated during polling. const won’t compile.

  4. Handle all four I/O outcomes. tryRead returns: data (n > 0), would-block (null), peer-close (n == 0), error. Don’t skip any.

  5. Don’t block worker threads. No std.Thread.sleep, no CPU loops, no sync file I/O. Use io.concurrent() for blocking work, volt.time.sleep() for delays.


See Common Pitfalls for detailed explanations of each footgun with bad/good code pairs.