db-mode config changes apply live in-process
Gates / frontend (push) Successful in 1m43s
Gates / test (push) Successful in 2m14s
Gates / test-aarch64 (push) Successful in 8m3s
Gates / package (push) Successful in 5m42s
Gates / container (push) Successful in 54s
CI / gates (push) Successful in 50m24s

settings and upstream writes now follow a prepare, commit, publish, retire
contract: candidates are built and validated before the database transaction,
published as infallible pointer swaps, and old generations retire after their
readers drain. per-query policy values snapshot once per query; upstream pool,
cache, rate limiter, sessions, api limiter, log sink, blocklist scheduler and
the query-log queue each gained one named live operation. restart_required
shrinks from every scalar key to the bind keys and web.enabled; the admin ui
drops its restart notices for everything else. file mode is unchanged.
This commit is contained in:
2026-08-24 00:04:28 +02:00
parent f7f4c8be09
commit ce143d1d87
47 changed files with 7698 additions and 926 deletions
+19 -12
View File
@@ -20,6 +20,7 @@ const std = @import("std");
const disk_monitor = @import("../../storage/disk_monitor.zig");
const http_util = @import("../http_util.zig");
const logger_controller = @import("../../storage/logger_controller.zig");
const logger_mod = @import("../../storage/logger.zig");
const metrics = @import("../metrics.zig");
const pause_mod = @import("../../server/pause.zig");
@@ -229,20 +230,25 @@ pub fn collect(state: *server.WebState, io: std.Io) Input {
input.disk_free_bytes = monitor.gauges().free_bytes;
}
if (state.pool) |pool| {
var raw: [metrics.max_upstreams]pool_mod.Snapshot = undefined;
const count = metrics.poolSnapshot(pool, io, &raw);
input.upstreams_total = @intCast(count);
for (raw[0..count]) |entry| {
if (entry.available) input.upstreams_available += 1;
if (state.upstreams) |owner| {
const generation = owner.acquire(io);
defer owner.release(io, generation);
if (generation.pool) |pool| {
var raw: [metrics.max_upstreams]pool_mod.Snapshot = undefined;
const count = metrics.poolSnapshot(pool, io, &raw);
input.upstreams_total = @intCast(count);
for (raw[0..count]) |entry| {
if (entry.available) input.upstreams_available += 1;
}
}
}
if (state.logger) |logger| {
input.queries_dropped = logger.queries_dropped.load(.monotonic);
input.last_drop_s = logger.lastDropSeconds();
input.writer_failed = logger.writer_failed.load(.monotonic);
input.gate_episode = logger.gateEpisode();
if (state.logger) |controller| {
const reading = controller.sample(io);
input.queries_dropped = reading.queries_dropped;
input.last_drop_s = reading.last_drop_s;
input.writer_failed = reading.writer_failed;
input.gate_episode = reading.gate_episode;
}
if (state.pause) |paused| input.pause_until = paused.until.load(.monotonic);
@@ -492,13 +498,14 @@ test "collect reads the logger's counters and the pause flag" {
query_logger.queries_dropped.store(4, .monotonic);
query_logger.last_drop_s.store(1_700_000_000, .monotonic);
query_logger.writer_failed.store(true, .monotonic);
var log_owner: logger_controller.Borrowed = .{};
var paused: pause_mod.Pause = .{};
paused.pauseFor(0, null);
var state: server.WebState = .{
.gpa = testing.allocator,
.logger = &query_logger,
.logger = log_owner.over(&query_logger),
.pause = &paused,
};
const input = collect(&state, io);