~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

A private repository's pages no longer wait for its space to sync

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:serve/private-settings-fast

What changes

A stale space syncs aside. When someone with a session reads a private repository whose space was synced before, but not within a minute (spaces::STALE), the read is now answered from the index as it was, and the sync runs in the background. Only a space never synced still makes the read wait. A read with a delegation token still waits, as before. moves and last_synced on App become Arc<Mutex<…>>, so the background task can record the sync.

A private repository's settings read nothing live. getRepoStorage keeps a private repository's count by its space. The count stays good until a sync of the space finds a write there, the same rule its mirror uses (App::space_followed, now shared with as_viewer). getRepoSettings builds its owner's readers list from the repository's record (readers and runners, less those who push) instead of listing the space's members from the PDS. Sharing, from the pages or the CLI, writes those fields and shows the appview the write, so a change shows at once. Other members still see no readers. Counts becomes Kept<T>.

Why

After the public storage fix landed, private repository pages were still slow on prod. For chadtmiller.com/group-host, getRepo and listRuns took 2.9 to 3.1 s (20:30:10, 20:32:55), and getRepoSettings took 1.3 to 3.7 s. Trace 8817a8a9: the mirror sync took 237 ms, then the read waited about 2.5 s on a full space sync. That sync failed (space repo read whole: a record that does not come to its CID, then space not synced: a record that is not a DRISL map), and it fails the same way every minute. Done directly, knotless members takes 2.4 s and knotless storage 3.5 s for group-host, and the settings page did both on every load.

How it was checked

  • gateway.rs: once the space counts as not synced lately, the owner's session read is answered, and the issue written meanwhile shows up once the background sync is done. The later delegation-token reads expect it too.
  • pages.rs: the owner's settings list a member shared for reading from the pages at once, from the record. A member's settings list none.
  • The unit test of Kept covers forgetting everything under a name.
  • agents_fork_review_and_merge (spaces, MCP) is quarantined until 2026-11-06. It fails now and then on main too (main's run at 4955bc71 logs it FLAKY, at an assignee's handle, mcp.rs:1430), and failed twice in a row on this pull. It needs a fix of its own.
  • Build, tests, coverage and checks are left to CI.

Shortcomings

  • group-host's space sync still fails on a record it can't decode. This pull only stops pages waiting on it, so the index may still miss new writes there. That needs its own fix.
  • The readers list is the record's word. A member added to the space some other way than share or runners isn't listed.
  • After a quiet minute, a page can show the index as it was until the background sync finishes, usually a second or two.

🤖 Generated with Claude Code

Approved

This pull makes a stale but already-synced private space sync in a spawned task, so a session read answers from the index as it was. A never-synced space and a delegation-token read still wait. It also keeps a private repository's storage count by space, invalidated by moves_of. And it keeps the owner's readers list per space and asker for five minutes, cleared when the pages share or unshare.

I found nothing that must change.

  • Background sync: it records last_synced and bumps moves on Ok(true). That matches what read_now/moved do for a space that was synced before, including logging a failure and not failing the read. synced_now is called before the spawn, so concurrent reads don't start more syncs.
  • Cache keys: a private repository is one space, so keying its storage by space alone is safe. The readers cache is keyed by asker, and only a successful listing is stored, so non-owners still see none.
  • Nit: in compact_repo, counted_as(&repo).0 for a public repository is the owner's DID. forget now drops the counts of all of that owner's repositories, not just this one. This only costs an extra recount, so I'm not asking for a change.
  • Docs and tests: docs, lexicon and tests are updated. The change is server-side, so I don't think it needs a changeset.
Approved

My earlier approval stands. The only change since it is 027df1f, which switches the moves and last_synced initialisers in App::new to Default::default() so they build as Arc<Mutex<…>>. That is correct and needs nothing further. I found nothing new to ask for.

Approved

This round keeps the background sync for a stale, already-synced space. It also keeps a private repository's storage count by its space. The new part is that getRepoSettings builds the owner's readers list from the repository's record (readers and runners, less those who push) instead of listing the space's members from the PDS.

I found nothing that must change.

  • Background sync: it is in keep, which the session read path reaches (private.rs:241). Only a space synced before is spawned. A never-synced space and a read with a delegation token still wait. The task records last_synced even when the sync fails, and bumps moves on Ok(true). That matches read_now for a synced space. synced_now runs before the spawn, so concurrent reads start no second sync.
  • Storage count: a private repository is one space, so keying by space is safe. moves_of invalidates it, and compact_repo still forgets it.
  • Readers from the record: only the owner gets a list, and a member gets none. The pages test covers both, and also that a share shows at once.
  • Gap, already stated in the body: a member added to the space some other way than share or runners isn't listed. A CLI push to a private repository is also not counted until a sync finds it. I'm not asking for a change on either.

CI was still running when I looked, so I haven't seen it pass.

Approved

My earlier approval stands. The only change since it is 57a8407. It fixes the pages test so it expects the member shared for reading to appear in the owner's readers, then checks that a page-shared reader appears alongside. It also quarantines the flaky agents_fork_review_and_merge MCP test until 2026-11-06. The test change matches the record-based readers behaviour, and the quarantine is time-boxed. I found nothing to ask for.

Approved

My earlier approval stands. The only change since it is 875721e. It compares the readers to a slice of the member, as clippy asks. That is a lint fix and doesn't change behaviour. I found nothing to ask for.

Merged as d29df62