Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add timeout/retry handling for fetch cache #66652

Merged
merged 15 commits into from
Jun 10, 2024
28 changes: 27 additions & 1 deletion packages/next/src/server/lib/incremental-cache/fetch-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,32 @@ const CACHE_REVALIDATE_HEADER = 'x-vercel-revalidate' as const
const CACHE_FETCH_URL_HEADER = 'x-vercel-cache-item-name' as const
const CACHE_CONTROL_VALUE_HEADER = 'x-vercel-cache-control' as const

async function fetchRetryWithTimeout(
url: Parameters<typeof fetch>[0],
init: Parameters<typeof fetch>[1],
retryIndex = 0
): Promise<Response> {
const controller = new AbortController()
const timeout = setTimeout(() => {
controller.abort()
}, 500)

return fetch(url, {
...(init || {}),
signal: controller.signal,
})
.catch((err) => {
if (retryIndex < 3) {
throw err
} else {
return fetchRetryWithTimeout(url, init, retryIndex + 1)
}
})
.finally(() => {
clearTimeout(timeout)
})
}

export default class FetchCache implements CacheHandler {
private headers: Record<string, string>
private cacheEndpoint?: string
Expand Down Expand Up @@ -147,7 +173,7 @@ export default class FetchCache implements CacheHandler {
}

try {
const res = await fetch(
const res = await fetchRetryWithTimeout(
`${this.cacheEndpoint}/v1/suspense-cache/revalidate?tags=${tags
.map((tag) => encodeURIComponent(tag))
.join(',')}`,
Expand Down
Loading