Skip to content

Commit 4e80990

Browse files
authored
Use provided waitUntil for pending revalidates (#74164)
Currently we are using `pendingWaitUntil` on `renderOpts` to handle pending revalidations (fetch updates and revalidate tag calls). This uses our old strategy of `waitUntil` inside of `sendResponse` which just keeps the stream open until the promise resolves. This isn't ideal if we have a proper waitUntil strategy provided so this updates to ensure we use that instead if available. Also adds some debug logs so we can track when this pending revalidates promise is resolved.
1 parent bc69d97 commit 4e80990

File tree

4 files changed

+47
-11
lines changed

4 files changed

+47
-11
lines changed

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,13 +1298,23 @@ async function renderToHTMLOrFlightImpl(
12981298
workStore.pendingRevalidateWrites ||
12991299
workStore.revalidatedTags
13001300
) {
1301-
options.waitUntil = Promise.all([
1301+
const pendingPromise = Promise.all([
13021302
workStore.incrementalCache?.revalidateTag(
13031303
workStore.revalidatedTags || []
13041304
),
13051305
...Object.values(workStore.pendingRevalidates || {}),
13061306
...(workStore.pendingRevalidateWrites || []),
1307-
])
1307+
]).finally(() => {
1308+
if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {
1309+
console.log('pending revalidates promise finished for:', url)
1310+
}
1311+
})
1312+
1313+
if (renderOpts.waitUntil) {
1314+
renderOpts.waitUntil(pendingPromise)
1315+
} else {
1316+
options.waitUntil = pendingPromise
1317+
}
13081318
}
13091319

13101320
if (response.collectedTags) {
@@ -1455,13 +1465,23 @@ async function renderToHTMLOrFlightImpl(
14551465
workStore.pendingRevalidateWrites ||
14561466
workStore.revalidatedTags
14571467
) {
1458-
options.waitUntil = Promise.all([
1468+
const pendingPromise = Promise.all([
14591469
workStore.incrementalCache?.revalidateTag(
14601470
workStore.revalidatedTags || []
14611471
),
14621472
...Object.values(workStore.pendingRevalidates || {}),
14631473
...(workStore.pendingRevalidateWrites || []),
1464-
])
1474+
]).finally(() => {
1475+
if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {
1476+
console.log('pending revalidates promise finished for:', url)
1477+
}
1478+
})
1479+
1480+
if (renderOpts.waitUntil) {
1481+
renderOpts.waitUntil(pendingPromise)
1482+
} else {
1483+
options.waitUntil = pendingPromise
1484+
}
14651485
}
14661486

14671487
// Create the new render result for the response.

packages/next/src/server/base-server.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,6 +2541,16 @@ export default abstract class Server<
25412541

25422542
return cacheEntry
25432543
}
2544+
let pendingWaitUntil = context.renderOpts.pendingWaitUntil
2545+
2546+
// Attempt using provided waitUntil if available
2547+
// if it's not we fallback to sendResponse's handling
2548+
if (pendingWaitUntil) {
2549+
if (context.renderOpts.waitUntil) {
2550+
context.renderOpts.waitUntil(pendingWaitUntil)
2551+
pendingWaitUntil = undefined
2552+
}
2553+
}
25442554

25452555
// Send the response now that we have copied it into the cache.
25462556
await sendResponse(

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,14 @@ export class AppRouteRouteModule extends RouteModule<
597597
workStore.revalidatedTags || []
598598
),
599599
...Object.values(workStore.pendingRevalidates || {}),
600-
])
600+
]).finally(() => {
601+
if (process.env.NEXT_PRIVATE_DEBUG_CACHE) {
602+
console.log(
603+
'pending revalidates promise finished for:',
604+
requestStore.url
605+
)
606+
}
607+
})
601608

602609
if (prerenderStore) {
603610
context.renderOpts.collectedTags = prerenderStore.tags?.join(',')

test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { findPort, waitFor } from 'next-test-utils'
1+
import { findPort, retry } from 'next-test-utils'
22
import http from 'http'
33
import url from 'url'
44
import { outdent } from 'outdent'
@@ -112,11 +112,10 @@ describe('app-fetch-deduping', () => {
112112
expect(invocation(next.cliOutput)).toBe(1)
113113

114114
// wait for the revalidation to finish
115-
await waitFor(revalidate * 1000 + 1000)
116-
117-
await next.render('/test')
118-
119-
expect(invocation(next.cliOutput)).toBe(2)
115+
await retry(async () => {
116+
await next.render('/test')
117+
expect(invocation(next.cliOutput)).toBe(2)
118+
}, 10_000)
120119
})
121120
})
122121
} else {

0 commit comments

Comments
 (0)