Files
felhom.eu/hub/cmd/hub
admin 7855d6355c
gates / gates (push) Successful in 21s
hub v0.100.0 — the Configuration page took 26 seconds, and it was never hashing anything
MEASURED, NOT GUESSED: GET /configuration -> HTTP 200 in 26.2s.

The reasonable guess was that it hashes the artifacts on page load. It does not, and the code already
said so: Gitea stores each package file's sha256 and gitea.FileSHA256 reads it as metadata — "a cheap
metadata call, the artifact bytes are never downloaded". The cost was never CPU.

IT WAS LATENCY x COUNT. artifactChoices made ONE SERIAL round-trip per version, for two packages,
capped at 20 each: 2 x (1 version list + 20 sha lookups) = 42 sequential requests at ~0.6s each out
through the public ingress. 42 x 0.6 = 26s, which is what the clock said.

1. The sha lookups now run CONCURRENTLY, bounded at 8 in flight. Order preserved by writing into a
   slot rather than appending — the dropdown is newest-first, and a scrambled sha would show the
   operator a hash belonging to a DIFFERENT artifact. A failed lookup still drops that version only.
2. The client talks to Gitea IN-CLUSTER (http://gitea.gitea-system.svc.cluster.local:3000,
   overridable via GITEA_API_URL). Measured from the hub pod: 0.11s against 0.26-1.16s, because the
   public path adds DNS, the ingress hop and a TLS handshake to each of the 42. Plain HTTP is safe
   ONLY because it never leaves the cluster network — the registry token rides the Authorization
   header, so this must not point at a public host without TLS. Unreachable -> the existing graceful
   degradation to manual text entry, unchanged.

DELIBERATELY NOT DONE: caching the sha in the hub's own database. That was the other half of the
proposal and it is the wrong shape. Gitea already IS the store; a copy in hub_settings would be a
second source of truth that can drift from the registry it describes — and the operator reads exactly
this value to confirm what they are about to vouch, so a stale one would be a confident wrong answer.
The same reasoning golden_currency_gate.py already records for the vouched version. With the fan-out,
a cold load needs no cache to be fast.

The cap stays at 20 and now bounds the FAN-OUT too, not just the rendered list.

Tests pin order (and that each sha belongs to its own version), per-version failure isolation, and
THE CONCURRENCY ITSELF — a wall-clock assertion plus an in-flight counter, so a fast run cannot be
luck, and an upper bound so a large package list cannot stampede Gitea. Red-proof: reverting to the
serial loop takes 861ms where the concurrent one takes 150ms, and the test fails naming the
26-second page.

go build / go vet / go test ./... green (18 packages), run separately from this commit.
2026-08-08 17:41:52 +02:00
..