-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Introduce asset discovery response caching behind flag (#419)
* test: [Spike] Add network caching to asset discovery behind flag * Only cache 200 status code responses Keep the caching layer real thin, since its an optimization * Add inline doc, clean up console.logs * Pull method out into its own util Up next is to test * Add tests for response cache util * Refactor `getResponseCache` function * Remove extra early testing snapshots * Remove `body` from mocked response obj * Code review: Update test to be more reliable
- Loading branch information
Showing
8 changed files
with
129 additions
and
2 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
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,47 @@ | ||
import { Response } from 'puppeteer' | ||
let responseCache = {} as any | ||
|
||
/** | ||
* Keep an in-memory cache of asset responses. | ||
* | ||
* When enabled, asset responses will be kept in memory. When the asset is | ||
* re-requested, it will be responsed with what the cached response. This makes | ||
* it so servers aren't being hounded for the same asset over and over again. | ||
*/ | ||
export async function cacheResponse(response: Response, logger: any) { | ||
const responseUrl = response.url() | ||
const statusCode = response.status() | ||
|
||
if (!!responseCache[responseUrl]) { | ||
logger.debug(`Asset already in cache ${responseUrl}`) | ||
return | ||
} | ||
|
||
if (![200, 201].includes(statusCode)) { | ||
return | ||
} | ||
|
||
try { | ||
const buffer = await response.buffer() | ||
|
||
responseCache[responseUrl] = { | ||
status: response.status(), | ||
headers: response.headers(), | ||
body: buffer, | ||
} | ||
|
||
logger.debug(`Added ${responseUrl} to asset discovery cache`) | ||
} catch (error) { | ||
logger.debug(`Could not cache response ${responseUrl}: ${error}`) | ||
} | ||
} | ||
|
||
export function getResponseCache(url: string) { | ||
return responseCache[url] | ||
} | ||
|
||
export function _setResponseCache(newResponseCache: any) { | ||
responseCache = newResponseCache | ||
|
||
return responseCache | ||
} |
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,57 @@ | ||
import { expect } from 'chai' | ||
import { _setResponseCache, cacheResponse, getResponseCache } from '../../src/utils/response-cache' | ||
|
||
// Mock logger | ||
const logger = { debug() { return '' }} | ||
const defaultResponse = { | ||
url() { return 'http://example.com/foo.txt' }, | ||
status() { return 200 }, | ||
headers() { return 'fake headers' }, | ||
buffer() { return 'hello' }, | ||
} as any | ||
|
||
describe('Response cache util', () => { | ||
beforeEach(() => { | ||
_setResponseCache({}) | ||
}) | ||
|
||
it('200 status code response adds to the cache', async () => { | ||
await cacheResponse(defaultResponse, logger) | ||
|
||
expect(getResponseCache('http://example.com/foo.txt')).to.eql({ | ||
status: 200, | ||
body: 'hello', | ||
headers: 'fake headers', | ||
}) | ||
}) | ||
|
||
it('201 status code response adds to the cache', async () => { | ||
await cacheResponse({ ...defaultResponse, status() { return 201 } }, logger) | ||
|
||
expect(getResponseCache('http://example.com/foo.txt')).to.eql({ | ||
status: 201, | ||
body: 'hello', | ||
headers: 'fake headers', | ||
}) | ||
}) | ||
|
||
it('calling the cache with the same URL does nothing', async () => { | ||
await cacheResponse(defaultResponse, logger) | ||
await cacheResponse({ ...defaultResponse, status() { return 201 } }, logger) | ||
|
||
expect(getResponseCache('http://example.com/foo.txt')).to.eql({ | ||
status: 200, | ||
body: 'hello', | ||
headers: 'fake headers', | ||
}) | ||
}) | ||
|
||
it('non-200 status code response does not add to the cache', async () => { | ||
await cacheResponse({ ...defaultResponse, status() { return 300 } }, logger) | ||
await cacheResponse({ ...defaultResponse, status() { return 500 } }, logger) | ||
await cacheResponse({ ...defaultResponse, status() { return 401 } }, logger) | ||
await cacheResponse({ ...defaultResponse, status() { return 404 } }, logger) | ||
|
||
expect(getResponseCache('http://example.com/foo.txt')).to.eql(undefined) | ||
}) | ||
}) |