Skip to content

Commit

Permalink
Fix resume stream handling (#58159)
Browse files Browse the repository at this point in the history
Ensures we don't await un-necessarily.
  • Loading branch information
ijjk authored Nov 8, 2023
1 parent 7e368c2 commit ccd6c4b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 6 deletions.
11 changes: 5 additions & 6 deletions packages/next/src/server/app-render/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -611,12 +611,11 @@ async function renderToHTMLOrFlightImpl(

const hasPostponed = typeof renderOpts.postponed === 'string'

let stringifiedFlightPayloadPromise =
isStaticGeneration || hasPostponed
? generateFlight(ctx)
.then((renderResult) => renderResult.toUnchunkedString(true))
.catch(() => null)
: Promise.resolve(null)
let stringifiedFlightPayloadPromise = isStaticGeneration
? generateFlight(ctx)
.then((renderResult) => renderResult.toUnchunkedString(true))
.catch(() => null)
: Promise.resolve(null)

// Get the nonce from the incoming request if it has one.
const csp = req.headers['content-security-policy']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Suspense } from 'react'
import { cookies } from 'next/headers'

export default function Page() {
return (
<>
<p>delayed page</p>

<Suspense fallback={'loading 1...'}>
<Time />
</Suspense>

<Suspense fallback={'loading 2...'}>
<Random />
</Suspense>
</>
)
}

async function Time() {
cookies()
await new Promise((resolve) => setTimeout(resolve, 1000))
return <p id="time">{Date.now()}</p>
}

async function Random() {
cookies()
await new Promise((resolve) => setTimeout(resolve, 4000))
return <p id="random">{Math.random()}</p>
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe('required server files app router', () => {
let next: NextInstance
let server
let appPort
let delayedPostpone

const setupNext = async ({
nextEnv,
Expand Down Expand Up @@ -50,6 +51,9 @@ describe('required server files app router', () => {
})
await next.stop()

delayedPostpone = (await next.readJSON('.next/server/app/delayed.meta'))
.postponed

await fs.move(
join(next.testDir, '.next/standalone'),
join(next.testDir, 'standalone')
Expand Down Expand Up @@ -106,6 +110,37 @@ describe('required server files app router', () => {
expect(next.cliOutput).not.toContain('ERR_INVALID_URL')
})

it('should properly stream resume', async () => {
const res = await fetchViaHTTP(appPort, '/delayed', undefined, {
headers: {
'x-matched-path': '/_next/postponed/resume/delayed',
},
method: 'POST',
body: delayedPostpone,
})

let chunks = []

for await (const chunk of res.body) {
chunks.push({
time: Date.now(),
chunk: chunk.toString(),
})
}

const firstSuspense = chunks.find((item) => item.chunk.includes('time'))
const secondSuspense = chunks.find((item) => item.chunk.includes('random'))

console.log({
firstSuspense,
secondSuspense,
})

expect(secondSuspense.time - firstSuspense.time).toBeGreaterThanOrEqual(
2 * 1000
)
})

it('should properly handle prerender for bot request', async () => {
const res = await fetchViaHTTP(appPort, '/isr/first', undefined, {
headers: {
Expand Down

0 comments on commit ccd6c4b

Please sign in to comment.