milestone 32: task-shaped configuration, file mode as a rendering, config status api
Gates / frontend (push) Successful in 1m22s
Gates / test (push) Successful in 1m54s
Gates / test-aarch64 (push) Successful in 7m57s
Gates / package (push) Successful in 5m29s
Gates / container (push) Successful in 10s
CI / gates (push) Successful in 32m51s

This commit is contained in:
2026-08-22 22:42:50 +02:00
parent 025edbb093
commit 7e0df5fd94
89 changed files with 6101 additions and 3750 deletions
+26
View File
@@ -52,6 +52,10 @@ pub fn applyCreate(
state.config_lock.unlock(io);
const id = inserted catch |err| return .{ .fail = mutations.dbFailure(err, url_conflict) };
// Ruling 12: the pool is built at startup, so the row now stored governs
// nothing until the next one. Stored after the insert, never before — a
// rejected url or a conflict owes no restart.
state.restart_pending.store(true, .monotonic);
return .{ .id = id };
}
@@ -83,6 +87,7 @@ pub fn applyUpdate(
upstreams_repo.updateUpstream(database, id, item) catch |err|
return mutations.dbFailure(err, url_conflict);
state.restart_pending.store(true, .monotonic);
return null;
}
@@ -106,6 +111,7 @@ pub fn applyDelete(state: *server.WebState, io: std.Io, arena: Allocator, id: i6
upstreams_repo.deleteUpstream(database, id) catch |err|
return mutations.dbFailure(err, url_conflict);
state.restart_pending.store(true, .monotonic);
return null;
}
@@ -245,6 +251,26 @@ test "a url the validator refuses never reaches the database" {
try testing.expectEqual(@as(i64, 0), try bench.queryInt("SELECT count(*) FROM upstreams"));
}
test "a refused upstream write owes no restart, and an accepted one does" {
var bench: mutations.Bench = undefined;
try bench.init(testing.allocator);
defer bench.deinit(testing.allocator);
try testing.expect((try applyCreate(&bench.state, bench.io(), bench.arena(), .{
.url = "udp://1.1.1.1:53",
})).fail == .invalid);
try testing.expect(!bench.state.restart_pending.load(.monotonic));
try testing.expect((try applyUpdate(&bench.state, bench.io(), bench.arena(), 999, doh)).? == .not_found);
try testing.expect(!bench.state.restart_pending.load(.monotonic));
try testing.expect(applyDelete(&bench.state, bench.io(), bench.arena(), 999).? == .not_found);
try testing.expect(!bench.state.restart_pending.load(.monotonic));
_ = try applyCreate(&bench.state, bench.io(), bench.arena(), doh);
try testing.expect(bench.state.restart_pending.load(.monotonic));
}
test "a duplicate url is a conflict" {
var bench: mutations.Bench = undefined;
try bench.init(testing.allocator);