improve main.zig based on established zig project patterns

- add thread_safe = true to GPA (required for multi-threaded usage)
- use detach() instead of misleading defer join() (consumer never returns)
- switch from debug.print to std.log.scoped for proper log levels
- group imports: stdlib → external → internal

patterns verified against ghostty, tigerbeetle, zap, http.zig

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Changed files
+12 -7
src
+12 -7
src/main.zig
··· 2 2 const net = std.net; 3 3 const posix = std.posix; 4 4 const Thread = std.Thread; 5 + 5 6 const http = @import("server/http.zig"); 6 7 const db = @import("stream/db.zig"); 7 8 const jetstream = @import("stream/jetstream.zig"); 8 9 const stats = @import("server/stats.zig"); 10 + 11 + const log = std.log.scoped(.main); 9 12 10 13 const MAX_HTTP_WORKERS = 16; 11 14 const SOCKET_TIMEOUT_SECS = 30; 12 15 13 16 pub fn main() !void { 14 - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 17 + var gpa = std.heap.GeneralPurposeAllocator(.{ 18 + .thread_safe = true, 19 + }){}; 15 20 defer _ = gpa.deinit(); 16 21 const allocator = gpa.allocator(); 17 22 ··· 21 26 // init database 22 27 try db.init(); 23 28 24 - // start jetstream consumer in background 29 + // start jetstream consumer in background (runs forever, reconnects on error) 25 30 const js_thread = try Thread.spawn(.{}, jetstream.consumer, .{allocator}); 26 - defer js_thread.join(); 31 + js_thread.detach(); 27 32 28 33 // init thread pool for http connections 29 34 var pool: Thread.Pool = undefined; ··· 43 48 var server = try address.listen(.{ .reuse_address = true }); 44 49 defer server.deinit(); 45 50 46 - std.debug.print("zig-bsky-feed listening on http://0.0.0.0:{d}\n", .{port}); 51 + log.info("listening on http://0.0.0.0:{d}", .{port}); 47 52 48 53 while (true) { 49 54 const conn = server.accept() catch |err| { 50 - std.debug.print("accept error: {}\n", .{err}); 55 + log.err("accept error: {}", .{err}); 51 56 continue; 52 57 }; 53 58 54 59 setSocketTimeout(conn.stream.handle, SOCKET_TIMEOUT_SECS) catch |err| { 55 - std.debug.print("failed to set socket timeout: {}\n", .{err}); 60 + log.warn("failed to set socket timeout: {}", .{err}); 56 61 }; 57 62 58 63 pool.spawn(http.handleConnection, .{conn}) catch |err| { 59 - std.debug.print("pool spawn error: {}\n", .{err}); 64 + log.err("pool spawn error: {}", .{err}); 60 65 conn.stream.close(); 61 66 }; 62 67 }