mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-30 05:55:34 +00:00
appview: read the sailor profile from the local users row, not the PDS, per request
Hold discovery in the registry middleware called getRecord on the repository owner's PDS for every request under /v2/: every HEAD, POST, PATCH, PUT and GET. A 10-layer push was 40 or more PDS round trips, and it was the last per-request network call on the push path that had nothing to do with moving bytes. Only two profile fields are used there: the default hold and the auto-remove-untagged flag. The users row already caches the default hold, written by the Jetstream processor on every profile event and prefilled by the backfill, and the auth gate already reads it from there. This makes the row a faithful copy of what the registry needs and switches the middleware to it. The auto-remove flag gets a nullable users column. NULL means the value has never been learned; the processor writes 0 or 1 on every profile event and never NULL. On a request whose row is missing or still NULL, the middleware does one live fetch, uses it, and writes both fields back, including a 0 for a user with no profile at all, so the fallback runs at most once per user. A failed fetch writes nothing and uses the appview default for that request, so a network error is never cached. That single mechanism covers the minutes after a deploy while the startup backfill fills the column, a brand-new user, and a user the backfill has not reached. The processor also stops returning early on an empty default hold, which left a user who removed their custom hold pushing to it forever. Empty is now written through and means the appview default, matching what the auth gate already reads. Tests count PDS requests with a test server: a populated row makes none, a NULL row makes exactly one and then none, a missing profile is cached as known, and a failed fetch degrades without writing. The migration was applied to a fresh database and to one built from the previous schema. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018Yf1ZVA7sXYhQNb9tCo1m5
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
47a107058d
commit
7045e84c00
+5
-2
@@ -18,7 +18,8 @@ ATCR supports "Bring Your Own Storage" (BYOS) for blob storage. Users can:
|
||||
│ - Profile management │
|
||||
└────────────┬─────────────────────────────┘
|
||||
│
|
||||
│ Hold discovery (findHoldDIDAndProfile):
|
||||
│ Hold discovery (findHoldDIDAndPrefs), read from
|
||||
│ the local users row, not the PDS:
|
||||
│ 1. io.atcr.sailor.profile.defaultHold (DID)
|
||||
│ 2. AppView default hold (server.managed_holds[0])
|
||||
│
|
||||
@@ -215,7 +216,9 @@ fly secrets set HOLD_REGISTRATION_OWNER_DID=did:plc:your-did-here
|
||||
2. AppView resolves alice → did:plc:alice123
|
||||
|
||||
3. AppView discovers hold DID:
|
||||
- Check alice's sailor profile for defaultHold
|
||||
- Read alice's cached defaultHold from the local users row, which Jetstream
|
||||
keeps current from her sailor profile. Only a row that has never been
|
||||
filled costs one live profile fetch, and that fetch is written back.
|
||||
- Returns: "did:web:alice-storage.fly.dev"
|
||||
|
||||
4. AppView gets service token from alice's PDS:
|
||||
|
||||
@@ -128,7 +128,7 @@ The flow the operator described:
|
||||
|
||||
```
|
||||
1. docker: POST https://<appview>/v2/<identity>/<image>/blobs/uploads/
|
||||
2. AppView: resolve hold DID (findHoldDIDAndProfile + resolveSuccessor)
|
||||
2. AppView: resolve hold DID (findHoldDIDAndPrefs + resolveSuccessor)
|
||||
check hold push policy (anonymous push allowed?)
|
||||
if auth required: mint/fetch service token (aud=hold DID) via user OAuth
|
||||
-> 202 Accepted
|
||||
@@ -228,7 +228,7 @@ pursued.
|
||||
| Change | Where |
|
||||
|---|---|
|
||||
| `POST .../blobs/uploads/` returns a cross-host hold Location instead of driving `ProxyBlobStore.Create` | new handler ahead of the distribution `/v2` handler; see "Distribution interaction" |
|
||||
| Hold push-policy check during handshake | `findHoldDIDAndProfile` result + captain push policy (Jetstream-fed local table, keep it local-fast) |
|
||||
| Hold push-policy check during handshake | `findHoldDIDAndPrefs` result + captain push policy (Jetstream-fed local table, keep it local-fast) |
|
||||
| Mint service token for upload, embed in Location | reuse `GetOrFetchServiceToken` (`pkg/auth/servicetoken.go`) |
|
||||
| `HEAD .../blobs/<digest>` (existence / layer skip) stays on AppView | answer from local layer metadata / hold query; keeps docker's skip-existing fast |
|
||||
| Manifest `PUT` stays on AppView; verify referenced blobs exist on the hold before storing | `manifest_store.go` + a hold existence check |
|
||||
|
||||
Reference in New Issue
Block a user