forked from github/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Robert Sese <734194+rsese@users.noreply.github.com>
- Loading branch information
Showing
10 changed files
with
247 additions
and
49 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: Warmup pageinfo cache | ||
|
||
description: Run this to create a .pageinfo-cache.json.gz file | ||
|
||
inputs: | ||
restore-only: | ||
description: Only attempt to restore, don't warm up | ||
required: false | ||
|
||
runs: | ||
using: 'composite' | ||
steps: | ||
# The caching technique here is to "unboundedly" add to the cache. | ||
# By unboundedly, it means the cached item will grow and grow. | ||
# The general idea is that we A) restore from cache, B) replace the | ||
# file by running the script, and C) save the file back to cache. | ||
# Optionally, you can have it just do A (and not B and C). | ||
|
||
- name: Cache .pageinfo-cache.json.gz (restore) | ||
# You can't use a SHA on these. Only possible with `actions/cache@SHA...` | ||
uses: actions/cache/restore@v3 | ||
with: | ||
path: .pageinfo-cache.json.gz | ||
key: pageinfo-cache- | ||
restore-keys: pageinfo-cache- | ||
|
||
# When we use this composite action from the workflows like | ||
# Azure Preview Deploy and Azure Production Deploy, we don't have | ||
# any Node installed or any of its packages. I.e. we never | ||
# run `npm ci` in those actions. For security sake. | ||
# So we can't do things that require Node code. | ||
# Tests and others will omit the `restore-only` input, but | ||
# prepping for Docker build and push, will set it to a non-empty | ||
# string which basically means "If you can restore it, great. | ||
# If not, that's fine, don't bother". | ||
- name: Run script | ||
if: ${{ inputs.restore-only == '' }} | ||
shell: bash | ||
run: npm run precompute-pageinfo | ||
|
||
- name: Cache .remotejson-cache (save) | ||
if: ${{ inputs.restore-only == '' }} | ||
uses: actions/cache/save@v3 | ||
with: | ||
path: .pageinfo-cache.json.gz | ||
key: pageinfo-cache-${{ github.sha }} |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#!/usr/bin/env node | ||
|
||
/** | ||
* This script gathers all English pages, computes each page's | ||
* 'title', 'intro' and 'product' properties. These things are then stored | ||
* in a JSON file (and gzipped) on disk. Then, the pageinfo middleware | ||
* can load in that JSON file to have a cache of pageinfo for all English | ||
* pages. | ||
* Now, when someone requests `/api/pageinfo?pathname=/en/foo/bar`, for the | ||
* backend, it just needs to read from a precomputed cache file instead | ||
* of having to do this computation on every request. Time saved, up front. | ||
* | ||
* Why cache?: Despite being a fast computation (3 Liquid + Markdown renders), | ||
* it still adds up. And it's safe and cheap to precompute in advance. | ||
* | ||
* Why only the English?: To make the file not too large. | ||
* Given how good these things compress, we might consider, in the | ||
* future, to do all languages. | ||
* | ||
* Why brotli?: Because the file gets included in the Docker container and | ||
* there every byte counts. | ||
* | ||
* When is this script run?: On every push to main, it gets computed | ||
* and uses actions/cache to store the result. Meaning, it's not run | ||
* during deployment. (During the deploy it only *downloads* from | ||
* actions/cache). | ||
*/ | ||
|
||
import fs from 'fs' | ||
import { brotliCompressSync } from 'zlib' | ||
|
||
import { loadPages, loadUnversionedTree } from '#src/frame/lib/page-data.js' | ||
import { CACHE_FILE_PATH, getPageInfo } from '../middleware.js' | ||
|
||
main() | ||
|
||
const CI = Boolean(JSON.parse(process.env.CI || 'false')) | ||
|
||
async function main() { | ||
const unversionedTree = await loadUnversionedTree(['en']) | ||
const pageList = await loadPages(unversionedTree, ['en']) | ||
|
||
let label = `Compute pageinfos for ${pageList.length.toLocaleString()} pages` | ||
console.time(label) | ||
const pageinfos = {} | ||
for (const page of pageList) { | ||
const pathname = page.permalinks[0].href | ||
try { | ||
const computed = await getPageInfo(page, pathname) | ||
if (computed) { | ||
pageinfos[pathname] = computed | ||
} | ||
} catch (error) { | ||
console.error(`Error computing pageinfo for ${page.fullPath} (${pathname})`) | ||
throw error | ||
} | ||
} | ||
console.timeEnd(label) | ||
|
||
label = `Serialize, compress, and write to ${CACHE_FILE_PATH}` | ||
console.time(label) | ||
const payload = CI ? JSON.stringify(pageinfos) : JSON.stringify(pageinfos, null, 2) | ||
const payloadBuffer = Buffer.from(payload, 'utf-8') | ||
const payloadCompressed = brotliCompressSync(payloadBuffer) | ||
fs.writeFileSync(CACHE_FILE_PATH, payloadCompressed) | ||
console.timeEnd(label) | ||
console.log( | ||
`Wrote ${Object.keys(pageinfos).length.toLocaleString()} pageinfos to ${CACHE_FILE_PATH}`, | ||
) | ||
} |