realm-server: extend job-scoped search cache to _federated-search-prerendered#4869
Closed
habdelra wants to merge 1 commit into
Closed
realm-server: extend job-scoped search cache to _federated-search-prerendered#4869habdelra wants to merge 1 commit into
habdelra wants to merge 1 commit into
Conversation
…rendered Wraps `searchPrerenderedRealms` in the `_federated-search-prerendered` handler with the same `JobScopedSearchCache` instance already used by `_federated-search`, gated on the same `x-boxel-job-id` + `x-boxel-consuming-realm` indexer-traffic headers. User-facing API callers continue to bypass the cache and observe live state. The prerendered handler's request shape carries htmlFormat / cardUrls / renderType which materially change the response body. These are passed through `opts` so the cache's sortKeysDeep-canonicalised inner key segregates entries that differ on any of them; the cache class stays signature-stable (`getOrPopulate(jobId, realms, query, opts, populate)`), and stores results opaquely so both endpoints' document types share the same store. Host: PrerenderedSearchResource stamps the consuming-realm and job-id headers on its outbound `_federated-search-prerendered` request, the same pattern store.ts uses for `_federated-search`. The three header helpers (during-prerender / consuming-realm / job-id) move from store.ts to a shared `lib/prerender-fetch-headers.ts` module so both fetch sites read the globals identically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Superseded by #4870 (same scope, plus the per-job hit/miss instrumentation folded in). |
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
The per-job
JobScopedSearchCachealready covers_federated-searchbut_federated-search-prerenderedcallssearchPrerenderedRealmsdirectly and bypasses it. Realms that drive their cards throughPrerenderedSearchResourcetherefore re-run the same SQL+HTML lookups on every cohort render during a reindex, while realms that drive cards throughstore.searchride the cache. This PR makes the two endpoints symmetric: the prerendered handler wraps its live SQL call in the same cache instance, gated on the same indexer-traffic headers.Trigger condition
The cache is consulted on
_federated-search-prerenderedonly when both of the following hold:x-boxel-job-idis present and well-formed (only the indexer worker stamps this; user / API callers never carry it), ANDx-boxel-consuming-realmis present and well-formed (the host's render route sets it only during prerender).Any request without either header falls through to a live populate, exactly like today. Both gates re-use the existing
sanitizePrerenderJobId/sanitizeConsumingRealmHeaderhelpers — no new sanitisers, no new headers.Cache-key extension
buildInnerKey's signature (realms,query,opts) is unchanged. The prerendered endpoint's response varies with three additional request fields:prerenderedHtmlFormat(embedded|fitted|atom|head)cardUrls(optional filter)renderType(optional codeRef)All three are folded into
optsbefore the call, so thesortKeysDeep-canonicalised key already segregates entries that differ on any of them. A test asserts that flippingprerenderedHtmlFormator addingcardUrlsunder an otherwise-identical(jobId, realms, query)tuple fires a fresh populate.CachedEntry.resultis now stored asunknown(typed atgetOrPopulate's call site via a generic), so the same instance can hold bothLinkableCollectionDocumentandPrerenderedCardCollectionDocumentresults without one endpoint serving the other's shape — collisions are structurally impossible because the inner key segregates by every parameter that affects the response.Host plumbing
PrerenderedSearchResource.fetchPrerenderedCardsnow attaches the same three prerender-context headers (x-boxel-during-prerender,x-boxel-consuming-realm,x-boxel-job-id) thatstore.tsalready attaches to_federated-search. The three header-helper functions move fromstore.tsto a sharedhost/app/lib/prerender-fetch-headers.tsmodule so both fetch sites read the page globals identically. Live (non-prerender) SPA fetches see no values for any of those globals and continue to send no headers.Shared cache instance
The same
searchCacheconstructed atroutes.ts:118is now passed to bothhandleSearch({ searchCache })andhandleSearchPrerendered({ searchCache }). One cache, shared.Test plan
server-endpoints/search-prerendered-test.tscover the hit/miss-by-jobId path, the htmlFormat / cardUrls cache-key extension, and the no-headers bypass.JobScopedSearchCacheunit tests and_federated-searchcache test continue to pass under the now-genericgetOrPopulate<T>.PrerenderedSearchResource(e.g. asearchPrerendered-heavy realm during a reindex): confirm fewer SQL-levelsearchPrerenderedpopulates land per job.🤖 Generated with Claude Code