Skip to content

Commit 9954a21

Browse files
committed
Update revalidateTag to batch tags in one request (#65296)
As discussed this collects all `revalidateTag` calls and invokes in a single request to avoid race conditions and overhead from multiple pending requests. x-ref: [slack thread](https://vercel.slack.com/archives/C0676QZBWKS/p1714688045037509?thread_ts=1710902198.529179&cid=C0676QZBWKS) Closes NEXT-3306
1 parent 937651f commit 9954a21

File tree

4 files changed

+32
-26
lines changed

4 files changed

+32
-26
lines changed

packages/next/src/server/app-render/action-handler.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,12 @@ async function addRevalidationHeader(
117117
requestStore: RequestStore
118118
}
119119
) {
120-
await Promise.all(
121-
Object.values(staticGenerationStore.pendingRevalidates || [])
122-
)
120+
await Promise.all([
121+
staticGenerationStore.incrementalCache?.revalidateTag(
122+
staticGenerationStore.revalidatedTags || []
123+
),
124+
...Object.values(staticGenerationStore.pendingRevalidates || {}),
125+
])
123126

124127
// If a tag was revalidated, the client router needs to invalidate all the
125128
// client router cache as they may be stale. And if a path was revalidated, the
@@ -481,9 +484,12 @@ export async function handleAction({
481484

482485
if (isFetchAction) {
483486
res.statusCode = 500
484-
await Promise.all(
485-
Object.values(staticGenerationStore.pendingRevalidates || [])
486-
)
487+
await Promise.all([
488+
staticGenerationStore.incrementalCache?.revalidateTag(
489+
staticGenerationStore.revalidatedTags || []
490+
),
491+
...Object.values(staticGenerationStore.pendingRevalidates || {}),
492+
])
487493

488494
const promise = Promise.reject(error)
489495
try {
@@ -840,9 +846,12 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc
840846

841847
if (isFetchAction) {
842848
res.statusCode = 500
843-
await Promise.all(
844-
Object.values(staticGenerationStore.pendingRevalidates || [])
845-
)
849+
await Promise.all([
850+
staticGenerationStore.incrementalCache?.revalidateTag(
851+
staticGenerationStore.revalidatedTags || []
852+
),
853+
...Object.values(staticGenerationStore.pendingRevalidates || {}),
854+
])
846855
const promise = Promise.reject(err)
847856
try {
848857
// we need to await the promise to trigger the rejection early

packages/next/src/server/app-render/app-render.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,9 +1350,12 @@ async function renderToHTMLOrFlightImpl(
13501350

13511351
// If we have pending revalidates, wait until they are all resolved.
13521352
if (staticGenerationStore.pendingRevalidates) {
1353-
options.waitUntil = Promise.all(
1354-
Object.values(staticGenerationStore.pendingRevalidates)
1355-
)
1353+
options.waitUntil = Promise.all([
1354+
staticGenerationStore.incrementalCache?.revalidateTag(
1355+
staticGenerationStore.revalidatedTags || []
1356+
),
1357+
...Object.values(staticGenerationStore.pendingRevalidates || {}),
1358+
])
13561359
}
13571360

13581361
addImplicitTags(staticGenerationStore)

packages/next/src/server/future/route-modules/app-route/module.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,11 +383,14 @@ export class AppRouteRouteModule extends RouteModule<
383383
context.renderOpts.fetchMetrics =
384384
staticGenerationStore.fetchMetrics
385385

386-
context.renderOpts.waitUntil = Promise.all(
387-
Object.values(
388-
staticGenerationStore.pendingRevalidates || []
389-
)
390-
)
386+
context.renderOpts.waitUntil = Promise.all([
387+
staticGenerationStore.incrementalCache?.revalidateTag(
388+
staticGenerationStore.revalidatedTags || []
389+
),
390+
...Object.values(
391+
staticGenerationStore.pendingRevalidates || {}
392+
),
393+
])
391394

392395
addImplicitTags(staticGenerationStore)
393396
;(context.renderOpts as any).fetchTags =

packages/next/src/server/web/spec-extension/revalidate.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,6 @@ function revalidate(tag: string, expression: string) {
6868
store.revalidatedTags.push(tag)
6969
}
7070

71-
if (!store.pendingRevalidates) {
72-
store.pendingRevalidates = {}
73-
}
74-
store.pendingRevalidates[tag] = store.incrementalCache
75-
.revalidateTag?.(tag)
76-
.catch((err) => {
77-
console.error(`revalidate failed for ${tag}`, err)
78-
})
79-
8071
// TODO: only revalidate if the path matches
8172
store.pathWasRevalidated = true
8273
}

0 commit comments

Comments
 (0)