hub v0.101.0 — memoise the artifact dropdown for 60s (R-267, operator ruling)
gates / gates (push) Successful in 28s

v0.100.x removed the serialisation: 26.2s -> ~9.85s mean. What remained was one Gitea package SEARCH
per dropdown at 0.20-3.8s depending on load, which concurrency cannot help.

Memoised for 60s IN MEMORY. The TTL was ruled by the operator against the workflow that cares: a
bake-and-vouch session publishes an artifact and comes straight here to select it, so a minute is
short enough not to be noticed and long enough that every reload in that session is instant.

NOT persisted. Gitea IS the store for both the version list and the sha; a copy in hub_settings would
be a second source of truth that can drift from the registry it describes, and the operator reads the
sha here to confirm what they are about to vouch. An in-memory cache dies with the process and can
never be mistaken for a record.

A failed resolve is NOT cached — a blip must not pin an empty dropdown for a minute. But an empty
list from a package that genuinely has no versions IS cached, because 'we found nothing' and 'we
could not look' are different answers (CONTEXT S-39, applied to a list instead of a figure).

THE FIRST VERSION OF THIS GOT THAT WRONG: the comment said only successful resolves were cached and
the code cached the empty list anyway. TestArtifactChoices_FailureIsNotCached caught it before it
shipped — which is the argument for writing the test that asserts the comment, and the same class
this session spent the day closing.

go build/vet/test green, go test -race clean, run separately from this commit.
This commit is contained in:
2026-08-08 20:08:51 +02:00
parent 1c14b91d6f
commit 7264f02172
3 changed files with 136 additions and 0 deletions
+31
View File
@@ -1,3 +1,34 @@
## v0.101.0 — the artifact dropdown is memoised for 60 seconds (2026-08-08, R-267, operator ruling)
v0.100.x took `/configuration` from 26.2 s to a mean of ~9.85 s by removing the serialisation. What
remained was **one Gitea call per dropdown** — the package search — measured at **0.203.8 s each
depending on load**, which concurrency cannot help (two together took 3.68 s against 3.82 s for one
alone; Gitea appears to serialise them).
**Memoised for 60 s, in memory.** The operator ruled the TTL against the one workflow that cares: a
bake-and-vouch session publishes an artifact and comes straight here to select it. A minute is short
enough not to be noticed and long enough that every reload in that session is instant.
**NOT persisted, and the reason is a rule this project already holds.** Gitea IS the store for both
the version list and the sha. A copy in `hub_settings` would be a second source of truth that can
drift from the registry it describes — and the operator reads the sha here to confirm what they are
about to vouch, so a stale one would be a confident wrong answer. `golden_currency_gate.py` records
the same reasoning for the vouched version. An in-memory cache dies with the process and can never be
mistaken for a record.
**A failed resolve is not cached** — a Gitea blip must not pin an empty dropdown in front of the
operator for a minute. **But an empty list from a package that genuinely has no versions IS cached**,
because "we found nothing" and "we could not look" are different answers; that distinction is
CONTEXT S-39 applied to a list instead of a figure. **The first version of this commit got that
wrong** — the comment claimed only successful resolves were cached and the code cached the empty
list anyway. `TestArtifactChoices_FailureIsNotCached` caught it before it shipped, which is the whole
argument for writing the test that asserts the comment.
Seven tests now cover the dropdown: order (and that each sha belongs to its own version),
per-version failure isolation, the concurrency itself (wall-clock plus an in-flight counter plus an
upper bound), the cap, the TTL hit, the failure-not-cached rule, and per-package isolation.
`go test -race` clean.
## v0.100.2 — the Configuration page took 26 seconds, and it was never hashing anything (2026-08-08)
**Measured, not guessed:** `GET /configuration`**HTTP 200 in 26.2 s**.