17 check-ins that include changes to files matching 'internal/obsduck/*'
|
2026-09-27
| ||
| 11:38 | Merge trunk into background-jobs-follow-the-lease check-in: cf04732cdd user: dmestas tags: background-jobs-follow-the-lease | |
| 11:27 | update node-identity-is-persisted from trunk closed check-in: f61888abaf user: zeitgeist tags: node-identity-is-persisted | |
| 11:23 | update ci-race-on-landings from trunk closed check-in: 3bfe3ae2d8 user: zeitgeist tags: ci-race-on-landings | |
| 11:12 | land ops-history-flush-off-request-path check-in: 1bcff88f59 user: dmestas tags: trunk | |
| 04:47 | Rows lost to a failed or cancelled write count as dropped, and the ops page shows the count check-in: 9f7e279623 user: dmestas tags: ops-history-flush-off-request-path | |
| 03:43 | Flush ops history off the request path and keep web renders in their own recent window check-in: 3bdf2f891d user: dmestas tags: ops-history-flush-off-request-path | |
| 03:23 | web: pages are opaque handles drawn only through a handler's hooks; register ciRunPage and personEditPage check-in: b67646c5ba user: dmestas tags: handler-owned-page-templates | |
| 02:46 | land api-ops-are-timed-at-the-registry check-in: 26de248275 user: dmestas tags: trunk | |
| 02:39 | Time every op at the registry and file API calls beside web renders, tagged by surface closed check-in: ccbcf4b34e user: dmestas tags: api-ops-are-timed-at-the-registry | |
|
2026-08-26
| ||
| 13:37 | Accepted. Clicking through found what testing the parts did not. check-in: 111491a3a9 user: dmestas tags: trunk | |
| 13:37 |
ops: the path actually requested, and two broken links
Recent renders showed the route pattern, so a dozen rows all read GET /r/{repo}/timeline and none could say which repository was slow. The URL is now recorded and shown, with the route beside it as the link to its drilldown. Two bugs found by clicking through rather than by testing the parts: queryesc double-encoded every URL it touched, because html/template already escapes a value in query context. The routes panel linked to its own drilldown with %252F for a slash, so every link 500'd. Six call sites, all wrong; the function is gone. The days control I added with the trend forwarded an empty parameter, and a numeric field with a default takes it when the key is MISSING and refuses when it is present and empty. Routes panel gains a filter and a sort; renders gain a deeper-history page reading the store rather than the ring. closed check-in: 2d033f106e user: dmestas tags: ops-paths | |
| 11:24 | Accepted. The link was in the DAG the whole time, and the history is finally being read. check-in: 23cec0f0fd user: dmestas tags: trunk | |
| 11:24 |
ops: read the history back — a route across days
The store recorded renders and nothing read them. The panels are one process's memory, so the page could say how fast a route is now and never whether it is worse than it was — which is the question after a deploy. The drilldown gains a per-day table from the store: p50, p95, max. Nearest-rank percentiles, matching how the snapshot computes them, so two numbers on one page both called p95 agree. Empty for no traffic and empty for history-off are different answers and the page gives the right one. closed check-in: a0fa952495 user: dmestas tags: landing-merge | |
| 09:37 | Accepted. The panel found something real, and the two things it could not say about itself are now things it says. check-in: 13cb36d2e5 user: dmestas tags: trunk | |
|
2026-08-25
| ||
| 22:19 |
Analytics: say whether history is being kept, and stop keeping it for ever
The live panels read in-memory rings, so a forge whose store failed to open looked exactly like a healthy one. Sink.Err() existed and nothing asked it. The page now distinguishes three states: off, broken, and recording to a named path. Retention was 'append for ever', which is a default nobody was asked about. --analytics-keep sets the window, 14d by default, 0 keeps everything. Pruned at startup and daily. check-in: e2b74749b4 user: dmestas tags: fleet-census | |
| 21:08 | Accepted. History, with the cgo cost taken knowingly and the wasm path verified intact. check-in: 61c32a8057 user: dmestas tags: trunk | |
| 19:24 |
ops: history, not just a snapshot
The rings die with the process, and this fleet restarts constantly — a 4.24s render and a 546 load average both left no trace. obs.Sink had one implementation and it did nothing; this is the durable one. DuckDB because the workload is columnar: append-only, time-ordered, aggregate-queried, never point-looked-up by a page. RFC 0001 defers the lake to 'when hydration and analytics — the things columnar is for — exist', and reserves the operational surface for SQLite. This is that analytics workload, not a second operational store. Wide flat tables, no keys and no indexes, which is also what a Parquet COPY TO wants when the lake arrives. Isolated behind a build constraint, in its own package, imported only by the composition root. Both halves of the reason were measured rather than assumed: CGO_ENABLED=0 fails on go-duckdb's bindings, and GOOS=js reports 'build constraints exclude all Go files'. Leaving the import off the request path is not enough — any reachable import breaks a wasm build — so cmd/quarry has two files, one per side of the tag. Verified: GOOS=js GOARCH=wasm builds cmd/quarry clean at 76MB, without DuckDB. Buffered, never a write per request, and flushed on a timer so a quiet forge still lands rows rather than holding them in memory for days. Failure is not fatal. The first run failed on 'at' being reserved in DuckDB; the server started anyway, the panels worked, and the log said what was wrong. Analytics is derived data about a forge that works without it. Costs, measured: +462MB module cache, binary 57MB -> 104MB, cold build +10s, and CGO_ENABLED=0 no longer builds the server. closed check-in: 564f272d3c user: dmestas tags: ops-history | |