@@ -1701,7 +1701,9 @@ async function renderToHTMLOrFlightImpl(
17011701 const rootParams = getRootParams ( loaderTree , ctx . getDynamicParamFromSegment )
17021702 const devValidatingFallbackParams =
17031703 getRequestMeta ( req , 'devValidatingFallbackParams' ) || null
1704- const requestStore = createRequestStoreForRender (
1704+
1705+ const createRequestStore = createRequestStoreForRender . bind (
1706+ null ,
17051707 req ,
17061708 res ,
17071709 url ,
@@ -1714,6 +1716,7 @@ async function renderToHTMLOrFlightImpl(
17141716 renderResumeDataCache ,
17151717 devValidatingFallbackParams
17161718 )
1719+ const requestStore = createRequestStore ( )
17171720
17181721 if (
17191722 process . env . NODE_ENV === 'development' &&
@@ -1725,6 +1728,9 @@ async function renderToHTMLOrFlightImpl(
17251728 ) {
17261729 const setIsrStatus = renderOpts . setIsrStatus
17271730 req . originalRequest . on ( 'end' , ( ) => {
1731+ // Note: if we're in Cache Components mode, and we restart the render due to a cache miss,
1732+ // we'll create a new request store, and the ISR status will not be picked up here.
1733+ // This is fine, because the indicator isn't useful in CC mode anyway.
17281734 if ( ! requestStore . usedDynamic && ! workStore . forceDynamic ) {
17291735 // only node can be ISR so we only need to update the status here
17301736 const { pathname } = new URL ( req . url || '/' , 'http://n' )
@@ -1785,7 +1791,8 @@ async function renderToHTMLOrFlightImpl(
17851791 formState ,
17861792 postponedState ,
17871793 metadata ,
1788- devValidatingFallbackParams
1794+ devValidatingFallbackParams ,
1795+ createRequestStore
17891796 )
17901797
17911798 return new RenderResult ( stream , {
@@ -1812,6 +1819,8 @@ async function renderToHTMLOrFlightImpl(
18121819 }
18131820
18141821 const stream = await renderToStreamWithTracing (
1822+ // NOTE: in Cache Components (dev), if the render is restarted, it will use a different requestStore
1823+ // than the one that we're passing in here.
18151824 requestStore ,
18161825 req ,
18171826 res ,
@@ -1820,7 +1829,8 @@ async function renderToHTMLOrFlightImpl(
18201829 formState ,
18211830 postponedState ,
18221831 metadata ,
1823- devValidatingFallbackParams
1832+ devValidatingFallbackParams ,
1833+ createRequestStore
18241834 )
18251835
18261836 // Invalid dynamic usages should only error the request in development.
@@ -2004,7 +2014,8 @@ async function renderToStream(
20042014 formState : any ,
20052015 postponedState : PostponedState | null ,
20062016 metadata : AppPageRenderResultMetadata ,
2007- devValidatingFallbackParams : OpaqueFallbackRouteParams | null
2017+ devValidatingFallbackParams : OpaqueFallbackRouteParams | null ,
2018+ createRequestStore : ( ) => RequestStore
20082019) : Promise < ReadableStream < Uint8Array > > {
20092020 const { assetPrefix, htmlRequestId, nonce, pagePath, renderOpts, requestId } =
20102021 ctx
@@ -2265,8 +2276,7 @@ async function renderToStream(
22652276
22662277 // The initial render acted as a prospective render to warm the caches.
22672278 // Now, we need to do another render.
2268-
2269- // TODO(restart-on-cache-miss): we should use a separate request store for this instead
2279+ requestStore = createRequestStore ( )
22702280
22712281 // We've filled the caches, so now we can render as usual.
22722282 requestStore . prerenderResumeDataCache = null
@@ -2275,10 +2285,6 @@ async function renderToStream(
22752285 )
22762286 requestStore . cacheSignal = null
22772287
2278- // Reset mutable fields.
2279- requestStore . prerenderPhase = undefined
2280- requestStore . usedDynamic = undefined
2281-
22822288 // The initial render already wrote to its debug channel. We're not using it,
22832289 // so we need to create a new one.
22842290 const finalRenderDebugChannel =
0 commit comments