Repository navigation
fix: address remaining review findings from PR #55's floating feature - #58
Merged
Merged
Conversation
Fixes 5 of the 6 previously-deferred, pre-existing (not introduced by the earlier floating-feature fixes) review findings; the 6th (ViewManager.AddView's UpdateDuplicateKey path overwriting a still-floating view's cache slot) turned out to be intended, tested behavior once verified against CloseOldInstance_DoesNotRemoveNewInstanceCacheOrHistory, so it was left as-is. - RegionNavigationService.OnAfterNavigationAsync: call OnNavigatedFromAsync before the pipeline's cancellation check throws, if cancellation raced in right after OnNavigatedToAsync succeeded - otherwise the view's lifecycle state (activated, never told it left) goes out of sync with the region reverting. Covered by a new regression test that reproduces the race via a test double's activation hook. - WeakUnloadObserver.Subscribe: take Func<INavigationAware, Task> instead of Action<INavigationAware> and await it, so its one caller's async lambda is a real awaited continuation instead of async-void with unobservable exceptions. - ViewManager: Remove(key, dispose) now returns bool (true if it actually removed something) instead of silently no-op'ing when the entry is pinned by a floating view, so callers can tell the two cases apart. - ViewManager.TrimCache: resume scanning from where the previous eviction left off instead of restarting from the LRU tail every iteration, avoiding O(evictions * pinned-views) work when floating views sit at the tail. - Extracted the "cancel the window's close, then raise CloseRequested" state machine - duplicated near-verbatim between AvaloniaFloatingWindowHost and WpfFloatingWindowHost - into a shared FloatingWindowCloseGuard in AsyncNavigation.Floating, so this exact subtle dance only needs fixing once. Verified: dotnet test tests/AsyncNavigation.Tests (158 passed) and tests/AsyncNavigation.E2E.Tests (9 passed), Debug and Release, plus a full solution build - all green. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
Follow-up to #55/#57. Fixes 5 of the 6 previously-deferred review findings on the floating feature (pre-existing, not introduced by #57's contended-lease fix); the 6th turned out to be a false positive once checked against an existing test.
OnNavigatedFromAsyncbefore the pipeline's cancellation check throws, if cancellation raced in right afterOnNavigatedToAsyncsucceeded — otherwise the view's lifecycle state (told it's activated, never told it left) goes out of sync with the region reverting to whatever was active before. Covered by a new regression test (Navigation_CancelledRightAfterActivation_StillCallsOnNavigatedFrom) that reproduces the exact race via a test-double activation hook.Func<INavigationAware, Task>instead ofAction<INavigationAware>and awaits it, so its one caller's async lambda is a real awaited continuation instead of async-void with unobservable exceptions.bool(true if it actually removed something) instead of silently no-oping when the entry is pinned by a floating view, so callers can tell the two cases apart. (IViewManager.Removesignature updated to match — source-compatible for every existing caller, which all discard the return value.)AsyncNavigation.Floating): extracted the "cancel the window's close, then raiseCloseRequested" state machine that was duplicated near-verbatim betweenAvaloniaFloatingWindowHostandWpfFloatingWindowHost, so this exact subtle dance only has to be gotten right once.Not changed:
ViewManager.AddView'sUpdateDuplicateKeypath overwriting a still-floating view's cache slot. The review flagged this as orphaning the floating instance from the cache map, butCloseOldInstance_DoesNotRemoveNewInstanceCacheOrHistoryalready tests and requires exactly this behavior (the fresh instance must become the authoritative cache entry so it's reusable once the old floating one closes) — applying the suggested guard broke that test, confirming the original behavior is intentional, not a bug.Test plan
dotnet test tests/AsyncNavigation.Tests— 158 passed (Debug and Release)dotnet test tests/AsyncNavigation.E2E.Tests— 9 passed (Debug and Release)FloatingWindowLifecycleTests.Dock_and_close_raise_separate_requestsheadless testCo-Authored-By: Claude Sonnet 5 noreply@anthropic.com