Remove the precomputed pageinfo cache (#63671) · mogya/github_docs@9a6ee54 · GitHub
Skip to content

Commit 9a6ee54

Browse files
heiskrCopilot
andauthored
Remove the precomputed pageinfo cache (#63671)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3f54fbf5-61d3-4bad-acb8-c9166d568794 Copilot-Session: c462fcc6-586e-4858-9e25-7cc27bd7fa50
1 parent f565d8f commit 9a6ee54

10 files changed

Lines changed: 14 additions & 260 deletions

File tree

‎.github/actions/precompute-pageinfo/action.yml‎

Lines changed: 0 additions & 44 deletions
This file was deleted.

‎.github/workflows/keep-caches-warm.yml‎

Lines changed: 2 additions & 5 deletions

‎.github/workflows/test.yml‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,6 @@ jobs:
141141
# Only routing tests cover archived enterprise server URLs.
142142
if: ${{ matrix.name == 'redirects' }}
143143

144-
- uses: ./.github/actions/precompute-pageinfo
145-
# Only pageinfo tests cover precomputed page info.
146-
if: ${{ matrix.name == 'article-api' }}
147-
env:
148-
ROOT: src/fixtures/fixtures
149-
150144
- name: Index fixtures into the local Elasticsearch
151145
# Run indexing only for suites that query the local Elasticsearch service.
152146
if: ${{ matrix.name == 'search' || matrix.name == 'languages' }}

‎.gitignore‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
# Node.js version specification
2525
.node-version
2626

27-
# Precomputed page info cache (brotli compressed)
28-
.pageinfo-cache.json.br
29-
3027
# getRemoteJSON() disk cache for archived content
3128
.remotejson-cache/
3229

‎Dockerfile‎

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,6 @@ FROM build AS warmup_cache
113113
# Generate remote JSON cache
114114
RUN npm run warmup-remotejson
115115

116-
# --------------------------------------
117-
# PRECOMPUTE STAGE: Precompute page info
118-
# --------------------------------------
119-
FROM build AS precompute_stage
120-
121-
# Generate precomputed page info. Only English + free-pro-team@latest
122-
# permalinks are cached; cache misses for older versions and translated
123-
# pages fall through to runtime compute (which is cheap and Fastly-cached
124-
# per pathname after the first hit).
125-
RUN npm run precompute-pageinfo -- --max-versions 1
126-
127116
# -------------------------------------------------
128117
# PRODUCTION STAGE: What will run on the containers
129118
# -------------------------------------------------
@@ -152,9 +141,6 @@ COPY --chown=node:node --from=build $APP_HOME/.next .next/
152141
# From warmup_cache stage
153142
COPY --chown=node:node --from=warmup_cache $APP_HOME/.remotejson-cache ./
154143

155-
# From precompute_stage
156-
COPY --chown=node:node --from=precompute_stage $APP_HOME/.pageinfo-cache.json.br* ./
157-
158144
# This makes it possible to set `--build-arg BUILD_SHA=abc123`
159145
# and it then becomes available as an environment variable in the docker run.
160146
ARG BUILD_SHA

‎package.json‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
"openapi-docs": "tsx src/rest/docs.ts",
7373
"playwright-test": "playwright test --config src/fixtures/playwright.config.ts --project=\"Google Chrome\"",
7474
"lint-report": "tsx src/content-linter/scripts/lint-report.ts",
75-
"precompute-pageinfo": "tsx src/article-api/scripts/precompute-pageinfo.ts",
7675
"prepare": "husky src/workflows/husky",
7776
"prettier": "prettier -w \"**/*.{ts,tsx,scss,yml,yaml}\"",
7877
"prettier-check": "prettier -c \"**/*.{ts,tsx,scss,yml,yaml}\"",

‎src/article-api/middleware/article-pageinfo.ts‎

Lines changed: 7 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ import contextualize from '@/frame/middleware/context/context'
77
import features from '@/versions/middleware/features'
88
import breadcrumbs from '@/frame/middleware/context/breadcrumbs'
99
import currentProductTree from '@/frame/middleware/context/current-product-tree'
10-
import { readCompressedJsonFile } from '@/frame/lib/read-json-file'
11-
12-
// scripts/precompute-pageinfo.ts imports this path; missing files fall back to live computation.
13-
export const CACHE_FILE_PATH = '.pageinfo-cache.json.br'
1410

1511
// Metadata rendering and breadcrumbs need this minimal middleware chain.
1612
async function makeRenderingReq(page: Page, pathname: string) {
@@ -33,7 +29,7 @@ async function makeRenderingReq(page: Page, pathname: string) {
3329

3430
type RenderingReq = Awaited<ReturnType<typeof makeRenderingReq>>
3531

36-
async function computeCacheableFromReq(renderingReq: RenderingReq, page: Page) {
32+
async function computePageInfoFromReq(renderingReq: RenderingReq, page: Page): Promise<PageInfo> {
3733
const context = renderingReq.context
3834

3935
const title = await page.renderProp('title', context, { textOnly: true })
@@ -67,24 +63,11 @@ async function computeBreadcrumbsFromReq(renderingReq: RenderingReq) {
6763
return renderingReq.context.breadcrumbs as Breadcrumb[] | undefined
6864
}
6965

70-
// Cache only title, intro, and product.
71-
// Breadcrumbs compute cheaply on cache hits and would bloat the cache file and dictionary.
72-
export async function getCacheablePageInfo(page: Page, pathname: string) {
73-
const renderingReq = await makeRenderingReq(page, pathname)
74-
return computeCacheableFromReq(renderingReq, page)
75-
}
76-
77-
// Breadcrumbs cost less than title and intro rendering, so cache hits compute them.
78-
export async function getBreadcrumbsForPage(page: Page, pathname: string) {
79-
const renderingReq = await makeRenderingReq(page, pathname)
80-
return computeBreadcrumbsFromReq(renderingReq)
81-
}
82-
83-
// getPageInfo reuses one rendering request on cache misses.
66+
// getPageInfo reuses one rendering request.
8467
// contextualize, shortVersions, and features run once for metadata and breadcrumbs.
85-
export async function getPageInfo(page: Page, pathname: string) {
68+
export async function getPageInfo(page: Page, pathname: string): Promise<PageInfoWithBreadcrumbs> {
8669
const renderingReq = await makeRenderingReq(page, pathname)
87-
const base = await computeCacheableFromReq(renderingReq, page)
70+
const base = await computePageInfoFromReq(renderingReq, page)
8871
const pageBreadcrumbs = await computeBreadcrumbsFromReq(renderingReq)
8972
return { ...base, breadcrumbs: pageBreadcrumbs }
9073
}
@@ -108,61 +91,16 @@ async function getProductPageInfo(page: Page, context: Context) {
10891
return _productPageCache[cacheKey]
10992
}
11093

111-
type CachedPageInfoEntry = {
94+
type PageInfo = {
11295
title: string
11396
intro: string
11497
product: string
11598
}
11699

117-
type CachedPageInfo = {
118-
[url: string]: CachedPageInfoEntry
119-
}
120-
121100
type Breadcrumb = { href: string; title: string }
122101

123-
type PageInfoWithBreadcrumbs = CachedPageInfoEntry & {
102+
type PageInfoWithBreadcrumbs = PageInfo & {
124103
breadcrumbs?: Breadcrumb[]
125-
cacheInfo?: string
126-
}
127-
128-
// getPageInfoFromCache does not fill the in-memory cache on misses.
129-
// Production sees each HTTP GET once per deploy because the CDN caches it until purge.
130-
// Local review does not need this cache path for performance.
131-
// CI warms the precomputed cache with npm run precompute-pageinfo before vitest.
132-
let _cache: CachedPageInfo | null = null
133-
export async function getPageInfoFromCache(
134-
page: Page,
135-
pathname: string,
136-
): Promise<PageInfoWithBreadcrumbs> {
137-
let cacheInfo = ''
138-
if (_cache === null) {
139-
try {
140-
_cache = readCompressedJsonFile(CACHE_FILE_PATH) as CachedPageInfo
141-
cacheInfo = 'initial-load'
142-
} catch (error) {
143-
cacheInfo = 'initial-fail'
144-
if (error instanceof Error && (error as NodeJS.ErrnoException).code !== 'ENOENT') {
145-
throw error
146-
}
147-
_cache = {}
148-
}
149-
}
150-
151-
const cached = _cache[pathname]
152-
if (!cacheInfo) {
153-
cacheInfo = cached ? 'hit' : 'miss'
154-
}
155-
156-
let meta: PageInfoWithBreadcrumbs
157-
if (cached) {
158-
// The precomputed cache omits breadcrumbs because cache hits can compute them cheaply.
159-
const pageBreadcrumbs = await getBreadcrumbsForPage(page, pathname)
160-
meta = { ...cached, breadcrumbs: pageBreadcrumbs }
161-
} else {
162-
meta = await getPageInfo(page, pathname)
163-
}
164-
meta.cacheInfo = cacheInfo
165-
return meta
166104
}
167105

168106
// pageValidationMiddleware follows redirects before getMetadata.
@@ -189,11 +127,9 @@ export async function getMetadata(req: ExtendedRequestWithPageInfo) {
189127
throw new Error(`pathname '${pathname}' not one of the page's permalinks`)
190128
}
191129

192-
const fromCache = await getPageInfoFromCache(page, pathname)
193-
const { cacheInfo, ...meta } = fromCache
130+
const meta = await getPageInfo(page, pathname)
194131

195132
return {
196133
meta: { ...meta, documentType, ...(redirectedFrom && { redirectedFrom }) },
197-
cacheInfo,
198134
}
199135
}

‎src/article-api/middleware/article.ts‎

Lines changed: 5 additions & 12 deletions

0 commit comments

Comments
 (0)