milestone 19: hygiene sweep - dead ecs surface, single-source constants, tls classification, frontend state hazards, docker smoke network fix
This commit is contained in:
+2
-2
@@ -268,8 +268,8 @@ pub const Db = struct {
|
||||
/// `verifyImmutable` to compare against when it ends.
|
||||
immutable_guard: ?ImmutableGuard = null,
|
||||
|
||||
/// Every mode carries `FULLMUTEX` (serialized mode). Phase 6's query logger
|
||||
/// and Phase 8's API handlers share one handle across `std.Io` tasks, and a
|
||||
/// Every mode carries `FULLMUTEX` (serialized mode). The query logger and
|
||||
/// the web API handlers share one handle across `std.Io` tasks, and a
|
||||
/// per-handle mutex inside SQLite is cheaper to be correct about than a
|
||||
/// hand-rolled one; `config.db` write volume is negligible. `EXRESCODE`
|
||||
/// makes `sqlite3_extended_errcode` meaningful from the first call.
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
//!
|
||||
//! The state is the gate other components read before a non-essential write:
|
||||
//! the query logger holds its batches while `writesAllowed` is false, and
|
||||
//! Phase 7 gates blocklist updates the same way. Nothing here edits a
|
||||
//! the blocklist scheduler gates its refresh passes the same way
|
||||
//! (`filter/manager.zig`'s `refreshGated`). Nothing here edits a
|
||||
//! milestone-5 file; the gate is pulled, not pushed.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
+12
-7
@@ -41,11 +41,14 @@ pub const hidden_marker = "hidden";
|
||||
/// How long a batch waits before it re-reads the disk monitor.
|
||||
pub const gate_retry_s = 1;
|
||||
|
||||
const max_domain_len = 253;
|
||||
/// The widths of the query log's text columns, and the single source of them:
|
||||
/// every producer that formats into one of these fields sizes its own buffer
|
||||
/// from the constant here, so nothing can format wider than the row stores.
|
||||
pub const max_domain_len = 253;
|
||||
/// RFC 5952 text of any IPv6 address, zone identifier included.
|
||||
const max_client_len = 45;
|
||||
const max_reason_len = 32;
|
||||
const max_upstream_len = 64;
|
||||
pub const max_client_len = 45;
|
||||
pub const max_reason_len = 32;
|
||||
pub const max_upstream_len = 64;
|
||||
|
||||
/// One row on its way to `query_log`, carrying its own bytes.
|
||||
pub const Entry = struct {
|
||||
@@ -175,8 +178,9 @@ pub const Logger = struct {
|
||||
/// that sees this must not expect rows.
|
||||
writer_failed: std.atomic.Value(bool),
|
||||
|
||||
/// `queue_buf.len` is the backpressure cap — Phase 7 passes
|
||||
/// `cfg.query_log_buffer_max` entries. The queue holds waiting tasks in
|
||||
/// `queue_buf.len` is the backpressure cap — the composition root
|
||||
/// (`app.zig:311`) allocates `cfg.logging.query_log_buffer_max` entries,
|
||||
/// which `config/validate.zig` bounds. The queue holds waiting tasks in
|
||||
/// intrusive lists, so a `Logger` must not be moved once anything has
|
||||
/// touched it.
|
||||
pub fn init(cfg: model.Logging, queue_buf: []Entry) Logger {
|
||||
@@ -300,7 +304,8 @@ pub const Logger = struct {
|
||||
/// it has flushed what was left.
|
||||
///
|
||||
/// A writer held by the disk gate keeps holding: it flushes when the disk
|
||||
/// recovers, and Phase 7 cancels the task if it will not wait. A canceled
|
||||
/// recovers, and the `group.cancel` that follows this call in `app.zig`
|
||||
/// stops a writer that will not wait. A canceled
|
||||
/// writer counts the batch it holds under `queries_dropped`.
|
||||
pub fn shutdown(self: *Logger, io: std.Io) void {
|
||||
self.queue.close(io);
|
||||
|
||||
@@ -68,7 +68,7 @@ pub const RecreateReason = enum { missing, corrupt, not_a_database, quick_check_
|
||||
|
||||
pub const OpenResult = struct {
|
||||
database: db.Db,
|
||||
/// Non-null feeds a counter and the `/api/health` rollup in Phase 8.
|
||||
/// Non-null feeds a counter and the `/api/health` rollup.
|
||||
recreated: ?RecreateReason,
|
||||
};
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
//! a test helper — it deliberately does not answer that question.
|
||||
//!
|
||||
//! The import path is list / insert / deleteAll / count, plus the two runtime
|
||||
//! calls `upsertSeen` and `pruneStale` that the Phase 7 client tracker owns.
|
||||
//! Phase 8's REST surface is the third section: it speaks row ids and shows
|
||||
//! calls `upsertSeen` and `pruneStale` that `server/clients.zig`'s tracker owns.
|
||||
//! The REST surface is the third section: it speaks row ids and shows
|
||||
//! every client, materialised ones included.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//! stable across an import, so an export carrying them would not re-import into
|
||||
//! the same shape.
|
||||
//!
|
||||
//! The import path is list / insert / deleteAll / count. Phase 8's REST surface
|
||||
//! The import path is list / insert / deleteAll / count. The REST surface
|
||||
//! is the second half of this file: it speaks row ids, because that is what a
|
||||
//! `/api/groups/{id}` request names.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! `local_records` and `forward_zones`.
|
||||
//!
|
||||
//! The import path is list / insert / deleteAll / count. Phase 8's REST surface
|
||||
//! The import path is list / insert / deleteAll / count. The REST surface
|
||||
//! follows each table's section: it speaks row ids, because that is what an
|
||||
//! `/api/local-records/{id}` or `/api/forward-zones/{id}` request names.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
//! order as a whole is: `import` inserts the rules in export order, so the new
|
||||
//! ids ascend in exactly the order this statement produced.
|
||||
//!
|
||||
//! The import path is list / insert / deleteAll / count. Phase 8's REST surface
|
||||
//! The import path is list / insert / deleteAll / count. The REST surface
|
||||
//! is the second half of this file: it speaks row ids, because that is what an
|
||||
//! `/api/rules/{id}` request names.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//! defaults so two exports taken minutes apart stay identical.
|
||||
//!
|
||||
//! The import path is list / insert / deleteAll / count; the runtime columns and
|
||||
//! Phase 8's REST surface follow it, both keyed by row id.
|
||||
//! the REST surface follow it, both keyed by row id.
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//! meaningful order — it matches what `Pool.init` expects — and `url` breaks
|
||||
//! ties uniquely, which is what makes an export byte-stable.
|
||||
//!
|
||||
//! The import path is list / insert / deleteAll / count. Phase 8's REST surface
|
||||
//! The import path is list / insert / deleteAll / count. The REST surface
|
||||
//! is the second half of this file: it speaks row ids, because that is what an
|
||||
//! `/api/upstreams/{id}` request names.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//!
|
||||
//! The pass touches `querylog.db` only. §3.6 walls `config.db` off from
|
||||
//! retention churn, and the `hand_edited=0` client rows of §7.2 are pruned by
|
||||
//! whatever creates them, which is Phase 7.
|
||||
//! whatever creates them, which is the client tracker (`server/clients.zig`).
|
||||
//!
|
||||
//! Nothing here retries within a pass. A failed step logs at `warn` and the
|
||||
//! next pass, a day later, does the same work again against the same data.
|
||||
@@ -134,7 +134,8 @@ pub const Retention = struct {
|
||||
_ = counter.fetchAdd(delta, .monotonic);
|
||||
}
|
||||
|
||||
/// Daily loop, first pass immediately. Phase 7 starts it.
|
||||
/// Daily loop, first pass immediately. The composition root starts it as a
|
||||
/// concurrent task (`app.zig`).
|
||||
///
|
||||
/// `boot` rather than `awake`: a box that suspends overnight must still see
|
||||
/// its day elapse.
|
||||
@@ -148,8 +149,9 @@ pub const Retention = struct {
|
||||
/// with the batch, and a checkpoint or a `VACUUM` can land inside a
|
||||
/// transaction that is still open.
|
||||
///
|
||||
/// Retention takes `database` per call and opens nothing itself; Phase 7
|
||||
/// opens the second connection. Isolation across the two connections is
|
||||
/// Retention takes `database` per call and opens nothing itself; the
|
||||
/// composition root opens the second connection with
|
||||
/// `cli.DataDir.reopenQuerylogDb`. Isolation across the two connections is
|
||||
/// SQLite's own — WAL plus the `busy_timeout` of `db.zig`'s open options —
|
||||
/// so a pass that still loses a race sees `error.Busy` or `error.Locked`,
|
||||
/// logs at `warn`, and repeats the work on the next interval.
|
||||
|
||||
Reference in New Issue
Block a user