Skip to content

Comments

Refactor: scope requestStore to dynamic renders only (#72312)#5

Open
MitchLewis930 wants to merge 1 commit intopr_035_beforefrom
pr_035_after
Open

Refactor: scope requestStore to dynamic renders only (#72312)#5
MitchLewis930 wants to merge 1 commit intopr_035_beforefrom
pr_035_after

Conversation

@MitchLewis930
Copy link

PR_035

This completes the refactor to eliminate a requestStore scoped around
prerenders. Now we only scope requestStore around dynamic renders. If
you are prerendering then the workUnitAsyncStorage will only have a
prerneder store or undefined. While it is possible to shadow stores
because you can enter a cache scope from a render or prerender it
generally should never be the case that you enter a prerender from a
request or enter a request from a prerender. These are effectively top
level scopes.

This should not change any program behavior

stacked on vercel#72212
@greptile-apps
Copy link

greptile-apps bot commented Jan 29, 2026

Greptile Overview

Greptile Summary

This PR refactors the requestStore to be scoped only to dynamic renders rather than being created for all renders. The key changes include:

  • Moved requestStore creation inside dynamic render branch: Previously requestStore was created in renderToHTMLOrFlight and passed to renderToHTMLOrFlightImpl. Now it's created inside renderToHTMLOrFlightImpl only when the dynamic render path is taken (line 1276 in app-render.tsx).

  • Removed nested workUnitAsyncStorage.run wrapper: The code previously used nested callbacks (workAsyncStorage.run(workStore, () => workUnitAsyncStorage.run(requestStore, () => renderToHTMLOrFlightImpl(...)))). Now it passes the function and arguments directly to workAsyncStorage.run(workStore, renderToHTMLOrFlightImpl, ...), leveraging the AsyncLocalStorage API's ability to pass functions with arguments.

  • Added explicit requestStore parameter: Functions like generateDynamicFlightRenderResult, finalizeAndGenerateFlight, and generateFlight now receive requestStore as an explicit parameter and use workUnitAsyncStorage.run(requestStore, ...) to execute operations within the request context.

  • Moved ISR status check logic: The logic that checks requestStore.usedDynamic for ISR status was moved from the request end handler to inside the dynamic render branch where requestStore is now available (lines 1288-1304).

  • Updated function signatures: createRequestStoreForRender parameter order changed, and warmupDevRender signature simplified by removing unused options parameter.

This refactoring improves performance by avoiding unnecessary requestStore creation for static/prerendered pages and makes the code clearer about when request context is actually needed.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The refactoring is well-structured and improves performance by scoping requestStore to only dynamic renders. The changes correctly use AsyncLocalStorage API with explicit parameter passing, all function signatures are updated consistently, and the logic flow remains intact with proper request context scoping.
  • No files require special attention

Important Files Changed

Filename Overview
packages/next/src/server/app-render/action-handler.ts added requestStore parameter to flight generation functions and wrapped action handler execution with workUnitAsyncStorage.run
packages/next/src/server/app-render/app-render.tsx moved requestStore creation to dynamic render scope, refactored async storage wrapping from nested callbacks to direct function passing
packages/next/src/server/async-storage/request-store.ts reordered parameters in createRequestStoreForRender function signature

Sequence Diagram

sequenceDiagram
    participant Client
    participant renderToHTMLOrFlight
    participant workAsyncStorage
    participant renderToHTMLOrFlightImpl
    participant Dynamic Render Branch
    participant requestStore
    participant workUnitAsyncStorage
    participant generateDynamicFlightRenderResult
    participant actionHandler

    Client->>renderToHTMLOrFlight: Request
    renderToHTMLOrFlight->>workAsyncStorage: run(workStore, renderToHTMLOrFlightImpl, ...)
    workAsyncStorage->>renderToHTMLOrFlightImpl: Execute with workStore context
    
    alt Static Render
        renderToHTMLOrFlightImpl->>renderToHTMLOrFlightImpl: Return static result
    else Dynamic Render
        renderToHTMLOrFlightImpl->>Dynamic Render Branch: Enter dynamic path
        Dynamic Render Branch->>requestStore: createRequestStoreForRender()
        Note over Dynamic Render Branch,requestStore: requestStore now created only for dynamic renders
        
        alt RSC Request
            Dynamic Render Branch->>workUnitAsyncStorage: run(requestStore, generateDynamicFlightRenderResult, ...)
            workUnitAsyncStorage->>generateDynamicFlightRenderResult: Execute with requestStore context
            generateDynamicFlightRenderResult->>workUnitAsyncStorage: run(requestStore, generateDynamicRSCPayload, ...)
            generateDynamicFlightRenderResult->>workUnitAsyncStorage: run(requestStore, renderToReadableStream, ...)
        else Action Request
            Dynamic Render Branch->>actionHandler: handleAction()
            actionHandler->>workUnitAsyncStorage: run(requestStore, actionHandler.apply, ...)
            workUnitAsyncStorage->>actionHandler: Execute action with requestStore context
            actionHandler->>workUnitAsyncStorage: finalizeAndGenerateFlight(req, ctx, requestStore, ...)
        end
    end
    
    renderToHTMLOrFlightImpl-->>Client: Response
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants