fix: re-resolve view definitions on a page-level "refresh now" - #663
Merged
Conversation
The page-level entry only forced the structure query and marked the views' results as outdated. The view definitions kept coming from the resolution memo in View, which is re-checked once a minute in the background and whose lookups are themselves served stale-while-revalidate, so a view superseded a moment ago only appeared on the second or third click. #657 fixed this for a single view display's "refresh now"; the page-level counterpart never called it. - View.withFreshResolution(Supplier) opens a scope in which the first View.get(id) per id goes back to the API instead of the memo, and the re-memoized answer serves the rest of the build. The structure build runs inside it, so it does not matter which id a view is looked up by — the referenced version for a display, the hard-coded id for a built-in view. - requestViewRefresh() asks for it, taken by the structure update, which runs on the update thread: the lookups block and have no business on a request thread. - Views built outside the page's structure (the About and Explore tabs build their own) have no refreshed view list to pick a newer definition up from, so the click re-checks them directly, as a view display's own refresh does. - Publishing asks for the definitions to be re-resolved too: what was just published can be a new version of a view the page shows. Only the definitions — refreshing every view's results is what #622 took away. - getStructureSignature() includes the resolved view id, not just the referenced one, or a new version of an already-referenced view would leave the signature unchanged and RefreshingStructurePanel would never swap the content in. Space-governed views float by get-latest-governed-version rather than the supersedes chain, which the refresh clears too — verified against a live governed view (SEMANTiCS 2026's extended-message-view), where one click issues the forced governed lookup it needs. Co-Authored-By: Claude Opus 5 (1M context) <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.
Follow-up to #657 / #662, closing the same gap on the page-level entry.
The problem
"refresh now" in the page title menu forced the structure query and marked the views' results as outdated, but never re-checked the view definitions. Those come from
View.latestResolvedViews, a memo re-resolved only once a minute in the background — and that background re-resolution is itself served stale-while-revalidate byQueryApiAccess.latestVersionMapandApiCache. So a view superseded a moment ago kept rendering as its previous version, and only turned up on the second or third click.The change
View.withFreshResolution(Supplier)— inside the scope, the firstView.get(id)per id callsrefreshLatestVersion(id)instead of reading the memo, and the re-memoized answer serves the rest of the build.buildViewDisplayswraps the whole structure build in it, so it does not matter which id a view is looked up by: a display resolves the version its nanopub references, a built-in view the id hard-coded for it. (A first attempt guessed the id from the query row's?view; the scope removes the guess.)requestViewRefresh()sets the request; the structure update takes it and runs the lookups on the update thread, never on a request thread.QueryResult.getShownViewId(), the way a view display's own "refresh now" does.requestViewDefinitionRefresh(), called from the publish listener): the nanopub just published can be a new version of a view the page shows. Definitions only — refreshing every view's results is what Auto-refresh after publishing doesn't always refresh the right things #622 took away.getStructureSignature()includes the resolved view id, not just the referenced one. A new version of an already-referenced view leaves the reference unchanged, soRefreshingStructurePanelwould have decided "structure unchanged" and never swapped the content in.Space-governed views
The case that exposed the gap: SEMANTiCS 2026's
extended-message-view(RAbdvJ8…→RAmu7tmj…, "💬 Messages (incl. sub-spaces and resources)" → "💬 All messages") declaresgen:governedBy, so it floats byget-latest-governed-version, not the supersedes chain.refreshLatestVersionclears that query's entry as well.Verified
Headless Playwright against a second jetty on :37374, driving the real menu click:
get-view-displays-unresolved): one click → 1 structure query + 12 forcedget-latest-version-of-np+ 3 forcedget-latest-governed-versionlookups, page re-rendering clean;get-view-displays): 1 structure query + 1 governed lookup — down from 18 supersedes lookups in the first attempt, since the pre-resolved variant needs no client-side chain lookups;Not exercised, as in #657: the flip itself on a just-superseded definition, which needs publishing a new view version.