atproto relay implementation in zig zlay.waow.tech

fix: move pullHosts to background thread for immediate HTTP startup

pullHosts pages through bsky.network API (~6 HTTPS requests), taking
30+ seconds. previously blocked start() → main() → HTTP server.
now everything (pullHosts + listActiveHosts + spawnWorker) runs in
the background thread, so the HTTP server and health probes come up
within seconds of process start.

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

+8 -9
+8 -9
src/slurper.zig
··· 247 247 self.ca_bundle = bundle; 248 248 log.info("loaded shared CA bundle", .{}); 249 249 250 - // always pull hosts from seed relay on startup — idempotent (getOrCreateHost skips existing) 251 - // Go relay: pull-hosts is a separate command, but we run it inline for simplicity 252 - log.info("pulling hosts from {s}...", .{self.options.seed_host}); 253 - self.pullHosts() catch |err| { 254 - log.warn("pullHosts from {s} failed: {s}", .{ self.options.seed_host, @errorName(err) }); 255 - }; 256 - 257 - // spawn worker startup and crawl queue in background threads so the 258 - // HTTP server can start immediately (health probes need it) 250 + // spawn worker startup in background so HTTP server + probes come up immediately. 251 + // pullHosts + listActiveHosts + spawnWorker all happen in the background thread. 259 252 self.startup_thread = try std.Thread.spawn(.{ .stack_size = @import("main.zig").default_stack_size }, spawnWorkers, .{self}); 260 253 self.crawl_thread = try std.Thread.spawn(.{ .stack_size = @import("main.zig").default_stack_size }, processCrawlQueue, .{self}); 261 254 } ··· 467 460 /// we spawn all at once — the brief memory spike from concurrent TLS handshakes 468 461 /// is shorter than a throttled ramp (many hosts fail-fast, freeing memory quickly). 469 462 fn spawnWorkers(self: *Slurper) void { 463 + // pull hosts from seed relay first — idempotent (getOrCreateHost skips existing) 464 + log.info("pulling hosts from {s}...", .{self.options.seed_host}); 465 + self.pullHosts() catch |err| { 466 + log.warn("pullHosts from {s} failed: {s}", .{ self.options.seed_host, @errorName(err) }); 467 + }; 468 + 470 469 const hosts = self.persist.listActiveHosts(self.allocator) catch |err| { 471 470 log.err("failed to load hosts: {s}", .{@errorName(err)}); 472 471 return;