feat(maven): delivery-gate and buffer the hosted downloads_count bump
What
Split from the Step 11 cache-hit serve path (!1439 (merged)) at that MR's review: the hosted repositories.downloads_count activation and the shared delivery-gate machinery ship here, first, so the serve-path MR's remote last_downloaded_at gate lands on top of these delivery verdicts. Merge order: this MR merges first; !1439 (merged) rebases onto it.
In scope:
buffered.go— the interimbufferedUpdatefire-and-forget dispatch (Maven twin ofinternal/format/npm/buffered.go): 5s per-worker deadline, 64-deep in-flight semaphore that sheds asresult=dropped, panic recovery, Warn-not-Error failure logging, test-only wait hook. CarriesTODO(buffered).metrics.go—bufferedCounterUpdates+RegisterMetrics, registered at the composition root beside npm's and oci's.download.godelivery gate —servePrimaryGet/serveStream/serveFull/serveRedirectreport delivery (full 200 body copy or written 302);bumpArchiveDownloadCountfires for archive-class GETs under that verdict. A206/416partial, CAS miss, or abandoned transfer counts nothing (mirroring npm'sdeliveryModeNonegate). The synchronous pre-response bump is removed.BumpRepoDownloadCountactivation (datastore) — executes itsUPDATEdirectly with the soft-delete leg, instead of the no-op stub; unit + integration pins flip to the positive increment.- S10 amendment — the counting rule retires the pre-response bump and states the delivery gate and the 206 case.
- Marker alignment (
TODO(buffered)), observability catalog row, plan split record (Status row 11a).
The last_downloaded_at label of the shared metric, the remote parents' bump, and the serve-path tests live in !1439 (merged).
Merge order
This MR lands first (the plan records the split and the order). The delivery verdicts it introduces are what !1439 (merged)'s remote last_downloaded_at gate consumes; until this merges, those verdicts do not exist on main.
Tests
TestBufferedUpdate_*(buffered_test.go): happy path, fn error, panic safety, shedding, deadline, cancellation detach, metric outcomes.TestPrimaryGET_ArchiveBumpDispatchesOffRequestPath+TestPrimaryGET_CounterBumpRuleszero arm (download_internal_test.go/download_test.go): one off-request-path dispatch per delivered archive; non-archive never dispatches.- Usage-data flips (
download_usagedata_test.go): abandoned transfer / over-long object no longer bumpdownloads_count. TestMavenRepositoryStore_BumpRepoDownloadCount_*: argument guards + execute pin (unit,recordingDB) and the +1 increment (integration).TestRegisterMetrics_ExposedViaGathererwith themavenCollectorslength guard.
Run: go test ./internal/format/maven/... ./internal/datastore/... -tags=integration and the unit suites.
Related to #286 (closed)