milestone 16: behavioral fixes for silent failures, locks, counters and the query log
CI / test (push) Failing after 11s
CI / cross (push) Failing after 25s
CI / docker (push) Failing after 24s
CI / test-aarch64 (push) Failing after 2m22s
CI / frontend (push) Successful in 43s

This commit is contained in:
2026-08-07 01:54:40 +02:00
parent 5802148887
commit 25455e5ae2
31 changed files with 2054 additions and 297 deletions
+27
View File
@@ -49,6 +49,19 @@ pub const Stats = struct {
send_errors: std.atomic.Value(u64) = .init(0),
};
/// A plain copy of `Stats`, the shape `metrics.counterGroup` walks for the
/// `nxdns_udp_server_*` families. Every counter is exported: the module doc
/// promises that a dropped datagram is counted, and a count nothing can read is
/// not a count.
pub const Snapshot = struct {
received: u64,
dropped_oversize: u64,
dropped_no_slot: u64,
dropped_handler: u64,
receive_errors: u64,
send_errors: u64,
};
/// Lifecycle of the receive loop. `serve` claims `.serving`, `deinit` publishes
/// `.closing`, and the two meet at `stopped` so no task touches the slots after
/// they are freed.
@@ -124,6 +137,20 @@ pub const UdpServer = struct {
return self.socket.address;
}
/// The counters, read one at a time. A scrape that lands mid-datagram can
/// see a receive counted before its drop is; a lock would buy a consistency
/// no consumer needs, and the receive loop takes that lock per datagram.
pub fn snapshotStats(self: *const UdpServer) Snapshot {
return .{
.received = self.stats.received.load(.monotonic),
.dropped_oversize = self.stats.dropped_oversize.load(.monotonic),
.dropped_no_slot = self.stats.dropped_no_slot.load(.monotonic),
.dropped_handler = self.stats.dropped_handler.load(.monotonic),
.receive_errors = self.stats.receive_errors.load(.monotonic),
.send_errors = self.stats.send_errors.load(.monotonic),
};
}
/// Receive loop. Returns when the task is canceled or `deinit` stops it.
pub fn serve(self: *UdpServer, io: std.Io) void {
if (self.state.cmpxchgStrong(.idle, .serving, .acq_rel, .acquire) != null) return;