Skip to content

fix: re-resolve view definitions on a page-level "refresh now" - #663

Merged
tkuhn merged 1 commit into
masterfrom
fix/page-refresh-view-versions
Aug 28, 2026
Merged

fix: re-resolve view definitions on a page-level "refresh now"#663
tkuhn merged 1 commit into
masterfrom
fix/page-refresh-view-versions

Conversation

@tkuhn

@tkuhn tkuhn commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

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 by QueryApiAccess.latestVersionMap and ApiCache. 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 first View.get(id) per id calls refreshLatestVersion(id) instead of reading the memo, and the re-memoized answer serves the rest of the build. buildViewDisplays wraps 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.
  • Views outside the 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 via the new QueryResult.getShownViewId(), the way a view display's own "refresh now" does.
  • Publishing re-resolves the definitions too (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, so RefreshingStructurePanel would 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") declares gen:governedBy, so it floats by get-latest-governed-version, not the supersedes chain. refreshLatestVersion clears that query's entry as well.

Verified

Headless Playwright against a second jetty on :37374, driving the real menu click:

  • SEMANTiCS 2026 space (ref-scoped get-view-displays-unresolved): one click → 1 structure query + 12 forced get-latest-version-of-np + 3 forced get-latest-governed-version lookups, page re-rendering clean;
  • home page (pre-resolved 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;
  • no errors in either run.

Not exercised, as in #657: the flip itself on a just-superseded definition, which needs publishing a new view version.

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>
@tkuhn
tkuhn merged commit 2ef3343 into master Aug 28, 2026
8 checks passed
@tkuhn
tkuhn deleted the fix/page-refresh-view-versions branch August 28, 2026 13:29
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.

1 participant