Skip to content

Fix stale README after cached repo tree refresh (RepoCodePage race) - #109

Merged
Xueyang-Song merged 1 commit into
mainfrom
claude/amazing-newton-cffdd5
Oct 28, 2026
Merged

Xueyang-Song merged 1 commit into
mainfrom
claude/amazing-newton-cffdd5

Conversation

@Xueyang-Song

Copy link
Copy Markdown
Collaborator

Summary

RepoCodePageViewModelTests.Initialize_CachedTreeRefreshReloadsReadmeWhenShaChanges failed in about 1 of 10 full-suite runs (Expected "readme-new", Actual "readme-old"). The test wasn't asserting too early: it already waits on TreeRefreshTask and DefaultPreviewTask, and the refresh waits on both the reconciliation and the default preview before it completes. The view model had a race. The fix is in JitHub.WinUI, and the test is unchanged.

Cause

When the code page opens from a stale cached tree, two background jobs start at once:

  1. a README preview for the cached tree (readme-old), and
  2. a tree refresh (NetworkOnly).

ApplyTreeAsync takes a snapshot of the visible file in one UI step. In a later UI step it applies the new tree and decides from that snapshot whether to reload the visible file. If the cached README finished loading between those two steps:

  • the snapshot showed no file, so the refresh skipped the reload and queued a new README preview instead;
  • that preview then saw a file already showing (Preview.CurrentFile is not null) and did nothing;
  • the stale readme-old stayed visible over a tree that lists readme-new.

This can happen in the app too, because the two UI steps are separate dispatcher posts. Tests have no dispatcher, so the window is wider there. When the README load landed while the new tree was being applied, a second outcome was an empty preview.

Fix

RefreshTreeInBackgroundAsync now waits for the in-flight default README preview to finish (the existing AwaitDefaultPreviewSettledAsync) before calling ApplyTreeAsync. The snapshot then reflects what is actually visible:

  • if the README sha changed, the existing reload path opens the fresh README;
  • if nothing is showing, the existing README preview opens it from the new tree.

Notes:

  • The task coordinator always completes its task normally, so this wait can't fault.
  • Route cancellation goes through the method's existing cancellation handler.
  • The preview never waits on the refresh, so this can't deadlock.
  • Trade-off: when the cached README loads more slowly than the network tree fetch, the refreshed tree now applies after that README load finishes instead of interrupting it.

Verification

  • Stress repro (temporary, not committed): the test's exact scenario run 2,560 times, 64 at a time.
    • Before: 94 failures (73 showed readme-old, 21 showed nothing).
    • After: 0 failures in 7,680.
  • All 83 RepoCode* tests pass.
  • 20 full-suite runs of dotnet test JitHub.WinUI.Tests/JitHub.WinUI.Tests.csproj -c Debug -p:Platform=x64: the target test passed in all 20.

Not changed (possible follow-up)

A file the user selects can hit the same snapshot gap if it finishes loading between the two UI steps of a tree refresh. One fix is to re-read Preview.CurrentFile inside the apply step. This PR doesn't change that, to keep it to the README path that the flaky test covers.

🤖 Generated with Claude Code

When the code page opens from a stale cached tree, it queues a README
preview and a background tree refresh at the same time. The refresh
snapshots the visible file, then applies the new tree and decides
whether to reload it. If the cached README finished loading between
the snapshot and the apply, the refresh saw "no file shown", skipped
the reload, and queued a README preview that then saw a file already
showing and did nothing. The stale README stayed over the new tree.

Wait for the in-flight default preview to settle before applying the
refreshed tree so the snapshot reflects what is actually visible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Xueyang-Song
Xueyang-Song merged commit 146d39c into main Oct 28, 2026
11 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants