Skip to content

Commit

Permalink
in-memory cache the changelog RSS downloads (github#23582)
Browse files Browse the repository at this point in the history
* in-memory cache the changelog RSS downloads

* fix tests
  • Loading branch information
peterbe authored Dec 11, 2021
1 parent e2fb5e1 commit 6363640
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 17 deletions.
20 changes: 16 additions & 4 deletions lib/changelog.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Parser from 'rss-parser'

export async function getRssFeed(url) {
async function getRssFeed(url) {
const parser = new Parser({ timeout: 5000 })
const feedUrl = `${url}/feed`
let feed
Expand All @@ -15,7 +15,16 @@ export async function getRssFeed(url) {
return feed
}

export async function getChangelogItems(prefix, feed) {
const globalCache = new Map()

export async function getChangelogItems(prefix, feedUrl) {
const cacheKey = prefix + feedUrl
if (globalCache.get(cacheKey)) {
return globalCache.get(cacheKey)
}

const feed = await getRssFeed(feedUrl)

if (!feed || !feed.items) {
console.log(feed)
console.error('feed is not valid or has no items')
Expand All @@ -34,7 +43,10 @@ export async function getChangelogItems(prefix, feed) {
}
})

// We don't cache the raw payload we'd get from the network request
// because it would waste memory. Instead we store the "serialized"
// object that's created from the raw payload.
globalCache.set(cacheKey, changelog)

return changelog
}

export default { getRssFeed, getChangelogItems }
10 changes: 6 additions & 4 deletions middleware/contextualizers/whats-new-changelog.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { getRssFeed, getChangelogItems } from '../../lib/changelog.js'
import { getChangelogItems } from '../../lib/changelog.js'
import getApplicableVersions from '../../lib/get-applicable-versions.js'

export default async function whatsNewChangelog(req, res, next) {
if (!req.context.page) return next()
if (!req.context.page.changelog) return next()
const label = req.context.page.changelog.label
const label = req.context.page.changelog.label.split(/\s+/g).join('')

// If there is no `versions` prop in the changelog frontmatter, assume the changelog should display in all versions.
if (req.context.page.changelog.versions) {
Expand All @@ -23,7 +23,9 @@ export default async function whatsNewChangelog(req, res, next) {

req.context.changelogUrl = labelUrls[label] || `https://github.blog/changelog/label/${label}`

const feed = await getRssFeed(req.context.changelogUrl)
req.context.whatsNewChangelog = await getChangelogItems(req.context.page.changelog.prefix, feed)
req.context.whatsNewChangelog = await getChangelogItems(
req.context.page.changelog.prefix,
req.context.changelogUrl
)
return next()
}
27 changes: 18 additions & 9 deletions tests/unit/get-rss-feeds.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import Parser from 'rss-parser'
import { getChangelogItems } from '../../lib/changelog.js'
import fs from 'fs/promises'
import path from 'path'
const parser = new Parser({ timeout: 5000 })
const rssFeedContent = await fs.readFile(
path.join(process.cwd(), 'tests/fixtures/rss-feed.xml'),
'utf8'
)

import nock from 'nock'

import { getChangelogItems } from '../../lib/changelog.js'

describe('getChangelogItems module', () => {
let changelog

beforeAll(async () => {
const feed = await parser.parseString(rssFeedContent)
changelog = await getChangelogItems('GitHub Actions:', feed)
const rssFeedContent = await fs.readFile(
path.join(process.cwd(), 'tests/fixtures/rss-feed.xml'),
'utf8'
)

nock('https://github.blog').get('/changelog/label/packages/feed').reply(200, rssFeedContent)

changelog = await getChangelogItems(
'GitHub Actions:',
'https://github.blog/changelog/label/packages'
)
})

afterAll(() => nock.cleanAll())

it('changelog contains 3 items', async () => {
expect(changelog.length).toEqual(3)
})
Expand Down

0 comments on commit 6363640

Please sign in to comment.