atproto relay implementation in zig zlay.waow.tech
9
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix reconcile loop: remove invalid Future.wait(), use sleep loop

Io.Future(void).wait() doesn't exist — futures use .await(io) and
are not threadsafe across fibers. replace startup_future.wait() with
a simple initial sleep (the first reconciliation pass runs 5 min
after startup anyway, well after spawnWorkers finishes).

also use 1-second sleep increments for shutdown responsiveness,
matching the subscriber backoff pattern.

caught by `zig build` (exe target) — `zig build test` misses this
due to lazy analysis when no test references the code path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+7 -7
+7 -7
src/slurper.zig
··· 716 716 /// respawns any active/dormant host that doesn't have a running subscriber. 717 717 /// catches hosts lost to prior exhaustion, bugs, or any other gap. 718 718 fn reconcileHosts(self: *Slurper) void { 719 - const interval = Io.Duration.fromSeconds(5 * 60); // 5 minutes 720 - 721 - // wait for initial startup to finish before first reconciliation 722 - if (self.startup_future) |*f| { 723 - f.wait(self.io) catch {}; 724 - } 719 + const interval_secs: u64 = 5 * 60; // 5 minutes 725 720 726 721 while (!self.shutdown.load(.acquire)) { 727 - self.io.sleep(interval, .awake) catch return; 722 + // sleep in 1-second increments so we can check shutdown 723 + var remaining: u64 = interval_secs; 724 + while (remaining > 0 and !self.shutdown.load(.acquire)) { 725 + self.io.sleep(Io.Duration.fromSeconds(1), .awake) catch return; 726 + remaining -= 1; 727 + } 728 728 if (self.shutdown.load(.acquire)) return; 729 729 730 730 const db_queue = self.db_queue orelse continue;