server: every dns listener shares one budget of 32 queries, stream listeners take 16 connections, the task pool is capped from those bounds, and work it cannot start is counted by site

This commit is contained in:
2026-10-22 15:24:10 +02:00
parent e4e405f8e9
commit 63cc5f8dc3
23 changed files with 983 additions and 324 deletions
+23 -2
View File
@@ -33,6 +33,7 @@ const std = @import("std");
const Allocator = std.mem.Allocator;
const builtin = @import("builtin");
const concurrency = @import("../platform/concurrency.zig");
const db = @import("db.zig");
const disk_monitor = @import("disk_monitor.zig");
const events = @import("events.zig");
@@ -817,10 +818,16 @@ pub const Logger = struct {
race.concurrent(.entry, takeOne, .{ &self.queue, io }) catch |err| switch (err) {
// No second unit of concurrency: the caller flushes what it holds
// rather than block past the interval.
error.ConcurrencyUnavailable => return null,
error.ConcurrencyUnavailable => {
concurrency.unavailable(.querylog_wait);
return null;
},
};
race.concurrent(.expiry, expire, .{ io, budget }) catch |err| switch (err) {
error.ConcurrencyUnavailable => return drainRace(&race),
error.ConcurrencyUnavailable => {
concurrency.unavailable(.querylog_wait);
return drainRace(&race);
},
};
const first = race.await() catch |err| {
@@ -1259,6 +1266,20 @@ test "log applies both privacy transforms before the entry reaches the queue" {
try testing.expectEqual(@as(u64, 0), logger.queries_dropped.load(.monotonic));
}
test "a wait that cannot start its race is counted and ends the batch early" {
var threaded: std.Io.Threaded = .init(testing.allocator, .{ .concurrent_limit = .nothing });
defer threaded.deinit();
const io = threaded.io();
var buf: [4]Entry = undefined;
var logger: Logger = .init(.{}, &buf);
const before = concurrency.snapshot().get(.querylog_wait);
const long: std.Io.Clock.Duration = .{ .raw = .fromSeconds(60), .clock = .awake };
try testing.expectEqual(@as(?Entry, null), try logger.getWithin(io, long, Gate.initial));
try testing.expectEqual(@as(u64, 1), concurrency.snapshot().get(.querylog_wait) - before);
}
test "hide_domains hides every query-derived name and leaves the labels alone" {
var threaded: std.Io.Threaded = .init(testing.allocator, .{});
defer threaded.deinit();