Skip to content

Commit 341465c

Browse files
committed
export separate functions instead of single function from lib/page-data
1 parent eadc5aa commit 341465c

2 files changed

Lines changed: 92 additions & 40 deletions

File tree

lib/page-data.js

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,41 @@ const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version')
66
const englishPath = path.join(__dirname, '..', 'content')
77

88
/**
9-
* This function creates three representions of pages we need for different purposes:
10-
*
11-
* 1. siteTree: A nested object with pages for every language and version, useful for nav because it
12-
* contains parent, child, and sibling relationships:
13-
* siteTree[languageCode][version].childPages[<array of pages>].childPages[<array of pages>] (etc...)
14-
*
15-
* 2. pageMap: A map of all pages with permalinks as keys for fast lookup.
16-
*
17-
* 3. pageList: A simple array of all page objects for fast iterating.
9+
* We only need to initialize pages _once per language_ since pages don't change per version. So we do that
10+
* first since it's the most expensive work. This gets us a nested object with pages attached that we can use
11+
* as the basis for the siteTree after we do some versioning. We can also use it to derive the pageList.
1812
*/
19-
module.exports = async function loadPageData () {
20-
/**
21-
* We only need to initialize pages _once per language_ since pages don't change per version. So we do that
22-
* first since it's the most expensive work. This gets us a nested object with pages attached that we can use
23-
* as the basis for the siteTree after we do some versioning.
24-
*/
25-
const rawTree = {}
13+
async function loadUnversionedTree () {
14+
const unversionedTree = {}
2615

2716
await Promise.all(Object.values(languages)
2817
.map(async (langObj) => {
29-
rawTree[langObj.code] = await createTree(englishPath, langObj)
18+
unversionedTree[langObj.code] = await createTree(englishPath, langObj)
3019
}))
3120

32-
/**
33-
* Now that we have the object of all pages per language, we can walk it for each version and do a couple operations:
34-
* 1. Add a versioned href to every item, where the href is the relevant permalink for the current version.
35-
* A) Add an entry for the permalink in the pageMap.
36-
* 2. Drop any child pages that are not available in the current version.
37-
* Note that order of languages and versions doesn't matter, but order of child page arrays DOES matter (for navigation).
38-
*/
21+
return unversionedTree
22+
}
23+
24+
/**
25+
* The siteTree is a nested object with pages for every language and version, useful for nav because it
26+
* contains parent, child, and sibling relationships:
27+
*
28+
* siteTree[languageCode][version].childPages[<array of pages>].childPages[<array of pages>] (etc...)
29+
30+
* Given an unversioned tree of all pages per language, we can walk it for each version and do a couple operations:
31+
* 1. Add a versioned href to every item, where the href is the relevant permalink for the current version.
32+
* 2. Drop any child pages that are not available in the current version.
33+
*
34+
* Order of languages and versions doesn't matter, but order of child page arrays DOES matter (for navigation).
35+
*/
36+
async function loadSiteTree (unversionedTree) {
37+
const rawTree = Object.assign({}, (unversionedTree || await loadUnversionedTree()))
3938
const siteTree = {}
40-
const pageMap = {}
4139

4240
await Promise.all(Object.keys(languages).map(async (langCode) => {
4341
const treePerVersion = {}
4442

4543
await Promise.all(versions.map(async (version) => {
46-
// Yes, we are mutating the rawTree object here...
4744
versionPages(rawTree[langCode])
4845

4946
// This step can't be asynchronous because the order of child pages matters.
@@ -53,9 +50,6 @@ module.exports = async function loadPageData () {
5350
.find(pl => pl.pageVersion === version || (pl.pageVersion === 'homepage' && version === nonEnterpriseDefaultVersion))
5451
.href
5552

56-
// Add permalinks to the pageMap.
57-
pageMap[item.href] = item.page
58-
5953
if (!item.childPages) return item
6054

6155
// Drop child pages that do not apply to the current version.
@@ -71,8 +65,53 @@ module.exports = async function loadPageData () {
7165
siteTree[langCode] = treePerVersion
7266
}))
7367

74-
// Get a simple array of pages.
75-
const pageList = [...new Set(Object.values(pageMap))]
68+
return siteTree
69+
}
70+
71+
// Derive a flat array of Page objects in all languages.
72+
async function loadPageList (unversionedTree) {
73+
const rawTree = unversionedTree || await loadUnversionedTree()
74+
const pageList = []
75+
76+
await Promise.all(Object.keys(languages).map(async (langCode) => {
77+
await addToCollection(rawTree[langCode], pageList)
78+
}))
79+
80+
async function addToCollection (item, collection) {
81+
if (!item.page) return
82+
collection.push(item.page)
83+
84+
if (!item.childPages) return
85+
await Promise.all(item.childPages.map(async (childPage) => await addToCollection(childPage, collection)))
86+
}
87+
88+
return pageList
89+
}
90+
91+
// Create an object from the list of all pages with permalinks as keys for fast lookup.
92+
function createMapFromArray (pageList) {
93+
const pageMap =
94+
pageList.reduce(
95+
(pageMap, page) => {
96+
for (const permalink of page.permalinks) {
97+
pageMap[permalink.href] = page
98+
}
99+
return pageMap
100+
},
101+
{}
102+
)
103+
104+
return pageMap
105+
}
106+
107+
async function loadPageMap (pageList) {
108+
const pages = pageList || await loadPageList()
109+
return createMapFromArray(pages)
110+
}
76111

77-
return { siteTree, pageList, pageMap }
112+
module.exports = {
113+
loadUnversionedTree,
114+
loadSiteTree,
115+
loadPages: loadPageList,
116+
loadPageMap
78117
}

lib/warm-server2.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
const statsd = require('./statsd')
2-
const loadPageData = require('./page-data')
2+
const { loadUnversionedTree, loadSiteTree, loadPages, loadPageMap } = require('./page-data')
33
const loadRedirects = require('./redirects/precompile')
44
const loadSiteData = require('./site-data')
55

66
// Instrument these functions so that
77
// it's wrapped in a timer that reports to Datadog
88
const dog = {
9-
loadPageData: statsd.asyncTimer(loadPageData, 'load_page_data'),
9+
loadUnversionedTree: statsd.asyncTimer(loadUnversionedTree, 'load_unversioned_tree'),
10+
loadSiteTree: statsd.asyncTimer(loadSiteTree, 'load_site_tree'),
11+
loadPages: statsd.asyncTimer(loadPages, 'load_pages'),
12+
loadPageMap: statsd.asyncTimer(loadPageMap, 'load_page_map'),
1013
loadRedirects: statsd.asyncTimer(loadRedirects, 'load_redirects'),
1114
loadSiteData: statsd.timer(loadSiteData, 'load_site_data')
1215
}
1316

1417
// For local caching
15-
let pageList, pageMap, site, redirects, siteTree
18+
let pageList, pageMap, site, redirects, unversionedTree, siteTree
1619

1720
function isFullyWarmed () {
1821
// NOTE: Yes, `pageList` is specifically excluded here as it is transient data
19-
const fullyWarmed = !!(pageMap && site && redirects && siteTree)
22+
const fullyWarmed = !!(pageMap && site && redirects && unversionedTree && siteTree)
2023
return fullyWarmed
2124
}
2225

@@ -25,6 +28,7 @@ function getWarmedCache () {
2528
pages: pageMap,
2629
site,
2730
redirects,
31+
unversionedTree,
2832
siteTree
2933
}
3034
}
@@ -36,11 +40,20 @@ async function warmServer () {
3640
console.log('Priming context information...')
3741
}
3842

43+
if (!unversionedTree) {
44+
unversionedTree = await dog.loadUnversionedTree()
45+
}
46+
3947
if (!siteTree) {
40-
const pageData = await dog.loadPageData()
41-
siteTree = pageData.siteTree
42-
pageList = pageData.pageList
43-
pageMap = pageData.pageMap
48+
siteTree = await dog.loadSiteTree(unversionedTree)
49+
}
50+
51+
if (!pageList) {
52+
pageList = await dog.loadPages(unversionedTree)
53+
}
54+
55+
if (!pageMap) {
56+
pageMap = await dog.loadPageMap(pageList)
4457
}
4558

4659
if (!site) {

0 commit comments

Comments
 (0)