From 1f574efa180cb7b81ffee6ab6016f180867eda64 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 19 Dec 2024 18:55:18 -0600 Subject: [PATCH 1/4] Use provided waitUntil for pending revalidates --- .../next/src/server/app-render/app-render.tsx | 28 ++++++++++++++++--- packages/next/src/server/base-server.ts | 10 +++++++ .../server/route-modules/app-route/module.ts | 9 +++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 1a6510248aa14..6c2f0dd08b92f 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -1298,13 +1298,23 @@ async function renderToHTMLOrFlightImpl( workStore.pendingRevalidateWrites || workStore.revalidatedTags ) { - options.waitUntil = Promise.all([ + const pendingPromise = Promise.all([ workStore.incrementalCache?.revalidateTag( workStore.revalidatedTags || [] ), ...Object.values(workStore.pendingRevalidates || {}), ...(workStore.pendingRevalidateWrites || []), - ]) + ]).finally(() => { + if (process.env.NEXT_PRIVATE_DEBUG_CACHE) { + console.log('pending revalidates promise finished for:', url) + } + }) + + if (renderOpts.waitUntil) { + renderOpts.waitUntil(pendingPromise) + } else { + options.waitUntil = pendingPromise + } } if (response.collectedTags) { @@ -1455,13 +1465,23 @@ async function renderToHTMLOrFlightImpl( workStore.pendingRevalidateWrites || workStore.revalidatedTags ) { - options.waitUntil = Promise.all([ + const pendingPromise = Promise.all([ workStore.incrementalCache?.revalidateTag( workStore.revalidatedTags || [] ), ...Object.values(workStore.pendingRevalidates || {}), ...(workStore.pendingRevalidateWrites || []), - ]) + ]).finally(() => { + if (process.env.NEXT_PRIVATE_DEBUG_CACHE) { + console.log('pending revalidates promise finished for:', url) + } + }) + + if (renderOpts.waitUntil) { + renderOpts.waitUntil(pendingPromise) + } else { + options.waitUntil = pendingPromise + } } // Create the new render result for the response. diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 564ffc68f4aec..bcd09130c97b5 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2541,6 +2541,16 @@ export default abstract class Server< return cacheEntry } + let pendingWaitUntil = context.renderOpts.pendingWaitUntil + + // Attempt using provided waitUntil if available + // if it's not we fallback to sendResponse's handling + if (pendingWaitUntil) { + if (context.renderOpts.waitUntil) { + context.renderOpts.waitUntil(pendingWaitUntil) + pendingWaitUntil = undefined + } + } // Send the response now that we have copied it into the cache. await sendResponse( diff --git a/packages/next/src/server/route-modules/app-route/module.ts b/packages/next/src/server/route-modules/app-route/module.ts index 23f1f79679453..3816331c89763 100644 --- a/packages/next/src/server/route-modules/app-route/module.ts +++ b/packages/next/src/server/route-modules/app-route/module.ts @@ -597,7 +597,14 @@ export class AppRouteRouteModule extends RouteModule< workStore.revalidatedTags || [] ), ...Object.values(workStore.pendingRevalidates || {}), - ]) + ]).finally(() => { + if (process.env.NEXT_PRIVATE_DEBUG_CACHE) { + console.log( + 'pending revalidates promise finished for:', + requestStore.url + ) + } + }) if (prerenderStore) { context.renderOpts.collectedTags = prerenderStore.tags?.join(',') From 9760b64f602b5d76a3ff6cad3d81987422708d9c Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 19 Dec 2024 19:46:59 -0600 Subject: [PATCH 2/4] fix test for new behavior --- .../app-fetch-deduping/app-fetch-deduping.test.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts b/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts index d08294db501f3..5663cac851fb4 100644 --- a/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts +++ b/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts @@ -1,4 +1,4 @@ -import { findPort, waitFor } from 'next-test-utils' +import { findPort, retry } from 'next-test-utils' import http from 'http' import url from 'url' import { outdent } from 'outdent' @@ -112,11 +112,9 @@ describe('app-fetch-deduping', () => { expect(invocation(next.cliOutput)).toBe(1) // wait for the revalidation to finish - await waitFor(revalidate * 1000 + 1000) - - await next.render('/test') - - expect(invocation(next.cliOutput)).toBe(2) + await retry(() => { + expect(invocation(next.cliOutput)).toBe(2) + }) }) }) } else { From 5607268af6a4daa7592bae4155e52d0dc2585f71 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 19 Dec 2024 19:50:30 -0600 Subject: [PATCH 3/4] missing revalidate --- test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts b/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts index 5663cac851fb4..02f2de2c816e8 100644 --- a/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts +++ b/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts @@ -112,7 +112,8 @@ describe('app-fetch-deduping', () => { expect(invocation(next.cliOutput)).toBe(1) // wait for the revalidation to finish - await retry(() => { + await retry(async () => { + await next.render('/test') expect(invocation(next.cliOutput)).toBe(2) }) }) From f4dd738a41cf8621daf19d0aefc4e8afe03c7c94 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 19 Dec 2024 20:03:46 -0600 Subject: [PATCH 4/4] update duration --- test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts b/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts index 02f2de2c816e8..3ea90dc18cdcd 100644 --- a/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts +++ b/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts @@ -115,7 +115,7 @@ describe('app-fetch-deduping', () => { await retry(async () => { await next.render('/test') expect(invocation(next.cliOutput)).toBe(2) - }) + }, 10_000) }) }) } else {