зеркало из https://github.com/github/docs.git
Memoize loadRedirects() with disk (#22161)
* memoize loadRedirects with disk in development * no need to await on sync functions * un-uncomment * wip * wip * cache with max age * rename redirects memoize cache file
This commit is contained in:
Родитель
711bd22f02
Коммит
da419fd869
|
@ -15,3 +15,4 @@ coverage/
|
|||
blc_output.log
|
||||
blc_output_internal.log
|
||||
broken_links.md
|
||||
lib/redirects/.redirects-cache_*.json
|
||||
|
|
|
@ -1,22 +1,53 @@
|
|||
import { languageKeys } from '../languages.js'
|
||||
import assert from 'assert'
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import { isPromise } from 'util/types'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import readJsonFile from '../read-json-file.js'
|
||||
import { latest } from '../../lib/enterprise-server-releases.js'
|
||||
import getExceptionRedirects from './exception-redirects.js'
|
||||
const developerRedirects = readJsonFile('./lib/redirects/static/developer.json')
|
||||
const latestDevRedirects = {}
|
||||
import { languageKeys } from '../languages.js'
|
||||
|
||||
// Replace hardcoded 'latest' with real value in the redirected path
|
||||
Object.entries(developerRedirects).forEach(([oldPath, newPath]) => {
|
||||
latestDevRedirects[oldPath] = newPath.replace(
|
||||
'enterprise-server@latest',
|
||||
`enterprise-server@${latest}`
|
||||
)
|
||||
})
|
||||
function diskMemoize(filePath, asyncFn, maxAgeSeconds = 60 * 60) {
|
||||
return async (...args) => {
|
||||
try {
|
||||
const stats = await fs.stat(filePath)
|
||||
const ageSeconds = (new Date().getTime() - stats.mtime.getTime()) / 1000
|
||||
if (ageSeconds < maxAgeSeconds) {
|
||||
const value = JSON.parse(await fs.readFile(filePath, 'utf-8'))
|
||||
console.log(`Redirects disk-cache HIT on ${filePath}`)
|
||||
return value
|
||||
}
|
||||
console.log(`Redirects disk-cache ${filePath} too old`)
|
||||
} catch (err) {
|
||||
if (err.code !== 'ENOENT') throw err
|
||||
}
|
||||
console.log(`Redirects disk-cache MISS on ${filePath}`)
|
||||
const promise = asyncFn(...args)
|
||||
assert(isPromise(promise), "memoized function didn't return a promise")
|
||||
return promise.then(async (value) => {
|
||||
await fs.writeFile(filePath, JSON.stringify(value), 'utf-8')
|
||||
return value
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const DISK_CACHE_FILEPATH = path.join(__dirname, `.redirects-cache_${languageKeys.join('_')}.json`)
|
||||
|
||||
// This function runs at server warmup and precompiles possible redirect routes.
|
||||
// It outputs them in key-value pairs within a neat Javascript object: { oldPath: newPath }
|
||||
export default async function precompileRedirects(pageList) {
|
||||
const allRedirects = Object.assign({}, latestDevRedirects)
|
||||
const precompileRedirects = diskMemoize(DISK_CACHE_FILEPATH, async (pageList) => {
|
||||
const allRedirects = readJsonFile('./lib/redirects/static/developer.json')
|
||||
|
||||
// Replace hardcoded 'latest' with real value in the redirected path
|
||||
Object.entries(allRedirects).forEach(([oldPath, newPath]) => {
|
||||
allRedirects[oldPath] = newPath.replace(
|
||||
'enterprise-server@latest',
|
||||
`enterprise-server@${latest}`
|
||||
)
|
||||
})
|
||||
|
||||
// Exception redirects are those that are essentially unicorn one-offs.
|
||||
// For example, we have redirects for documents that used to be on
|
||||
|
@ -35,9 +66,8 @@ export default async function precompileRedirects(pageList) {
|
|||
|
||||
// CURRENT PAGES PERMALINKS AND FRONTMATTER
|
||||
// create backwards-compatible old paths for page permalinks and frontmatter redirects
|
||||
await Promise.all(
|
||||
pageList.map(async (page) => Object.assign(allRedirects, page.buildRedirects()))
|
||||
)
|
||||
pageList.forEach((page) => Object.assign(allRedirects, page.buildRedirects()))
|
||||
|
||||
return allRedirects
|
||||
}
|
||||
})
|
||||
export default precompileRedirects
|
||||
|
|
Загрузка…
Ссылка в новой задаче