Serve fact queries live and drop the cache headers #26
Reference in New Issue
Block a user
Delete Branch "benvin/drop-fact-caching"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
pdbmux has to be indistinguishable from PuppetDB, but the v0.3.0 response cache left fact answers up to 30s stale and added
X-CacheandAgeheaders real PuppetDB never emits./facts,/facts/<name>[/<value>]and/fact-nameslive on every request/nodesonlyX-CacheandAgefrom every response;/healthzstill reports cache stateapplication/json;charset=utf-8Review findings.
Blocking / needs discussion
/factscache is factually wrong. puppetboard's/factsoverview page (puppetboard/views/facts.py, routes/factsand/<env>/facts) callspuppetdb.facts(query=query)wherequeryisAndOperator()filtered only byenvironment— orNoneentirely when "All Environments" is selected, a normal menu choice. That's a bare, non-name/certname-filtered fetch of every fact for every node (in-environment, or estate-wide with*). This is exactly the page pdbmux's own pre-PR README named as one of the two hardest-hitting paths the fact cache existed to absorb, not an edge case./factsfromcacheForalso silently drops single-flight coalescing for it:serveFiltered's!enabledbranch callsbuild()directly, bypassings.flights.Do. Combined with (1), two concurrent loads of the facts-overview page now each trigger a full two-backend, whole-estate fact fan-out instead of sharing one (or hitting a ≤30s cache). Worth an explicit call whether the backends can absorb that, since the PR body doesn't mention coalescing loss at all.Verified independently:
git grepon voxpupuli/pypuppetdb and voxpupuli/puppetboard shows neither readsX-Cache/Age, and neither validates responseContent-Type(pypuppetdb parses viarequests'.json()), so those two header/content-type changes are safe client-side.Non-blocking
server.gojsonContentType) citeshttp.clj:80, but that line in OpenVoxProject/openvoxdb literally sets"application/json; charset=utf-8"(with a space); the deployed backends actually emitapplication/json;charset=utf-8(no space, confirmed live against bothpuppetdbapi.service.consul:8080andpuppetdb.k8s.syd1.au.unkin.net), which is what the PR uses. Value is correct, citation doesn't explain the discrepancy.cacheFor/cache-key logic, error-path content-type, and every other header are otherwise correctly untouched and complete: no fact-bearing route stayed cached, and/nodesis the only route the cache still covers. Confirmed against a live/nodesrecord that it carries only report/run-lifecycle fields (certname, deactivated/expired, catalog/facts/report timestamps, environments,latest_report_*) and no fact key/value data, so a ≤30s-stale/nodesread cannot resurface a stale fact — the "report caching" reading is sound. That staleness window onlatest_report_status/deactivated/expiredalready existed pre-PR (nodes was already cached), so it's not a new regression.cacheForswitch + header/content-type code on the PR branch reproduces failures in 6 tests (TestHandler_CachedResponsesCarryNoCacheHeaders,TestHandler_FactPathsAreNeverCached,TestHandler_FactResponsesCarryNoCacheHeaders,TestHandler_SuccessContentTypeMatchesPuppetDB,TestHandler_FactsBySourceNameValuesFilterOneFetch,TestHandler_FactRoutesAreNotCached) — close to the claimed five and confirms they aren't vacuous. The deleted fact+cache-interaction tests (source attribution, per-key gating, suppression-survives-hit, stale drilldown filtering) have live equivalents already in the untouchedsource_test.go/factroutes_test.go, so coverage moved rather than disappeared.go test -race ./...,golangci-lint run ./..., andpre-commit run --all-filesall pass clean on the PR branch; e2e files still compile under-tags e2e.