Repository navigation
perf(hub): cross-project pages stop re-reading every activity log (2.146.0) - #199
Merged
Merged
Conversation
find_last JSON-parsed every line walking back, so a type a project never logged cost a parse of the whole file (up to the 5 MB cap). The Hub's list_projects calls it about six times per project on every request. Chunks and lines without the type's JSON-encoded name are now skipped unparsed, and get_recent reads its tail from the end of the file instead of the whole file forward. list_projects: 628 ms -> 173 ms on 71 projects. Claude-Session: https://claude.ai/code/session_01DEKoSbeEFepPGwPHQDHxAJ
The missing-value flag added in 2.144 called is_resolvable per entry, which re-read config.json and re-resolved the home and project paths each time: 43 entries cost 362 registry reads, 912 path resolutions and 120 keyring reads. value_presence reads the registry, realm, sidecar and master key once per vault. is_resolvable delegates to it; the project UI, c3_credentials list and c3 creds list use presence_for over their merged view, and backup status probes each vault once and accepts a caller's map. Claude-Session: https://claude.ai/code/session_01DEKoSbeEFepPGwPHQDHxAJ
Eleven Hub call sites used list_projects() only for names and paths, paying for its per-project activity-log scan and session-port probes on every request, including the 5 s polls on the locks, access and enforcement pages. They now call list_registered(), the stored rows. The credentials overview and project listing probe each vault once via value_presence and hand the result to the backup banner instead of probing every entry twice. Test stubs rename list_projects to match. Claude-Session: https://claude.ai/code/session_01DEKoSbeEFepPGwPHQDHxAJ
Every orphan C3 record checked every folder under ~/.claude/projects for its transcript (9.6k stat calls per Hub sessions request), and a project without an exact slug match re-listed the root. One listing now serves the whole request, and a transcript found in another folder goes through the per-file cache instead of being re-read each time. The listing is not kept across requests: Windows does not refresh a folder's mtime in its parent's listing when a file is created inside, so a kept one misses new sessions. Claude-Session: https://claude.ai/code/session_01DEKoSbeEFepPGwPHQDHxAJ
The Hub CI tab re-inspects every 10 s (2 s during a run), and each inspect spawned act --version, docker version and docker image inspect: 250 ms here, and a stalled Docker Desktop can hold it for the 30 s probe timeout. inspect_project now passes max_age so a recent probe is reused. Starting a run and c3_ci doctor call availability() without it and still probe fresh. Claude-Session: https://claude.ai/code/session_01DEKoSbeEFepPGwPHQDHxAJ
babel-standalone's default presets include preset-env, which compiled the 600 KB Hub bundle to ES5 on every page load (1.9 s on a desktop vs 0.35 s for JSX alone); both shells now ask for the React preset only. The global vault manager takes its rows from the Credentials page's overview instead of loading it again. usePoll skips a tick while the last call is running, and the project list polls every 30 s off the Projects view. Both bundles ran top-level in a VM, and the Hub rendered in Chrome with no errors. Claude-Session: https://claude.ai/code/session_01DEKoSbeEFepPGwPHQDHxAJ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Hub's Credentials page was slow to open and slow after every save, worst on a work laptop. Almost none of the time went to credentials. Every cross-project route called
list_projects()just for names and paths, and that call re-reads every project's activity log to work out live sessions.ActivityLog.find_lastJSON-parsed each line on the way back, so a type a project had never logged cost a parse of the whole file, about six times per project.Measured with 71 registered projects, same box, origin/main vs this branch:
/api/hub/credentials/overview/api/hub/credentials/audit/api/hub/sessions/api/hub/tokens/overview/api/projects(5 s poll)/api/ci/inspect(2–10 s poll)One commit per change:
find_lastand typedget_recentskip chunks and lines without the type's JSON name before parsing.get_recentreads its tail from the end.value_presence()checks a whole vault with one registry read. Before, 43 entries cost 362config.jsonreads and 912 path resolutions.is_resolvabledelegates to it.list_registered(), the stored rows. The backup banner reuses the listing's probe.doctorstill probe fresh.data-presets="react", since babel's default ran preset-env on the 600 KB bundle. The global vault manager reuses the page's overview instead of fetching it a second time.usePollno longer overlaps a slow call, and the project list polls every 30 s off the Projects view.Not measured: the work laptop itself. If its projects sit on network drives, per-project I/O may still dominate there.
Verification: ruff clean. New tests cover the prefilter, the tail window, per-kind presence answers, registry-read counts, transcript-root staleness and the probe cache. Both JS bundles ran top-level under the React-only preset in a Node VM, and the branch's Hub rendered in Chrome with no console errors (one overview request on the Credentials page, 21/21 global entries).
https://claude.ai/code/session_01DEKoSbeEFepPGwPHQDHxAJ