prefect server in zig
zig 0.15 patterns#
notes from working with zig 0.15.2 in this codebase.
ArrayListUnmanaged vs ArrayList#
in zig 0.15, use ArrayListUnmanaged with explicit allocator per-method instead of ArrayList.init(alloc):
// prefer this pattern
var results = std.ArrayListUnmanaged(MyType){};
try results.append(alloc, item);
defer results.deinit(alloc);
return results.toOwnedSlice(alloc);
// NOT this (old pattern)
var results = std.ArrayList(MyType).init(alloc); // error: no member 'init'
this matches the pattern used throughout the codebase (see db/*.zig).
pg.zig strict type checking#
postgres driver (pg.zig) is strict about column types:
INTEGER/INT4→ must usei32viarow.getInt(col)BIGINT/INT8→ must usei64viarow.getBigInt(col)
our backend.zig abstraction:
pub fn int(self: Row, col: usize) i64 {
// for INTEGER columns
return switch (self) {
.sqlite => |r| r.int(col),
.postgres => |r| r.getInt(col), // returns i32, coerced to i64
};
}
pub fn bigint(self: Row, col: usize) i64 {
// for BIGINT columns
return switch (self) {
.sqlite => |r| r.int(col),
.postgres => |r| r.getBigInt(col), // returns i64
};
}
buffer allocation: stack first, heap fallback#
for variable-size data, try stack buffer first, fall back to heap for large data:
var heap_buf: ?[]u8 = null;
defer if (heap_buf) |hb| alloc.free(hb);
const result = blk: {
// try 64KB stack buffer first
var stack_buf: [65536]u8 = undefined;
break :blk doWork(&stack_buf, data) catch |err| {
if (err == error.NoSpaceLeft and data.len > 60000) {
// large data - allocate on heap
heap_buf = try alloc.alloc(u8, data.len + 1024);
break :blk try doWork(heap_buf.?, data);
}
return err;
};
};
this avoids heap allocation for common cases while handling edge cases.
function pointer types with slice parameters#
when accepting buffers, use []u8 slice instead of pointer-to-array:
// flexible - works with stack and heap buffers
fn formatJson(buf: []u8, data: []const u8) ![]const u8 {
return std.fmt.bufPrint(buf, ...);
}
// usage with stack buffer
var stack_buf: [65536]u8 = undefined;
_ = try formatJson(&stack_buf, data);
// usage with heap buffer
const heap_buf = try alloc.alloc(u8, size);
_ = try formatJson(heap_buf, data);