Skip to content

Commit

Permalink
Manual purge cache key for /api/search/v1 (#44945)
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbe authored Oct 24, 2023
1 parent 39609bb commit 2f8deb5
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 31 deletions.
4 changes: 2 additions & 2 deletions middleware/cache-control.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ export const errorCacheControl = cacheControlFactory(60) // 1 minute

// This means we tell the browser to cache the XHR request for 1h
const searchBrowserCacheControl = cacheControlFactory(60 * 60)
// This tells the CDN to cache the response for 4 hours
const searchCdnCacheControl = cacheControlFactory(60 * 60 * 4, {
// This tells the CDN to cache the response for 24 hours
const searchCdnCacheControl = cacheControlFactory(60 * 60 * 24, {
key: 'surrogate-control',
})
export function searchCacheControl(res) {
Expand Down
39 changes: 11 additions & 28 deletions src/search/middleware/search.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import express from 'express'

import FailBot from '#src/observability/lib/failbot.js'
import statsd from '#src/observability/lib/statsd.js'
import { searchCacheControl } from '../../../middleware/cache-control.js'
import catchMiddlewareError from '#src/observability/middleware/catch-middleware-error.js'
import { setFastlySurrogateKey } from '../../../middleware/set-fastly-surrogate-key.js'
import {
setFastlySurrogateKey,
SURROGATE_ENUMS,
} from '../../../middleware/set-fastly-surrogate-key.js'
import { getSearchResults } from './es-search.js'
import { getSearchFromRequest } from './get-search-request.js'

Expand All @@ -30,27 +32,8 @@ router.get(
'/v1',
validationMiddleware,
catchMiddlewareError(async function search(req, res) {
const {
indexName,
language,
query,
autocomplete,
page,
size,
debug,
sort,
highlights,
include,
} = req.search

// The getSearchResults() function is a mix of preparing the search,
// sending & receiving it, and post-processing the response from the
// network (i.e. Elasticsearch).
// This measurement then combines both the Node-work and the total
// network-work but we know that roughly 99.5% of the total time is
// spent in the network-work time so this primarily measures that.
const tags = ['version:v1', `indexName:${indexName}`]
const timed = statsd.asyncTimer(getSearchResults, 'api.search', tags)
const { indexName, query, autocomplete, page, size, debug, sort, highlights, include } =
req.search

const options = {
indexName,
Expand All @@ -64,14 +47,14 @@ router.get(
include,
}
try {
const { meta, hits } = await timed(options)

statsd.timing('api.search.total', meta.took.total_msec, tags)
statsd.timing('api.search.query', meta.took.query_msec, tags)
const { meta, hits } = await getSearchResults(options)

if (process.env.NODE_ENV !== 'development') {
searchCacheControl(res)
setFastlySurrogateKey(res, `api-search:${language}`, true)
// We can cache this without purging it after every deploy
// because the API search is only used as a proxy for local
// and preview environments.
setFastlySurrogateKey(res, SURROGATE_ENUMS.MANUAL)
}

// The v1 version of the output matches perfectly what comes out
Expand Down
2 changes: 1 addition & 1 deletion src/search/tests/api-search.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describeIfElasticsearchURL('search v1 middleware', () => {
expect(res.headers['cache-control']).toMatch(/max-age=[1-9]/)
expect(res.headers['surrogate-control']).toContain('public')
expect(res.headers['surrogate-control']).toMatch(/max-age=[1-9]/)
expect(res.headers['surrogate-key']).toBe('api-search:en')
expect(res.headers['surrogate-key']).toBe('manual-purge')
})

test('debug search', async () => {
Expand Down

0 comments on commit 2f8deb5

Please sign in to comment.